1 |
Author: phreak |
2 |
Date: 2008-04-30 11:39:06 +0000 (Wed, 30 Apr 2008) |
3 |
New Revision: 94 |
4 |
|
5 |
Added: |
6 |
hardened-sources/2.6/tags/2.6.24-1/ |
7 |
hardened-sources/2.6/tags/2.6.24-1/4420_grsec-2.1.11-2.6.24.4-200803262003.patch |
8 |
hardened-sources/2.6/tags/2.6.24-1/4421_remove-localversion-grsec.patch |
9 |
hardened-sources/2.6/tags/2.6.24-1/4425_alpha-sysctl-uac-for-hardened.patch |
10 |
hardened-sources/2.6/tags/2.6.24-1/4430_grsec-kconfig-default-gids.patch |
11 |
hardened-sources/2.6/tags/2.6.24-1/4435_grsec-kconfig-gentoo.patch |
12 |
hardened-sources/2.6/tags/2.6.24-1/4440_grsec-kconfig-pax-without-grsec.patch |
13 |
hardened-sources/2.6/tags/2.6.24-1/4445_disable-compat_vdso.patch |
14 |
hardened-sources/2.6/tags/2.6.24-1/4450_grsec-2.1.11-mute-warnings.patch |
15 |
hardened-sources/2.6/tags/2.6.24-1/4455_grsec-2.1.11-pax-curr_ip-fixes.patch |
16 |
hardened-sources/2.6/tags/2.6.24-1/4460_selinux-avc_audit-log-curr_ip.patch |
17 |
Log: |
18 |
Importing patchset for 2.6.24-1 (from hardened-patches-2.6.24-1.extras.tar.bz2). |
19 |
|
20 |
Added: hardened-sources/2.6/tags/2.6.24-1/4420_grsec-2.1.11-2.6.24.4-200803262003.patch |
21 |
=================================================================== |
22 |
--- hardened-sources/2.6/tags/2.6.24-1/4420_grsec-2.1.11-2.6.24.4-200803262003.patch (rev 0) |
23 |
+++ hardened-sources/2.6/tags/2.6.24-1/4420_grsec-2.1.11-2.6.24.4-200803262003.patch 2008-04-30 11:39:06 UTC (rev 94) |
24 |
@@ -0,0 +1,37453 @@ |
25 |
+diff -urNp linux-2.6.24.4/arch/alpha/kernel/module.c linux-2.6.24.4/arch/alpha/kernel/module.c |
26 |
+--- linux-2.6.24.4/arch/alpha/kernel/module.c 2008-03-24 14:49:18.000000000 -0400 |
27 |
++++ linux-2.6.24.4/arch/alpha/kernel/module.c 2008-03-26 17:56:55.000000000 -0400 |
28 |
+@@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, |
29 |
+ |
30 |
+ /* The small sections were sorted to the end of the segment. |
31 |
+ The following should definitely cover them. */ |
32 |
+- gp = (u64)me->module_core + me->core_size - 0x8000; |
33 |
++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000; |
34 |
+ got = sechdrs[me->arch.gotsecindex].sh_addr; |
35 |
+ |
36 |
+ for (i = 0; i < n; i++) { |
37 |
+diff -urNp linux-2.6.24.4/arch/alpha/kernel/osf_sys.c linux-2.6.24.4/arch/alpha/kernel/osf_sys.c |
38 |
+--- linux-2.6.24.4/arch/alpha/kernel/osf_sys.c 2008-03-24 14:49:18.000000000 -0400 |
39 |
++++ linux-2.6.24.4/arch/alpha/kernel/osf_sys.c 2008-03-26 17:56:55.000000000 -0400 |
40 |
+@@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp |
41 |
+ merely specific addresses, but regions of memory -- perhaps |
42 |
+ this feature should be incorporated into all ports? */ |
43 |
+ |
44 |
++#ifdef CONFIG_PAX_RANDMMAP |
45 |
++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
46 |
++#endif |
47 |
++ |
48 |
+ if (addr) { |
49 |
+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit); |
50 |
+ if (addr != (unsigned long) -ENOMEM) |
51 |
+@@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp |
52 |
+ } |
53 |
+ |
54 |
+ /* Next, try allocating at TASK_UNMAPPED_BASE. */ |
55 |
+- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE), |
56 |
+- len, limit); |
57 |
++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit); |
58 |
++ |
59 |
+ if (addr != (unsigned long) -ENOMEM) |
60 |
+ return addr; |
61 |
+ |
62 |
+diff -urNp linux-2.6.24.4/arch/alpha/kernel/ptrace.c linux-2.6.24.4/arch/alpha/kernel/ptrace.c |
63 |
+--- linux-2.6.24.4/arch/alpha/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400 |
64 |
++++ linux-2.6.24.4/arch/alpha/kernel/ptrace.c 2008-03-26 17:56:55.000000000 -0400 |
65 |
+@@ -15,6 +15,7 @@ |
66 |
+ #include <linux/slab.h> |
67 |
+ #include <linux/security.h> |
68 |
+ #include <linux/signal.h> |
69 |
++#include <linux/grsecurity.h> |
70 |
+ |
71 |
+ #include <asm/uaccess.h> |
72 |
+ #include <asm/pgtable.h> |
73 |
+@@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi |
74 |
+ size_t copied; |
75 |
+ long ret; |
76 |
+ |
77 |
++ if (gr_handle_ptrace(child, request)) |
78 |
++ return -EPERM; |
79 |
++ |
80 |
+ switch (request) { |
81 |
+ /* When I and D space are separate, these will need to be fixed. */ |
82 |
+ case PTRACE_PEEKTEXT: /* read word at location addr. */ |
83 |
+diff -urNp linux-2.6.24.4/arch/alpha/mm/fault.c linux-2.6.24.4/arch/alpha/mm/fault.c |
84 |
+--- linux-2.6.24.4/arch/alpha/mm/fault.c 2008-03-24 14:49:18.000000000 -0400 |
85 |
++++ linux-2.6.24.4/arch/alpha/mm/fault.c 2008-03-26 18:53:27.000000000 -0400 |
86 |
+@@ -23,6 +23,7 @@ |
87 |
+ #include <linux/smp.h> |
88 |
+ #include <linux/interrupt.h> |
89 |
+ #include <linux/module.h> |
90 |
++#include <linux/binfmts.h> |
91 |
+ |
92 |
+ #include <asm/system.h> |
93 |
+ #include <asm/uaccess.h> |
94 |
+@@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct * |
95 |
+ __reload_thread(pcb); |
96 |
+ } |
97 |
+ |
98 |
++#ifdef CONFIG_PAX_PAGEEXEC |
99 |
++/* |
100 |
++ * PaX: decide what to do with offenders (regs->pc = fault address) |
101 |
++ * |
102 |
++ * returns 1 when task should be killed |
103 |
++ * 2 when patched PLT trampoline was detected |
104 |
++ * 3 when unpatched PLT trampoline was detected |
105 |
++ */ |
106 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
107 |
++{ |
108 |
++ |
109 |
++#ifdef CONFIG_PAX_EMUPLT |
110 |
++ int err; |
111 |
++ |
112 |
++ do { /* PaX: patched PLT emulation #1 */ |
113 |
++ unsigned int ldah, ldq, jmp; |
114 |
++ |
115 |
++ err = get_user(ldah, (unsigned int *)regs->pc); |
116 |
++ err |= get_user(ldq, (unsigned int *)(regs->pc+4)); |
117 |
++ err |= get_user(jmp, (unsigned int *)(regs->pc+8)); |
118 |
++ |
119 |
++ if (err) |
120 |
++ break; |
121 |
++ |
122 |
++ if ((ldah & 0xFFFF0000U) == 0x277B0000U && |
123 |
++ (ldq & 0xFFFF0000U) == 0xA77B0000U && |
124 |
++ jmp == 0x6BFB0000U) |
125 |
++ { |
126 |
++ unsigned long r27, addr; |
127 |
++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; |
128 |
++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL; |
129 |
++ |
130 |
++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); |
131 |
++ err = get_user(r27, (unsigned long *)addr); |
132 |
++ if (err) |
133 |
++ break; |
134 |
++ |
135 |
++ regs->r27 = r27; |
136 |
++ regs->pc = r27; |
137 |
++ return 2; |
138 |
++ } |
139 |
++ } while (0); |
140 |
++ |
141 |
++ do { /* PaX: patched PLT emulation #2 */ |
142 |
++ unsigned int ldah, lda, br; |
143 |
++ |
144 |
++ err = get_user(ldah, (unsigned int *)regs->pc); |
145 |
++ err |= get_user(lda, (unsigned int *)(regs->pc+4)); |
146 |
++ err |= get_user(br, (unsigned int *)(regs->pc+8)); |
147 |
++ |
148 |
++ if (err) |
149 |
++ break; |
150 |
++ |
151 |
++ if ((ldah & 0xFFFF0000U) == 0x277B0000U && |
152 |
++ (lda & 0xFFFF0000U) == 0xA77B0000U && |
153 |
++ (br & 0xFFE00000U) == 0xC3E00000U) |
154 |
++ { |
155 |
++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL; |
156 |
++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; |
157 |
++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL; |
158 |
++ |
159 |
++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); |
160 |
++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); |
161 |
++ return 2; |
162 |
++ } |
163 |
++ } while (0); |
164 |
++ |
165 |
++ do { /* PaX: unpatched PLT emulation */ |
166 |
++ unsigned int br; |
167 |
++ |
168 |
++ err = get_user(br, (unsigned int *)regs->pc); |
169 |
++ |
170 |
++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) { |
171 |
++ unsigned int br2, ldq, nop, jmp; |
172 |
++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver; |
173 |
++ |
174 |
++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); |
175 |
++ err = get_user(br2, (unsigned int *)addr); |
176 |
++ err |= get_user(ldq, (unsigned int *)(addr+4)); |
177 |
++ err |= get_user(nop, (unsigned int *)(addr+8)); |
178 |
++ err |= get_user(jmp, (unsigned int *)(addr+12)); |
179 |
++ err |= get_user(resolver, (unsigned long *)(addr+16)); |
180 |
++ |
181 |
++ if (err) |
182 |
++ break; |
183 |
++ |
184 |
++ if (br2 == 0xC3600000U && |
185 |
++ ldq == 0xA77B000CU && |
186 |
++ nop == 0x47FF041FU && |
187 |
++ jmp == 0x6B7B0000U) |
188 |
++ { |
189 |
++ regs->r28 = regs->pc+4; |
190 |
++ regs->r27 = addr+16; |
191 |
++ regs->pc = resolver; |
192 |
++ return 3; |
193 |
++ } |
194 |
++ } |
195 |
++ } while (0); |
196 |
++#endif |
197 |
++ |
198 |
++ return 1; |
199 |
++} |
200 |
++ |
201 |
++void pax_report_insns(void *pc, void *sp) |
202 |
++{ |
203 |
++ unsigned long i; |
204 |
++ |
205 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
206 |
++ for (i = 0; i < 5; i++) { |
207 |
++ unsigned int c; |
208 |
++ if (get_user(c, (unsigned int *)pc+i)) |
209 |
++ printk("???????? "); |
210 |
++ else |
211 |
++ printk("%08x ", c); |
212 |
++ } |
213 |
++ printk("\n"); |
214 |
++} |
215 |
++#endif |
216 |
+ |
217 |
+ /* |
218 |
+ * This routine handles page faults. It determines the address, |
219 |
+@@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns |
220 |
+ good_area: |
221 |
+ si_code = SEGV_ACCERR; |
222 |
+ if (cause < 0) { |
223 |
+- if (!(vma->vm_flags & VM_EXEC)) |
224 |
++ if (!(vma->vm_flags & VM_EXEC)) { |
225 |
++ |
226 |
++#ifdef CONFIG_PAX_PAGEEXEC |
227 |
++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc) |
228 |
++ goto bad_area; |
229 |
++ |
230 |
++ up_read(&mm->mmap_sem); |
231 |
++ switch (pax_handle_fetch_fault(regs)) { |
232 |
++ |
233 |
++#ifdef CONFIG_PAX_EMUPLT |
234 |
++ case 2: |
235 |
++ case 3: |
236 |
++ return; |
237 |
++#endif |
238 |
++ |
239 |
++ } |
240 |
++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp()); |
241 |
++ do_group_exit(SIGKILL); |
242 |
++#else |
243 |
+ goto bad_area; |
244 |
++#endif |
245 |
++ |
246 |
++ } |
247 |
+ } else if (!cause) { |
248 |
+ /* Allow reads even for write-only mappings */ |
249 |
+ if (!(vma->vm_flags & (VM_READ | VM_WRITE))) |
250 |
+diff -urNp linux-2.6.24.4/arch/arm/mm/mmap.c linux-2.6.24.4/arch/arm/mm/mmap.c |
251 |
+--- linux-2.6.24.4/arch/arm/mm/mmap.c 2008-03-24 14:49:18.000000000 -0400 |
252 |
++++ linux-2.6.24.4/arch/arm/mm/mmap.c 2008-03-26 17:56:55.000000000 -0400 |
253 |
+@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp |
254 |
+ if (len > TASK_SIZE) |
255 |
+ return -ENOMEM; |
256 |
+ |
257 |
++#ifdef CONFIG_PAX_RANDMMAP |
258 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
259 |
++#endif |
260 |
++ |
261 |
+ if (addr) { |
262 |
+ if (do_align) |
263 |
+ addr = COLOUR_ALIGN(addr, pgoff); |
264 |
+@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp |
265 |
+ return addr; |
266 |
+ } |
267 |
+ if (len > mm->cached_hole_size) { |
268 |
+- start_addr = addr = mm->free_area_cache; |
269 |
++ start_addr = addr = mm->free_area_cache; |
270 |
+ } else { |
271 |
+- start_addr = addr = TASK_UNMAPPED_BASE; |
272 |
+- mm->cached_hole_size = 0; |
273 |
++ start_addr = addr = mm->mmap_base; |
274 |
++ mm->cached_hole_size = 0; |
275 |
+ } |
276 |
+ |
277 |
+ full_search: |
278 |
+@@ -91,8 +95,8 @@ full_search: |
279 |
+ * Start a new search - just in case we missed |
280 |
+ * some holes. |
281 |
+ */ |
282 |
+- if (start_addr != TASK_UNMAPPED_BASE) { |
283 |
+- start_addr = addr = TASK_UNMAPPED_BASE; |
284 |
++ if (start_addr != mm->mmap_base) { |
285 |
++ start_addr = addr = mm->mmap_base; |
286 |
+ mm->cached_hole_size = 0; |
287 |
+ goto full_search; |
288 |
+ } |
289 |
+diff -urNp linux-2.6.24.4/arch/avr32/mm/fault.c linux-2.6.24.4/arch/avr32/mm/fault.c |
290 |
+--- linux-2.6.24.4/arch/avr32/mm/fault.c 2008-03-24 14:49:18.000000000 -0400 |
291 |
++++ linux-2.6.24.4/arch/avr32/mm/fault.c 2008-03-26 18:53:27.000000000 -0400 |
292 |
+@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru |
293 |
+ |
294 |
+ int exception_trace = 1; |
295 |
+ |
296 |
++#ifdef CONFIG_PAX_PAGEEXEC |
297 |
++void pax_report_insns(void *pc, void *sp) |
298 |
++{ |
299 |
++ unsigned long i; |
300 |
++ |
301 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
302 |
++ for (i = 0; i < 20; i++) { |
303 |
++ unsigned char c; |
304 |
++ if (get_user(c, (unsigned char *)pc+i)) |
305 |
++ printk("???????? "); |
306 |
++ else |
307 |
++ printk("%02x ", c); |
308 |
++ } |
309 |
++ printk("\n"); |
310 |
++} |
311 |
++#endif |
312 |
++ |
313 |
+ /* |
314 |
+ * This routine handles page faults. It determines the address and the |
315 |
+ * problem, and then passes it off to one of the appropriate routines. |
316 |
+@@ -157,6 +174,16 @@ bad_area: |
317 |
+ up_read(&mm->mmap_sem); |
318 |
+ |
319 |
+ if (user_mode(regs)) { |
320 |
++ |
321 |
++#ifdef CONFIG_PAX_PAGEEXEC |
322 |
++ if (mm->pax_flags & MF_PAX_PAGEEXEC) { |
323 |
++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) { |
324 |
++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp); |
325 |
++ do_group_exit(SIGKILL); |
326 |
++ } |
327 |
++ } |
328 |
++#endif |
329 |
++ |
330 |
+ if (exception_trace && printk_ratelimit()) |
331 |
+ printk("%s%s[%d]: segfault at %08lx pc %08lx " |
332 |
+ "sp %08lx ecr %lu\n", |
333 |
+diff -urNp linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c |
334 |
+--- linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c 2008-03-24 14:49:18.000000000 -0400 |
335 |
++++ linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c 2008-03-26 17:56:55.000000000 -0400 |
336 |
+@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_ |
337 |
+ |
338 |
+ #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack)) |
339 |
+ |
340 |
++#ifdef CONFIG_PAX_ASLR |
341 |
++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL) |
342 |
++ |
343 |
++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) |
344 |
++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) |
345 |
++#endif |
346 |
++ |
347 |
+ /* Ugly but avoids duplication */ |
348 |
+ #include "../../../fs/binfmt_elf.c" |
349 |
+ |
350 |
+diff -urNp linux-2.6.24.4/arch/ia64/ia32/ia32priv.h linux-2.6.24.4/arch/ia64/ia32/ia32priv.h |
351 |
+--- linux-2.6.24.4/arch/ia64/ia32/ia32priv.h 2008-03-24 14:49:18.000000000 -0400 |
352 |
++++ linux-2.6.24.4/arch/ia64/ia32/ia32priv.h 2008-03-26 17:56:55.000000000 -0400 |
353 |
+@@ -303,7 +303,14 @@ struct old_linux32_dirent { |
354 |
+ #define ELF_DATA ELFDATA2LSB |
355 |
+ #define ELF_ARCH EM_386 |
356 |
+ |
357 |
+-#define IA32_STACK_TOP IA32_PAGE_OFFSET |
358 |
++#ifdef CONFIG_PAX_RANDUSTACK |
359 |
++#define __IA32_DELTA_STACK (current->mm->delta_stack) |
360 |
++#else |
361 |
++#define __IA32_DELTA_STACK 0UL |
362 |
++#endif |
363 |
++ |
364 |
++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK) |
365 |
++ |
366 |
+ #define IA32_GATE_OFFSET IA32_PAGE_OFFSET |
367 |
+ #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE |
368 |
+ |
369 |
+diff -urNp linux-2.6.24.4/arch/ia64/kernel/module.c linux-2.6.24.4/arch/ia64/kernel/module.c |
370 |
+--- linux-2.6.24.4/arch/ia64/kernel/module.c 2008-03-24 14:49:18.000000000 -0400 |
371 |
++++ linux-2.6.24.4/arch/ia64/kernel/module.c 2008-03-26 17:56:55.000000000 -0400 |
372 |
+@@ -321,7 +321,7 @@ module_alloc (unsigned long size) |
373 |
+ void |
374 |
+ module_free (struct module *mod, void *module_region) |
375 |
+ { |
376 |
+- if (mod->arch.init_unw_table && module_region == mod->module_init) { |
377 |
++ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) { |
378 |
+ unw_remove_unwind_table(mod->arch.init_unw_table); |
379 |
+ mod->arch.init_unw_table = NULL; |
380 |
+ } |
381 |
+@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd |
382 |
+ } |
383 |
+ |
384 |
+ static inline int |
385 |
++in_init_rx (const struct module *mod, uint64_t addr) |
386 |
++{ |
387 |
++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx; |
388 |
++} |
389 |
++ |
390 |
++static inline int |
391 |
++in_init_rw (const struct module *mod, uint64_t addr) |
392 |
++{ |
393 |
++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw; |
394 |
++} |
395 |
++ |
396 |
++static inline int |
397 |
+ in_init (const struct module *mod, uint64_t addr) |
398 |
+ { |
399 |
+- return addr - (uint64_t) mod->module_init < mod->init_size; |
400 |
++ return in_init_rx(mod, value) || in_init_rw(mod, value); |
401 |
++} |
402 |
++ |
403 |
++static inline int |
404 |
++in_core_rx (const struct module *mod, uint64_t addr) |
405 |
++{ |
406 |
++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx; |
407 |
++} |
408 |
++ |
409 |
++static inline int |
410 |
++in_core_rw (const struct module *mod, uint64_t addr) |
411 |
++{ |
412 |
++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw; |
413 |
+ } |
414 |
+ |
415 |
+ static inline int |
416 |
+ in_core (const struct module *mod, uint64_t addr) |
417 |
+ { |
418 |
+- return addr - (uint64_t) mod->module_core < mod->core_size; |
419 |
++ return in_core_rx(mod, addr) || in_core_rw(mod, addr); |
420 |
+ } |
421 |
+ |
422 |
+ static inline int |
423 |
+@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_ |
424 |
+ break; |
425 |
+ |
426 |
+ case RV_BDREL: |
427 |
+- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core); |
428 |
++ if (in_init_rx(mod, val)) |
429 |
++ val -= (uint64_t) mod->module_init_rx; |
430 |
++ else if (in_init_rw(mod, val)) |
431 |
++ val -= (uint64_t) mod->module_init_rw; |
432 |
++ else if (in_core_rx(mod, val)) |
433 |
++ val -= (uint64_t) mod->module_core_rx; |
434 |
++ else if (in_core_rw(mod, val)) |
435 |
++ val -= (uint64_t) mod->module_core_rw; |
436 |
+ break; |
437 |
+ |
438 |
+ case RV_LTV: |
439 |
+@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs, |
440 |
+ * addresses have been selected... |
441 |
+ */ |
442 |
+ uint64_t gp; |
443 |
+- if (mod->core_size > MAX_LTOFF) |
444 |
++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF) |
445 |
+ /* |
446 |
+ * This takes advantage of fact that SHF_ARCH_SMALL gets allocated |
447 |
+ * at the end of the module. |
448 |
+ */ |
449 |
+- gp = mod->core_size - MAX_LTOFF / 2; |
450 |
++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2; |
451 |
+ else |
452 |
+- gp = mod->core_size / 2; |
453 |
+- gp = (uint64_t) mod->module_core + ((gp + 7) & -8); |
454 |
++ gp = (mod->core_size_rx + mod->core_size_rw) / 2; |
455 |
++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8); |
456 |
+ mod->arch.gp = gp; |
457 |
+ DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); |
458 |
+ } |
459 |
+diff -urNp linux-2.6.24.4/arch/ia64/kernel/ptrace.c linux-2.6.24.4/arch/ia64/kernel/ptrace.c |
460 |
+--- linux-2.6.24.4/arch/ia64/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400 |
461 |
++++ linux-2.6.24.4/arch/ia64/kernel/ptrace.c 2008-03-26 17:56:55.000000000 -0400 |
462 |
+@@ -17,6 +17,7 @@ |
463 |
+ #include <linux/security.h> |
464 |
+ #include <linux/audit.h> |
465 |
+ #include <linux/signal.h> |
466 |
++#include <linux/grsecurity.h> |
467 |
+ |
468 |
+ #include <asm/pgtable.h> |
469 |
+ #include <asm/processor.h> |
470 |
+@@ -1451,6 +1452,9 @@ sys_ptrace (long request, pid_t pid, uns |
471 |
+ if (pid == 1) /* no messing around with init! */ |
472 |
+ goto out_tsk; |
473 |
+ |
474 |
++ if (gr_handle_ptrace(child, request)) |
475 |
++ goto out_tsk; |
476 |
++ |
477 |
+ if (request == PTRACE_ATTACH) { |
478 |
+ ret = ptrace_attach(child); |
479 |
+ goto out_tsk; |
480 |
+diff -urNp linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c |
481 |
+--- linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c 2008-03-24 14:49:18.000000000 -0400 |
482 |
++++ linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c 2008-03-26 17:56:55.000000000 -0400 |
483 |
+@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil |
484 |
+ if (REGION_NUMBER(addr) == RGN_HPAGE) |
485 |
+ addr = 0; |
486 |
+ #endif |
487 |
++ |
488 |
++#ifdef CONFIG_PAX_RANDMMAP |
489 |
++ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp) |
490 |
++ addr = mm->free_area_cache; |
491 |
++ else |
492 |
++#endif |
493 |
++ |
494 |
+ if (!addr) |
495 |
+ addr = mm->free_area_cache; |
496 |
+ |
497 |
+@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil |
498 |
+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { |
499 |
+ /* At this point: (!vma || addr < vma->vm_end). */ |
500 |
+ if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) { |
501 |
+- if (start_addr != TASK_UNMAPPED_BASE) { |
502 |
++ if (start_addr != mm->mmap_base) { |
503 |
+ /* Start a new search --- just in case we missed some holes. */ |
504 |
+- addr = TASK_UNMAPPED_BASE; |
505 |
++ addr = mm->mmap_base; |
506 |
+ goto full_search; |
507 |
+ } |
508 |
+ return -ENOMEM; |
509 |
+diff -urNp linux-2.6.24.4/arch/ia64/mm/fault.c linux-2.6.24.4/arch/ia64/mm/fault.c |
510 |
+--- linux-2.6.24.4/arch/ia64/mm/fault.c 2008-03-24 14:49:18.000000000 -0400 |
511 |
++++ linux-2.6.24.4/arch/ia64/mm/fault.c 2008-03-26 18:53:27.000000000 -0400 |
512 |
+@@ -10,6 +10,7 @@ |
513 |
+ #include <linux/interrupt.h> |
514 |
+ #include <linux/kprobes.h> |
515 |
+ #include <linux/kdebug.h> |
516 |
++#include <linux/binfmts.h> |
517 |
+ |
518 |
+ #include <asm/pgtable.h> |
519 |
+ #include <asm/processor.h> |
520 |
+@@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned |
521 |
+ return pte_present(pte); |
522 |
+ } |
523 |
+ |
524 |
++#ifdef CONFIG_PAX_PAGEEXEC |
525 |
++void pax_report_insns(void *pc, void *sp) |
526 |
++{ |
527 |
++ unsigned long i; |
528 |
++ |
529 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
530 |
++ for (i = 0; i < 8; i++) { |
531 |
++ unsigned int c; |
532 |
++ if (get_user(c, (unsigned int *)pc+i)) |
533 |
++ printk("???????? "); |
534 |
++ else |
535 |
++ printk("%08x ", c); |
536 |
++ } |
537 |
++ printk("\n"); |
538 |
++} |
539 |
++#endif |
540 |
++ |
541 |
+ void __kprobes |
542 |
+ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs) |
543 |
+ { |
544 |
+@@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres |
545 |
+ mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT) |
546 |
+ | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)); |
547 |
+ |
548 |
+- if ((vma->vm_flags & mask) != mask) |
549 |
++ if ((vma->vm_flags & mask) != mask) { |
550 |
++ |
551 |
++#ifdef CONFIG_PAX_PAGEEXEC |
552 |
++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) { |
553 |
++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip) |
554 |
++ goto bad_area; |
555 |
++ |
556 |
++ up_read(&mm->mmap_sem); |
557 |
++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12); |
558 |
++ do_group_exit(SIGKILL); |
559 |
++ } |
560 |
++#endif |
561 |
++ |
562 |
+ goto bad_area; |
563 |
+ |
564 |
++ } |
565 |
++ |
566 |
+ survive: |
567 |
+ /* |
568 |
+ * If for any reason at all we couldn't handle the fault, make |
569 |
+diff -urNp linux-2.6.24.4/arch/ia64/mm/init.c linux-2.6.24.4/arch/ia64/mm/init.c |
570 |
+--- linux-2.6.24.4/arch/ia64/mm/init.c 2008-03-24 14:49:18.000000000 -0400 |
571 |
++++ linux-2.6.24.4/arch/ia64/mm/init.c 2008-03-26 17:56:55.000000000 -0400 |
572 |
+@@ -20,8 +20,8 @@ |
573 |
+ #include <linux/proc_fs.h> |
574 |
+ #include <linux/bitops.h> |
575 |
+ #include <linux/kexec.h> |
576 |
++#include <linux/a.out.h> |
577 |
+ |
578 |
+-#include <asm/a.out.h> |
579 |
+ #include <asm/dma.h> |
580 |
+ #include <asm/ia32.h> |
581 |
+ #include <asm/io.h> |
582 |
+@@ -128,6 +128,19 @@ ia64_init_addr_space (void) |
583 |
+ vma->vm_start = current->thread.rbs_bot & PAGE_MASK; |
584 |
+ vma->vm_end = vma->vm_start + PAGE_SIZE; |
585 |
+ vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT; |
586 |
++ |
587 |
++#ifdef CONFIG_PAX_PAGEEXEC |
588 |
++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) { |
589 |
++ vm->vm_flags &= ~VM_EXEC; |
590 |
++ |
591 |
++#ifdef CONFIG_PAX_MPROTECT |
592 |
++ if (current->mm->pax_flags & MF_PAX_MPROTECT) |
593 |
++ vma->vm_flags &= ~VM_MAYEXEC; |
594 |
++#endif |
595 |
++ |
596 |
++ } |
597 |
++#endif |
598 |
++ |
599 |
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
600 |
+ down_write(¤t->mm->mmap_sem); |
601 |
+ if (insert_vm_struct(current->mm, vma)) { |
602 |
+diff -urNp linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c |
603 |
+--- linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c 2008-03-24 14:49:18.000000000 -0400 |
604 |
++++ linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c 2008-03-26 17:56:55.000000000 -0400 |
605 |
+@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N |
606 |
+ #undef ELF_ET_DYN_BASE |
607 |
+ #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) |
608 |
+ |
609 |
++#ifdef CONFIG_PAX_ASLR |
610 |
++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) |
611 |
++ |
612 |
++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
613 |
++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
614 |
++#endif |
615 |
++ |
616 |
+ #include <asm/processor.h> |
617 |
+ #include <linux/module.h> |
618 |
+ #include <linux/elfcore.h> |
619 |
+diff -urNp linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c |
620 |
+--- linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c 2008-03-24 14:49:18.000000000 -0400 |
621 |
++++ linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c 2008-03-26 17:56:55.000000000 -0400 |
622 |
+@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N |
623 |
+ #undef ELF_ET_DYN_BASE |
624 |
+ #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) |
625 |
+ |
626 |
++#ifdef CONFIG_PAX_ASLR |
627 |
++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) |
628 |
++ |
629 |
++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
630 |
++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
631 |
++#endif |
632 |
++ |
633 |
+ #include <asm/processor.h> |
634 |
+ #include <linux/module.h> |
635 |
+ #include <linux/elfcore.h> |
636 |
+diff -urNp linux-2.6.24.4/arch/mips/kernel/syscall.c linux-2.6.24.4/arch/mips/kernel/syscall.c |
637 |
+--- linux-2.6.24.4/arch/mips/kernel/syscall.c 2008-03-24 14:49:18.000000000 -0400 |
638 |
++++ linux-2.6.24.4/arch/mips/kernel/syscall.c 2008-03-26 17:56:55.000000000 -0400 |
639 |
+@@ -93,6 +93,11 @@ unsigned long arch_get_unmapped_area(str |
640 |
+ do_color_align = 0; |
641 |
+ if (filp || (flags & MAP_SHARED)) |
642 |
+ do_color_align = 1; |
643 |
++ |
644 |
++#ifdef CONFIG_PAX_RANDMMAP |
645 |
++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
646 |
++#endif |
647 |
++ |
648 |
+ if (addr) { |
649 |
+ if (do_color_align) |
650 |
+ addr = COLOUR_ALIGN(addr, pgoff); |
651 |
+@@ -103,7 +108,7 @@ unsigned long arch_get_unmapped_area(str |
652 |
+ (!vmm || addr + len <= vmm->vm_start)) |
653 |
+ return addr; |
654 |
+ } |
655 |
+- addr = TASK_UNMAPPED_BASE; |
656 |
++ addr = current->mm->mmap_base; |
657 |
+ if (do_color_align) |
658 |
+ addr = COLOUR_ALIGN(addr, pgoff); |
659 |
+ else |
660 |
+diff -urNp linux-2.6.24.4/arch/mips/mm/fault.c linux-2.6.24.4/arch/mips/mm/fault.c |
661 |
+--- linux-2.6.24.4/arch/mips/mm/fault.c 2008-03-24 14:49:18.000000000 -0400 |
662 |
++++ linux-2.6.24.4/arch/mips/mm/fault.c 2008-03-26 17:56:55.000000000 -0400 |
663 |
+@@ -26,6 +26,23 @@ |
664 |
+ #include <asm/ptrace.h> |
665 |
+ #include <asm/highmem.h> /* For VMALLOC_END */ |
666 |
+ |
667 |
++#ifdef CONFIG_PAX_PAGEEXEC |
668 |
++void pax_report_insns(void *pc) |
669 |
++{ |
670 |
++ unsigned long i; |
671 |
++ |
672 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
673 |
++ for (i = 0; i < 5; i++) { |
674 |
++ unsigned int c; |
675 |
++ if (get_user(c, (unsigned int *)pc+i)) |
676 |
++ printk("???????? "); |
677 |
++ else |
678 |
++ printk("%08x ", c); |
679 |
++ } |
680 |
++ printk("\n"); |
681 |
++} |
682 |
++#endif |
683 |
++ |
684 |
+ /* |
685 |
+ * This routine handles page faults. It determines the address, |
686 |
+ * and the problem, and then passes it off to one of the appropriate |
687 |
+diff -urNp linux-2.6.24.4/arch/parisc/kernel/module.c linux-2.6.24.4/arch/parisc/kernel/module.c |
688 |
+--- linux-2.6.24.4/arch/parisc/kernel/module.c 2008-03-24 14:49:18.000000000 -0400 |
689 |
++++ linux-2.6.24.4/arch/parisc/kernel/module.c 2008-03-26 17:56:55.000000000 -0400 |
690 |
+@@ -73,16 +73,38 @@ |
691 |
+ |
692 |
+ /* three functions to determine where in the module core |
693 |
+ * or init pieces the location is */ |
694 |
++static inline int in_init_rx(struct module *me, void *loc) |
695 |
++{ |
696 |
++ return (loc >= me->module_init_rx && |
697 |
++ loc < (me->module_init_rx + me->init_size_rx)); |
698 |
++} |
699 |
++ |
700 |
++static inline int in_init_rw(struct module *me, void *loc) |
701 |
++{ |
702 |
++ return (loc >= me->module_init_rw && |
703 |
++ loc < (me->module_init_rw + me->init_size_rw)); |
704 |
++} |
705 |
++ |
706 |
+ static inline int in_init(struct module *me, void *loc) |
707 |
+ { |
708 |
+- return (loc >= me->module_init && |
709 |
+- loc <= (me->module_init + me->init_size)); |
710 |
++ return in_init_rx(me, loc) || in_init_rw(me, loc); |
711 |
++} |
712 |
++ |
713 |
++static inline int in_core_rx(struct module *me, void *loc) |
714 |
++{ |
715 |
++ return (loc >= me->module_core_rx && |
716 |
++ loc < (me->module_core_rx + me->core_size_rx)); |
717 |
++} |
718 |
++ |
719 |
++static inline int in_core_rw(struct module *me, void *loc) |
720 |
++{ |
721 |
++ return (loc >= me->module_core_rw && |
722 |
++ loc < (me->module_core_rw + me->core_size_rw)); |
723 |
+ } |
724 |
+ |
725 |
+ static inline int in_core(struct module *me, void *loc) |
726 |
+ { |
727 |
+- return (loc >= me->module_core && |
728 |
+- loc <= (me->module_core + me->core_size)); |
729 |
++ return in_core_rx(me, loc) || in_core_rw(me, loc); |
730 |
+ } |
731 |
+ |
732 |
+ static inline int in_local(struct module *me, void *loc) |
733 |
+@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_ |
734 |
+ } |
735 |
+ |
736 |
+ /* align things a bit */ |
737 |
+- me->core_size = ALIGN(me->core_size, 16); |
738 |
+- me->arch.got_offset = me->core_size; |
739 |
+- me->core_size += gots * sizeof(struct got_entry); |
740 |
+- |
741 |
+- me->core_size = ALIGN(me->core_size, 16); |
742 |
+- me->arch.fdesc_offset = me->core_size; |
743 |
+- me->core_size += fdescs * sizeof(Elf_Fdesc); |
744 |
+- |
745 |
+- me->core_size = ALIGN(me->core_size, 16); |
746 |
+- me->arch.stub_offset = me->core_size; |
747 |
+- me->core_size += stubs * sizeof(struct stub_entry); |
748 |
+- |
749 |
+- me->init_size = ALIGN(me->init_size, 16); |
750 |
+- me->arch.init_stub_offset = me->init_size; |
751 |
+- me->init_size += init_stubs * sizeof(struct stub_entry); |
752 |
++ me->core_size_rw = ALIGN(me->core_size_rw, 16); |
753 |
++ me->arch.got_offset = me->core_size_rw; |
754 |
++ me->core_size_rw += gots * sizeof(struct got_entry); |
755 |
++ |
756 |
++ me->core_size_rw = ALIGN(me->core_size_rw, 16); |
757 |
++ me->arch.fdesc_offset = me->core_size_rw; |
758 |
++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc); |
759 |
++ |
760 |
++ me->core_size_rx = ALIGN(me->core_size_rx, 16); |
761 |
++ me->arch.stub_offset = me->core_size_rx; |
762 |
++ me->core_size_rx += stubs * sizeof(struct stub_entry); |
763 |
++ |
764 |
++ me->init_size_rx = ALIGN(me->init_size_rx, 16); |
765 |
++ me->arch.init_stub_offset = me->init_size_rx; |
766 |
++ me->init_size_rx += init_stubs * sizeof(struct stub_entry); |
767 |
+ |
768 |
+ me->arch.got_max = gots; |
769 |
+ me->arch.fdesc_max = fdescs; |
770 |
+@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module |
771 |
+ |
772 |
+ BUG_ON(value == 0); |
773 |
+ |
774 |
+- got = me->module_core + me->arch.got_offset; |
775 |
++ got = me->module_core_rw + me->arch.got_offset; |
776 |
+ for (i = 0; got[i].addr; i++) |
777 |
+ if (got[i].addr == value) |
778 |
+ goto out; |
779 |
+@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module |
780 |
+ #ifdef CONFIG_64BIT |
781 |
+ static Elf_Addr get_fdesc(struct module *me, unsigned long value) |
782 |
+ { |
783 |
+- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset; |
784 |
++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset; |
785 |
+ |
786 |
+ if (!value) { |
787 |
+ printk(KERN_ERR "%s: zero OPD requested!\n", me->name); |
788 |
+@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module |
789 |
+ |
790 |
+ /* Create new one */ |
791 |
+ fdesc->addr = value; |
792 |
+- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset; |
793 |
++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset; |
794 |
+ return (Elf_Addr)fdesc; |
795 |
+ } |
796 |
+ #endif /* CONFIG_64BIT */ |
797 |
+@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module * |
798 |
+ if(init_section) { |
799 |
+ i = me->arch.init_stub_count++; |
800 |
+ BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max); |
801 |
+- stub = me->module_init + me->arch.init_stub_offset + |
802 |
++ stub = me->module_init_rx + me->arch.init_stub_offset + |
803 |
+ i * sizeof(struct stub_entry); |
804 |
+ } else { |
805 |
+ i = me->arch.stub_count++; |
806 |
+ BUG_ON(me->arch.stub_count > me->arch.stub_max); |
807 |
+- stub = me->module_core + me->arch.stub_offset + |
808 |
++ stub = me->module_core_rx + me->arch.stub_offset + |
809 |
+ i * sizeof(struct stub_entry); |
810 |
+ } |
811 |
+ |
812 |
+@@ -759,7 +781,7 @@ register_unwind_table(struct module *me, |
813 |
+ |
814 |
+ table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr; |
815 |
+ end = table + sechdrs[me->arch.unwind_section].sh_size; |
816 |
+- gp = (Elf_Addr)me->module_core + me->arch.got_offset; |
817 |
++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset; |
818 |
+ |
819 |
+ DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n", |
820 |
+ me->arch.unwind_section, table, end, gp); |
821 |
+diff -urNp linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c |
822 |
+--- linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c 2008-03-24 14:49:18.000000000 -0400 |
823 |
++++ linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c 2008-03-26 17:56:55.000000000 -0400 |
824 |
+@@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str |
825 |
+ if (flags & MAP_FIXED) |
826 |
+ return addr; |
827 |
+ if (!addr) |
828 |
+- addr = TASK_UNMAPPED_BASE; |
829 |
++ addr = current->mm->mmap_base; |
830 |
+ |
831 |
+ if (filp) { |
832 |
+ addr = get_shared_area(filp->f_mapping, addr, len, pgoff); |
833 |
+diff -urNp linux-2.6.24.4/arch/parisc/kernel/traps.c linux-2.6.24.4/arch/parisc/kernel/traps.c |
834 |
+--- linux-2.6.24.4/arch/parisc/kernel/traps.c 2008-03-24 14:49:18.000000000 -0400 |
835 |
++++ linux-2.6.24.4/arch/parisc/kernel/traps.c 2008-03-26 17:56:55.000000000 -0400 |
836 |
+@@ -713,9 +713,7 @@ void handle_interruption(int code, struc |
837 |
+ |
838 |
+ down_read(¤t->mm->mmap_sem); |
839 |
+ vma = find_vma(current->mm,regs->iaoq[0]); |
840 |
+- if (vma && (regs->iaoq[0] >= vma->vm_start) |
841 |
+- && (vma->vm_flags & VM_EXEC)) { |
842 |
+- |
843 |
++ if (vma && (regs->iaoq[0] >= vma->vm_start)) { |
844 |
+ fault_address = regs->iaoq[0]; |
845 |
+ fault_space = regs->iasq[0]; |
846 |
+ |
847 |
+diff -urNp linux-2.6.24.4/arch/parisc/mm/fault.c linux-2.6.24.4/arch/parisc/mm/fault.c |
848 |
+--- linux-2.6.24.4/arch/parisc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400 |
849 |
++++ linux-2.6.24.4/arch/parisc/mm/fault.c 2008-03-26 18:53:27.000000000 -0400 |
850 |
+@@ -16,6 +16,8 @@ |
851 |
+ #include <linux/sched.h> |
852 |
+ #include <linux/interrupt.h> |
853 |
+ #include <linux/module.h> |
854 |
++#include <linux/unistd.h> |
855 |
++#include <linux/binfmts.h> |
856 |
+ |
857 |
+ #include <asm/uaccess.h> |
858 |
+ #include <asm/traps.h> |
859 |
+@@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex |
860 |
+ static unsigned long |
861 |
+ parisc_acctyp(unsigned long code, unsigned int inst) |
862 |
+ { |
863 |
+- if (code == 6 || code == 16) |
864 |
++ if (code == 6 || code == 7 || code == 16) |
865 |
+ return VM_EXEC; |
866 |
+ |
867 |
+ switch (inst & 0xf0000000) { |
868 |
+@@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign |
869 |
+ } |
870 |
+ #endif |
871 |
+ |
872 |
++#ifdef CONFIG_PAX_PAGEEXEC |
873 |
++/* |
874 |
++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address) |
875 |
++ * |
876 |
++ * returns 1 when task should be killed |
877 |
++ * 2 when rt_sigreturn trampoline was detected |
878 |
++ * 3 when unpatched PLT trampoline was detected |
879 |
++ */ |
880 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
881 |
++{ |
882 |
++ |
883 |
++#ifdef CONFIG_PAX_EMUPLT |
884 |
++ int err; |
885 |
++ |
886 |
++ do { /* PaX: unpatched PLT emulation */ |
887 |
++ unsigned int bl, depwi; |
888 |
++ |
889 |
++ err = get_user(bl, (unsigned int *)instruction_pointer(regs)); |
890 |
++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4)); |
891 |
++ |
892 |
++ if (err) |
893 |
++ break; |
894 |
++ |
895 |
++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) { |
896 |
++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12; |
897 |
++ |
898 |
++ err = get_user(ldw, (unsigned int *)addr); |
899 |
++ err |= get_user(bv, (unsigned int *)(addr+4)); |
900 |
++ err |= get_user(ldw2, (unsigned int *)(addr+8)); |
901 |
++ |
902 |
++ if (err) |
903 |
++ break; |
904 |
++ |
905 |
++ if (ldw == 0x0E801096U && |
906 |
++ bv == 0xEAC0C000U && |
907 |
++ ldw2 == 0x0E881095U) |
908 |
++ { |
909 |
++ unsigned int resolver, map; |
910 |
++ |
911 |
++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8)); |
912 |
++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12)); |
913 |
++ if (err) |
914 |
++ break; |
915 |
++ |
916 |
++ regs->gr[20] = instruction_pointer(regs)+8; |
917 |
++ regs->gr[21] = map; |
918 |
++ regs->gr[22] = resolver; |
919 |
++ regs->iaoq[0] = resolver | 3UL; |
920 |
++ regs->iaoq[1] = regs->iaoq[0] + 4; |
921 |
++ return 3; |
922 |
++ } |
923 |
++ } |
924 |
++ } while (0); |
925 |
++#endif |
926 |
++ |
927 |
++#ifdef CONFIG_PAX_EMUTRAMP |
928 |
++ |
929 |
++#ifndef CONFIG_PAX_EMUSIGRT |
930 |
++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) |
931 |
++ return 1; |
932 |
++#endif |
933 |
++ |
934 |
++ do { /* PaX: rt_sigreturn emulation */ |
935 |
++ unsigned int ldi1, ldi2, bel, nop; |
936 |
++ |
937 |
++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs)); |
938 |
++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4)); |
939 |
++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8)); |
940 |
++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12)); |
941 |
++ |
942 |
++ if (err) |
943 |
++ break; |
944 |
++ |
945 |
++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) && |
946 |
++ ldi2 == 0x3414015AU && |
947 |
++ bel == 0xE4008200U && |
948 |
++ nop == 0x08000240U) |
949 |
++ { |
950 |
++ regs->gr[25] = (ldi1 & 2) >> 1; |
951 |
++ regs->gr[20] = __NR_rt_sigreturn; |
952 |
++ regs->gr[31] = regs->iaoq[1] + 16; |
953 |
++ regs->sr[0] = regs->iasq[1]; |
954 |
++ regs->iaoq[0] = 0x100UL; |
955 |
++ regs->iaoq[1] = regs->iaoq[0] + 4; |
956 |
++ regs->iasq[0] = regs->sr[2]; |
957 |
++ regs->iasq[1] = regs->sr[2]; |
958 |
++ return 2; |
959 |
++ } |
960 |
++ } while (0); |
961 |
++#endif |
962 |
++ |
963 |
++ return 1; |
964 |
++} |
965 |
++ |
966 |
++void pax_report_insns(void *pc, void *sp) |
967 |
++{ |
968 |
++ unsigned long i; |
969 |
++ |
970 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
971 |
++ for (i = 0; i < 5; i++) { |
972 |
++ unsigned int c; |
973 |
++ if (get_user(c, (unsigned int *)pc+i)) |
974 |
++ printk("???????? "); |
975 |
++ else |
976 |
++ printk("%08x ", c); |
977 |
++ } |
978 |
++ printk("\n"); |
979 |
++} |
980 |
++#endif |
981 |
++ |
982 |
+ void do_page_fault(struct pt_regs *regs, unsigned long code, |
983 |
+ unsigned long address) |
984 |
+ { |
985 |
+@@ -165,8 +277,33 @@ good_area: |
986 |
+ |
987 |
+ acc_type = parisc_acctyp(code,regs->iir); |
988 |
+ |
989 |
+- if ((vma->vm_flags & acc_type) != acc_type) |
990 |
++ if ((vma->vm_flags & acc_type) != acc_type) { |
991 |
++ |
992 |
++#ifdef CONFIG_PAX_PAGEEXEC |
993 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) && |
994 |
++ (address & ~3UL) == instruction_pointer(regs)) |
995 |
++ { |
996 |
++ up_read(&mm->mmap_sem); |
997 |
++ switch (pax_handle_fetch_fault(regs)) { |
998 |
++ |
999 |
++#ifdef CONFIG_PAX_EMUPLT |
1000 |
++ case 3: |
1001 |
++ return; |
1002 |
++#endif |
1003 |
++ |
1004 |
++#ifdef CONFIG_PAX_EMUTRAMP |
1005 |
++ case 2: |
1006 |
++ return; |
1007 |
++#endif |
1008 |
++ |
1009 |
++ } |
1010 |
++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]); |
1011 |
++ do_group_exit(SIGKILL); |
1012 |
++ } |
1013 |
++#endif |
1014 |
++ |
1015 |
+ goto bad_area; |
1016 |
++ } |
1017 |
+ |
1018 |
+ /* |
1019 |
+ * If for any reason at all we couldn't handle the fault, make |
1020 |
+diff -urNp linux-2.6.24.4/arch/powerpc/kernel/module_32.c linux-2.6.24.4/arch/powerpc/kernel/module_32.c |
1021 |
+--- linux-2.6.24.4/arch/powerpc/kernel/module_32.c 2008-03-24 14:49:18.000000000 -0400 |
1022 |
++++ linux-2.6.24.4/arch/powerpc/kernel/module_32.c 2008-03-26 17:56:55.000000000 -0400 |
1023 |
+@@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr |
1024 |
+ me->arch.core_plt_section = i; |
1025 |
+ } |
1026 |
+ if (!me->arch.core_plt_section || !me->arch.init_plt_section) { |
1027 |
+- printk("Module doesn't contain .plt or .init.plt sections.\n"); |
1028 |
++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name); |
1029 |
+ return -ENOEXEC; |
1030 |
+ } |
1031 |
+ |
1032 |
+@@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati |
1033 |
+ |
1034 |
+ DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location); |
1035 |
+ /* Init, or core PLT? */ |
1036 |
+- if (location >= mod->module_core |
1037 |
+- && location < mod->module_core + mod->core_size) |
1038 |
++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) || |
1039 |
++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw)) |
1040 |
+ entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr; |
1041 |
+- else |
1042 |
++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) || |
1043 |
++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw)) |
1044 |
+ entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr; |
1045 |
++ else { |
1046 |
++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name); |
1047 |
++ return ~0UL; |
1048 |
++ } |
1049 |
+ |
1050 |
+ /* Find this entry, or if that fails, the next avail. entry */ |
1051 |
+ while (entry->jump[0]) { |
1052 |
+diff -urNp linux-2.6.24.4/arch/powerpc/kernel/signal_32.c linux-2.6.24.4/arch/powerpc/kernel/signal_32.c |
1053 |
+--- linux-2.6.24.4/arch/powerpc/kernel/signal_32.c 2008-03-24 14:49:18.000000000 -0400 |
1054 |
++++ linux-2.6.24.4/arch/powerpc/kernel/signal_32.c 2008-03-26 17:56:55.000000000 -0400 |
1055 |
+@@ -731,7 +731,7 @@ int handle_rt_signal32(unsigned long sig |
1056 |
+ /* Save user registers on the stack */ |
1057 |
+ frame = &rt_sf->uc.uc_mcontext; |
1058 |
+ addr = frame; |
1059 |
+- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) { |
1060 |
++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) { |
1061 |
+ if (save_user_regs(regs, frame, 0)) |
1062 |
+ goto badframe; |
1063 |
+ regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp; |
1064 |
+diff -urNp linux-2.6.24.4/arch/powerpc/kernel/signal_64.c linux-2.6.24.4/arch/powerpc/kernel/signal_64.c |
1065 |
+--- linux-2.6.24.4/arch/powerpc/kernel/signal_64.c 2008-03-24 14:49:18.000000000 -0400 |
1066 |
++++ linux-2.6.24.4/arch/powerpc/kernel/signal_64.c 2008-03-26 17:56:55.000000000 -0400 |
1067 |
+@@ -369,7 +369,7 @@ int handle_rt_signal64(int signr, struct |
1068 |
+ current->thread.fpscr.val = 0; |
1069 |
+ |
1070 |
+ /* Set up to return from userspace. */ |
1071 |
+- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) { |
1072 |
++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) { |
1073 |
+ regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp; |
1074 |
+ } else { |
1075 |
+ err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]); |
1076 |
+diff -urNp linux-2.6.24.4/arch/powerpc/kernel/vdso.c linux-2.6.24.4/arch/powerpc/kernel/vdso.c |
1077 |
+--- linux-2.6.24.4/arch/powerpc/kernel/vdso.c 2008-03-24 14:49:18.000000000 -0400 |
1078 |
++++ linux-2.6.24.4/arch/powerpc/kernel/vdso.c 2008-03-26 17:56:55.000000000 -0400 |
1079 |
+@@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l |
1080 |
+ vdso_base = VDSO32_MBASE; |
1081 |
+ #endif |
1082 |
+ |
1083 |
+- current->mm->context.vdso_base = 0; |
1084 |
++ current->mm->context.vdso_base = ~0UL; |
1085 |
+ |
1086 |
+ /* vDSO has a problem and was disabled, just don't "enable" it for the |
1087 |
+ * process |
1088 |
+@@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l |
1089 |
+ */ |
1090 |
+ down_write(&mm->mmap_sem); |
1091 |
+ vdso_base = get_unmapped_area(NULL, vdso_base, |
1092 |
+- vdso_pages << PAGE_SHIFT, 0, 0); |
1093 |
++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE); |
1094 |
+ if (IS_ERR_VALUE(vdso_base)) { |
1095 |
+ rc = vdso_base; |
1096 |
+ goto fail_mmapsem; |
1097 |
+diff -urNp linux-2.6.24.4/arch/powerpc/mm/fault.c linux-2.6.24.4/arch/powerpc/mm/fault.c |
1098 |
+--- linux-2.6.24.4/arch/powerpc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400 |
1099 |
++++ linux-2.6.24.4/arch/powerpc/mm/fault.c 2008-03-26 18:53:27.000000000 -0400 |
1100 |
+@@ -29,6 +29,12 @@ |
1101 |
+ #include <linux/module.h> |
1102 |
+ #include <linux/kprobes.h> |
1103 |
+ #include <linux/kdebug.h> |
1104 |
++#include <linux/binfmts.h> |
1105 |
++#include <linux/slab.h> |
1106 |
++#include <linux/pagemap.h> |
1107 |
++#include <linux/compiler.h> |
1108 |
++#include <linux/binfmts.h> |
1109 |
++#include <linux/unistd.h> |
1110 |
+ |
1111 |
+ #include <asm/page.h> |
1112 |
+ #include <asm/pgtable.h> |
1113 |
+@@ -62,6 +68,363 @@ static inline int notify_page_fault(stru |
1114 |
+ } |
1115 |
+ #endif |
1116 |
+ |
1117 |
++#ifdef CONFIG_PAX_EMUSIGRT |
1118 |
++void pax_syscall_close(struct vm_area_struct *vma) |
1119 |
++{ |
1120 |
++ vma->vm_mm->call_syscall = 0UL; |
1121 |
++} |
1122 |
++ |
1123 |
++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type) |
1124 |
++{ |
1125 |
++ struct page *page; |
1126 |
++ unsigned int *kaddr; |
1127 |
++ |
1128 |
++ page = alloc_page(GFP_HIGHUSER); |
1129 |
++ if (!page) |
1130 |
++ return NOPAGE_OOM; |
1131 |
++ |
1132 |
++ kaddr = kmap(page); |
1133 |
++ memset(kaddr, 0, PAGE_SIZE); |
1134 |
++ kaddr[0] = 0x44000002U; /* sc */ |
1135 |
++ __flush_dcache_icache(kaddr); |
1136 |
++ kunmap(page); |
1137 |
++ if (type) |
1138 |
++ *type = VM_FAULT_MAJOR; |
1139 |
++ return page; |
1140 |
++} |
1141 |
++ |
1142 |
++static struct vm_operations_struct pax_vm_ops = { |
1143 |
++ .close = pax_syscall_close, |
1144 |
++ .nopage = pax_syscall_nopage, |
1145 |
++}; |
1146 |
++ |
1147 |
++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) |
1148 |
++{ |
1149 |
++ int ret; |
1150 |
++ |
1151 |
++ vma->vm_mm = current->mm; |
1152 |
++ vma->vm_start = addr; |
1153 |
++ vma->vm_end = addr + PAGE_SIZE; |
1154 |
++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; |
1155 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
1156 |
++ vma->vm_ops = &pax_vm_ops; |
1157 |
++ |
1158 |
++ ret = insert_vm_struct(current->mm, vma); |
1159 |
++ if (ret) |
1160 |
++ return ret; |
1161 |
++ |
1162 |
++ ++current->mm->total_vm; |
1163 |
++ return 0; |
1164 |
++} |
1165 |
++#endif |
1166 |
++ |
1167 |
++#ifdef CONFIG_PAX_PAGEEXEC |
1168 |
++/* |
1169 |
++ * PaX: decide what to do with offenders (regs->nip = fault address) |
1170 |
++ * |
1171 |
++ * returns 1 when task should be killed |
1172 |
++ * 2 when patched GOT trampoline was detected |
1173 |
++ * 3 when patched PLT trampoline was detected |
1174 |
++ * 4 when unpatched PLT trampoline was detected |
1175 |
++ * 5 when sigreturn trampoline was detected |
1176 |
++ * 6 when rt_sigreturn trampoline was detected |
1177 |
++ */ |
1178 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
1179 |
++{ |
1180 |
++ |
1181 |
++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT) |
1182 |
++ int err; |
1183 |
++#endif |
1184 |
++ |
1185 |
++#ifdef CONFIG_PAX_EMUPLT |
1186 |
++ do { /* PaX: patched GOT emulation */ |
1187 |
++ unsigned int blrl; |
1188 |
++ |
1189 |
++ err = get_user(blrl, (unsigned int *)regs->nip); |
1190 |
++ |
1191 |
++ if (!err && blrl == 0x4E800021U) { |
1192 |
++ unsigned long temp = regs->nip; |
1193 |
++ |
1194 |
++ regs->nip = regs->link & 0xFFFFFFFCUL; |
1195 |
++ regs->link = temp + 4UL; |
1196 |
++ return 2; |
1197 |
++ } |
1198 |
++ } while (0); |
1199 |
++ |
1200 |
++ do { /* PaX: patched PLT emulation #1 */ |
1201 |
++ unsigned int b; |
1202 |
++ |
1203 |
++ err = get_user(b, (unsigned int *)regs->nip); |
1204 |
++ |
1205 |
++ if (!err && (b & 0xFC000003U) == 0x48000000U) { |
1206 |
++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL); |
1207 |
++ return 3; |
1208 |
++ } |
1209 |
++ } while (0); |
1210 |
++ |
1211 |
++ do { /* PaX: unpatched PLT emulation #1 */ |
1212 |
++ unsigned int li, b; |
1213 |
++ |
1214 |
++ err = get_user(li, (unsigned int *)regs->nip); |
1215 |
++ err |= get_user(b, (unsigned int *)(regs->nip+4)); |
1216 |
++ |
1217 |
++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { |
1218 |
++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; |
1219 |
++ unsigned long addr = b | 0xFC000000UL; |
1220 |
++ |
1221 |
++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
1222 |
++ err = get_user(rlwinm, (unsigned int *)addr); |
1223 |
++ err |= get_user(add, (unsigned int *)(addr+4)); |
1224 |
++ err |= get_user(li2, (unsigned int *)(addr+8)); |
1225 |
++ err |= get_user(addis2, (unsigned int *)(addr+12)); |
1226 |
++ err |= get_user(mtctr, (unsigned int *)(addr+16)); |
1227 |
++ err |= get_user(li3, (unsigned int *)(addr+20)); |
1228 |
++ err |= get_user(addis3, (unsigned int *)(addr+24)); |
1229 |
++ err |= get_user(bctr, (unsigned int *)(addr+28)); |
1230 |
++ |
1231 |
++ if (err) |
1232 |
++ break; |
1233 |
++ |
1234 |
++ if (rlwinm == 0x556C083CU && |
1235 |
++ add == 0x7D6C5A14U && |
1236 |
++ (li2 & 0xFFFF0000U) == 0x39800000U && |
1237 |
++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U && |
1238 |
++ mtctr == 0x7D8903A6U && |
1239 |
++ (li3 & 0xFFFF0000U) == 0x39800000U && |
1240 |
++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U && |
1241 |
++ bctr == 0x4E800420U) |
1242 |
++ { |
1243 |
++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1244 |
++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1245 |
++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; |
1246 |
++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1247 |
++ regs->ctr += (addis2 & 0xFFFFU) << 16; |
1248 |
++ regs->nip = regs->ctr; |
1249 |
++ return 4; |
1250 |
++ } |
1251 |
++ } |
1252 |
++ } while (0); |
1253 |
++ |
1254 |
++#if 0 |
1255 |
++ do { /* PaX: unpatched PLT emulation #2 */ |
1256 |
++ unsigned int lis, lwzu, b, bctr; |
1257 |
++ |
1258 |
++ err = get_user(lis, (unsigned int *)regs->nip); |
1259 |
++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4)); |
1260 |
++ err |= get_user(b, (unsigned int *)(regs->nip+8)); |
1261 |
++ err |= get_user(bctr, (unsigned int *)(regs->nip+12)); |
1262 |
++ |
1263 |
++ if (err) |
1264 |
++ break; |
1265 |
++ |
1266 |
++ if ((lis & 0xFFFF0000U) == 0x39600000U && |
1267 |
++ (lwzu & 0xU) == 0xU && |
1268 |
++ (b & 0xFC000003U) == 0x48000000U && |
1269 |
++ bctr == 0x4E800420U) |
1270 |
++ { |
1271 |
++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; |
1272 |
++ unsigned long addr = b | 0xFC000000UL; |
1273 |
++ |
1274 |
++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
1275 |
++ err = get_user(addis, (unsigned int*)addr); |
1276 |
++ err |= get_user(addi, (unsigned int*)(addr+4)); |
1277 |
++ err |= get_user(rlwinm, (unsigned int*)(addr+8)); |
1278 |
++ err |= get_user(add, (unsigned int*)(addr+12)); |
1279 |
++ err |= get_user(li2, (unsigned int*)(addr+16)); |
1280 |
++ err |= get_user(addis2, (unsigned int*)(addr+20)); |
1281 |
++ err |= get_user(mtctr, (unsigned int*)(addr+24)); |
1282 |
++ err |= get_user(li3, (unsigned int*)(addr+28)); |
1283 |
++ err |= get_user(addis3, (unsigned int*)(addr+32)); |
1284 |
++ err |= get_user(bctr, (unsigned int*)(addr+36)); |
1285 |
++ |
1286 |
++ if (err) |
1287 |
++ break; |
1288 |
++ |
1289 |
++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U && |
1290 |
++ (addi & 0xFFFF0000U) == 0x396B0000U && |
1291 |
++ rlwinm == 0x556C083CU && |
1292 |
++ add == 0x7D6C5A14U && |
1293 |
++ (li2 & 0xFFFF0000U) == 0x39800000U && |
1294 |
++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U && |
1295 |
++ mtctr == 0x7D8903A6U && |
1296 |
++ (li3 & 0xFFFF0000U) == 0x39800000U && |
1297 |
++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U && |
1298 |
++ bctr == 0x4E800420U) |
1299 |
++ { |
1300 |
++ regs->gpr[PT_R11] = |
1301 |
++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1302 |
++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1303 |
++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; |
1304 |
++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1305 |
++ regs->ctr += (addis2 & 0xFFFFU) << 16; |
1306 |
++ regs->nip = regs->ctr; |
1307 |
++ return 4; |
1308 |
++ } |
1309 |
++ } |
1310 |
++ } while (0); |
1311 |
++#endif |
1312 |
++ |
1313 |
++ do { /* PaX: unpatched PLT emulation #3 */ |
1314 |
++ unsigned int li, b; |
1315 |
++ |
1316 |
++ err = get_user(li, (unsigned int *)regs->nip); |
1317 |
++ err |= get_user(b, (unsigned int *)(regs->nip+4)); |
1318 |
++ |
1319 |
++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { |
1320 |
++ unsigned int addis, lwz, mtctr, bctr; |
1321 |
++ unsigned long addr = b | 0xFC000000UL; |
1322 |
++ |
1323 |
++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
1324 |
++ err = get_user(addis, (unsigned int *)addr); |
1325 |
++ err |= get_user(lwz, (unsigned int *)(addr+4)); |
1326 |
++ err |= get_user(mtctr, (unsigned int *)(addr+8)); |
1327 |
++ err |= get_user(bctr, (unsigned int *)(addr+12)); |
1328 |
++ |
1329 |
++ if (err) |
1330 |
++ break; |
1331 |
++ |
1332 |
++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U && |
1333 |
++ (lwz & 0xFFFF0000U) == 0x816B0000U && |
1334 |
++ mtctr == 0x7D6903A6U && |
1335 |
++ bctr == 0x4E800420U) |
1336 |
++ { |
1337 |
++ unsigned int r11; |
1338 |
++ |
1339 |
++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1340 |
++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1341 |
++ |
1342 |
++ err = get_user(r11, (unsigned int *)addr); |
1343 |
++ if (err) |
1344 |
++ break; |
1345 |
++ |
1346 |
++ regs->gpr[PT_R11] = r11; |
1347 |
++ regs->ctr = r11; |
1348 |
++ regs->nip = r11; |
1349 |
++ return 4; |
1350 |
++ } |
1351 |
++ } |
1352 |
++ } while (0); |
1353 |
++#endif |
1354 |
++ |
1355 |
++#ifdef CONFIG_PAX_EMUSIGRT |
1356 |
++ do { /* PaX: sigreturn emulation */ |
1357 |
++ unsigned int li, sc; |
1358 |
++ |
1359 |
++ err = get_user(li, (unsigned int *)regs->nip); |
1360 |
++ err |= get_user(sc, (unsigned int *)(regs->nip+4)); |
1361 |
++ |
1362 |
++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) { |
1363 |
++ struct vm_area_struct *vma; |
1364 |
++ unsigned long call_syscall; |
1365 |
++ |
1366 |
++ down_read(¤t->mm->mmap_sem); |
1367 |
++ call_syscall = current->mm->call_syscall; |
1368 |
++ up_read(¤t->mm->mmap_sem); |
1369 |
++ if (likely(call_syscall)) |
1370 |
++ goto emulate; |
1371 |
++ |
1372 |
++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
1373 |
++ |
1374 |
++ down_write(¤t->mm->mmap_sem); |
1375 |
++ if (current->mm->call_syscall) { |
1376 |
++ call_syscall = current->mm->call_syscall; |
1377 |
++ up_write(¤t->mm->mmap_sem); |
1378 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
1379 |
++ goto emulate; |
1380 |
++ } |
1381 |
++ |
1382 |
++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
1383 |
++ if (!vma || (call_syscall & ~PAGE_MASK)) { |
1384 |
++ up_write(¤t->mm->mmap_sem); |
1385 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
1386 |
++ return 1; |
1387 |
++ } |
1388 |
++ |
1389 |
++ if (pax_insert_vma(vma, call_syscall)) { |
1390 |
++ up_write(¤t->mm->mmap_sem); |
1391 |
++ kmem_cache_free(vm_area_cachep, vma); |
1392 |
++ return 1; |
1393 |
++ } |
1394 |
++ |
1395 |
++ current->mm->call_syscall = call_syscall; |
1396 |
++ up_write(¤t->mm->mmap_sem); |
1397 |
++ |
1398 |
++emulate: |
1399 |
++ regs->gpr[PT_R0] = __NR_sigreturn; |
1400 |
++ regs->nip = call_syscall; |
1401 |
++ return 5; |
1402 |
++ } |
1403 |
++ } while (0); |
1404 |
++ |
1405 |
++ do { /* PaX: rt_sigreturn emulation */ |
1406 |
++ unsigned int li, sc; |
1407 |
++ |
1408 |
++ err = get_user(li, (unsigned int *)regs->nip); |
1409 |
++ err |= get_user(sc, (unsigned int *)(regs->nip+4)); |
1410 |
++ |
1411 |
++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) { |
1412 |
++ struct vm_area_struct *vma; |
1413 |
++ unsigned int call_syscall; |
1414 |
++ |
1415 |
++ down_read(¤t->mm->mmap_sem); |
1416 |
++ call_syscall = current->mm->call_syscall; |
1417 |
++ up_read(¤t->mm->mmap_sem); |
1418 |
++ if (likely(call_syscall)) |
1419 |
++ goto rt_emulate; |
1420 |
++ |
1421 |
++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
1422 |
++ |
1423 |
++ down_write(¤t->mm->mmap_sem); |
1424 |
++ if (current->mm->call_syscall) { |
1425 |
++ call_syscall = current->mm->call_syscall; |
1426 |
++ up_write(¤t->mm->mmap_sem); |
1427 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
1428 |
++ goto rt_emulate; |
1429 |
++ } |
1430 |
++ |
1431 |
++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
1432 |
++ if (!vma || (call_syscall & ~PAGE_MASK)) { |
1433 |
++ up_write(¤t->mm->mmap_sem); |
1434 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
1435 |
++ return 1; |
1436 |
++ } |
1437 |
++ |
1438 |
++ if (pax_insert_vma(vma, call_syscall)) { |
1439 |
++ up_write(¤t->mm->mmap_sem); |
1440 |
++ kmem_cache_free(vm_area_cachep, vma); |
1441 |
++ return 1; |
1442 |
++ } |
1443 |
++ |
1444 |
++ current->mm->call_syscall = call_syscall; |
1445 |
++ up_write(¤t->mm->mmap_sem); |
1446 |
++ |
1447 |
++rt_emulate: |
1448 |
++ regs->gpr[PT_R0] = __NR_rt_sigreturn; |
1449 |
++ regs->nip = call_syscall; |
1450 |
++ return 6; |
1451 |
++ } |
1452 |
++ } while (0); |
1453 |
++#endif |
1454 |
++ |
1455 |
++ return 1; |
1456 |
++} |
1457 |
++ |
1458 |
++void pax_report_insns(void *pc, void *sp) |
1459 |
++{ |
1460 |
++ unsigned long i; |
1461 |
++ |
1462 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
1463 |
++ for (i = 0; i < 5; i++) { |
1464 |
++ unsigned int c; |
1465 |
++ if (get_user(c, (unsigned int *)pc+i)) |
1466 |
++ printk("???????? "); |
1467 |
++ else |
1468 |
++ printk("%08x ", c); |
1469 |
++ } |
1470 |
++ printk("\n"); |
1471 |
++} |
1472 |
++#endif |
1473 |
++ |
1474 |
+ /* |
1475 |
+ * Check whether the instruction at regs->nip is a store using |
1476 |
+ * an update addressing form which will update r1. |
1477 |
+@@ -157,7 +520,7 @@ int __kprobes do_page_fault(struct pt_re |
1478 |
+ * indicate errors in DSISR but can validly be set in SRR1. |
1479 |
+ */ |
1480 |
+ if (trap == 0x400) |
1481 |
+- error_code &= 0x48200000; |
1482 |
++ error_code &= 0x58200000; |
1483 |
+ else |
1484 |
+ is_write = error_code & DSISR_ISSTORE; |
1485 |
+ #else |
1486 |
+@@ -357,6 +720,37 @@ bad_area: |
1487 |
+ bad_area_nosemaphore: |
1488 |
+ /* User mode accesses cause a SIGSEGV */ |
1489 |
+ if (user_mode(regs)) { |
1490 |
++ |
1491 |
++#ifdef CONFIG_PAX_PAGEEXEC |
1492 |
++ if (mm->pax_flags & MF_PAX_PAGEEXEC) { |
1493 |
++#ifdef CONFIG_PPC64 |
1494 |
++ if (is_exec && (error_code & DSISR_PROTFAULT)) { |
1495 |
++#else |
1496 |
++ if (is_exec && regs->nip == address) { |
1497 |
++#endif |
1498 |
++ switch (pax_handle_fetch_fault(regs)) { |
1499 |
++ |
1500 |
++#ifdef CONFIG_PAX_EMUPLT |
1501 |
++ case 2: |
1502 |
++ case 3: |
1503 |
++ case 4: |
1504 |
++ return 0; |
1505 |
++#endif |
1506 |
++ |
1507 |
++#ifdef CONFIG_PAX_EMUSIGRT |
1508 |
++ case 5: |
1509 |
++ case 6: |
1510 |
++ return 0; |
1511 |
++#endif |
1512 |
++ |
1513 |
++ } |
1514 |
++ |
1515 |
++ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]); |
1516 |
++ do_group_exit(SIGKILL); |
1517 |
++ } |
1518 |
++ } |
1519 |
++#endif |
1520 |
++ |
1521 |
+ _exception(SIGSEGV, regs, code, address); |
1522 |
+ return 0; |
1523 |
+ } |
1524 |
+diff -urNp linux-2.6.24.4/arch/powerpc/mm/mmap.c linux-2.6.24.4/arch/powerpc/mm/mmap.c |
1525 |
+--- linux-2.6.24.4/arch/powerpc/mm/mmap.c 2008-03-24 14:49:18.000000000 -0400 |
1526 |
++++ linux-2.6.24.4/arch/powerpc/mm/mmap.c 2008-03-26 17:56:55.000000000 -0400 |
1527 |
+@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str |
1528 |
+ */ |
1529 |
+ if (mmap_is_legacy()) { |
1530 |
+ mm->mmap_base = TASK_UNMAPPED_BASE; |
1531 |
++ |
1532 |
++#ifdef CONFIG_PAX_RANDMMAP |
1533 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
1534 |
++ mm->mmap_base += mm->delta_mmap; |
1535 |
++#endif |
1536 |
++ |
1537 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
1538 |
+ mm->unmap_area = arch_unmap_area; |
1539 |
+ } else { |
1540 |
+ mm->mmap_base = mmap_base(); |
1541 |
++ |
1542 |
++#ifdef CONFIG_PAX_RANDMMAP |
1543 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
1544 |
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; |
1545 |
++#endif |
1546 |
++ |
1547 |
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
1548 |
+ mm->unmap_area = arch_unmap_area_topdown; |
1549 |
+ } |
1550 |
+diff -urNp linux-2.6.24.4/arch/ppc/mm/fault.c linux-2.6.24.4/arch/ppc/mm/fault.c |
1551 |
+--- linux-2.6.24.4/arch/ppc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400 |
1552 |
++++ linux-2.6.24.4/arch/ppc/mm/fault.c 2008-03-26 18:53:27.000000000 -0400 |
1553 |
+@@ -25,6 +25,11 @@ |
1554 |
+ #include <linux/interrupt.h> |
1555 |
+ #include <linux/highmem.h> |
1556 |
+ #include <linux/module.h> |
1557 |
++#include <linux/slab.h> |
1558 |
++#include <linux/pagemap.h> |
1559 |
++#include <linux/compiler.h> |
1560 |
++#include <linux/binfmts.h> |
1561 |
++#include <linux/unistd.h> |
1562 |
+ |
1563 |
+ #include <asm/page.h> |
1564 |
+ #include <asm/pgtable.h> |
1565 |
+@@ -48,6 +53,363 @@ unsigned long pte_misses; /* updated by |
1566 |
+ unsigned long pte_errors; /* updated by do_page_fault() */ |
1567 |
+ unsigned int probingmem; |
1568 |
+ |
1569 |
++#ifdef CONFIG_PAX_EMUSIGRT |
1570 |
++void pax_syscall_close(struct vm_area_struct *vma) |
1571 |
++{ |
1572 |
++ vma->vm_mm->call_syscall = 0UL; |
1573 |
++} |
1574 |
++ |
1575 |
++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type) |
1576 |
++{ |
1577 |
++ struct page *page; |
1578 |
++ unsigned int *kaddr; |
1579 |
++ |
1580 |
++ page = alloc_page(GFP_HIGHUSER); |
1581 |
++ if (!page) |
1582 |
++ return NOPAGE_OOM; |
1583 |
++ |
1584 |
++ kaddr = kmap(page); |
1585 |
++ memset(kaddr, 0, PAGE_SIZE); |
1586 |
++ kaddr[0] = 0x44000002U; /* sc */ |
1587 |
++ __flush_dcache_icache(kaddr); |
1588 |
++ kunmap(page); |
1589 |
++ if (type) |
1590 |
++ *type = VM_FAULT_MAJOR; |
1591 |
++ return page; |
1592 |
++} |
1593 |
++ |
1594 |
++static struct vm_operations_struct pax_vm_ops = { |
1595 |
++ .close = pax_syscall_close, |
1596 |
++ .nopage = pax_syscall_nopage, |
1597 |
++}; |
1598 |
++ |
1599 |
++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) |
1600 |
++{ |
1601 |
++ int ret; |
1602 |
++ |
1603 |
++ vma->vm_mm = current->mm; |
1604 |
++ vma->vm_start = addr; |
1605 |
++ vma->vm_end = addr + PAGE_SIZE; |
1606 |
++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; |
1607 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
1608 |
++ vma->vm_ops = &pax_vm_ops; |
1609 |
++ |
1610 |
++ ret = insert_vm_struct(current->mm, vma); |
1611 |
++ if (ret) |
1612 |
++ return ret; |
1613 |
++ |
1614 |
++ ++current->mm->total_vm; |
1615 |
++ return 0; |
1616 |
++} |
1617 |
++#endif |
1618 |
++ |
1619 |
++#ifdef CONFIG_PAX_PAGEEXEC |
1620 |
++/* |
1621 |
++ * PaX: decide what to do with offenders (regs->nip = fault address) |
1622 |
++ * |
1623 |
++ * returns 1 when task should be killed |
1624 |
++ * 2 when patched GOT trampoline was detected |
1625 |
++ * 3 when patched PLT trampoline was detected |
1626 |
++ * 4 when unpatched PLT trampoline was detected |
1627 |
++ * 5 when sigreturn trampoline was detected |
1628 |
++ * 6 when rt_sigreturn trampoline was detected |
1629 |
++ */ |
1630 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
1631 |
++{ |
1632 |
++ |
1633 |
++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT) |
1634 |
++ int err; |
1635 |
++#endif |
1636 |
++ |
1637 |
++#ifdef CONFIG_PAX_EMUPLT |
1638 |
++ do { /* PaX: patched GOT emulation */ |
1639 |
++ unsigned int blrl; |
1640 |
++ |
1641 |
++ err = get_user(blrl, (unsigned int *)regs->nip); |
1642 |
++ |
1643 |
++ if (!err && blrl == 0x4E800021U) { |
1644 |
++ unsigned long temp = regs->nip; |
1645 |
++ |
1646 |
++ regs->nip = regs->link & 0xFFFFFFFCUL; |
1647 |
++ regs->link = temp + 4UL; |
1648 |
++ return 2; |
1649 |
++ } |
1650 |
++ } while (0); |
1651 |
++ |
1652 |
++ do { /* PaX: patched PLT emulation #1 */ |
1653 |
++ unsigned int b; |
1654 |
++ |
1655 |
++ err = get_user(b, (unsigned int *)regs->nip); |
1656 |
++ |
1657 |
++ if (!err && (b & 0xFC000003U) == 0x48000000U) { |
1658 |
++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL); |
1659 |
++ return 3; |
1660 |
++ } |
1661 |
++ } while (0); |
1662 |
++ |
1663 |
++ do { /* PaX: unpatched PLT emulation #1 */ |
1664 |
++ unsigned int li, b; |
1665 |
++ |
1666 |
++ err = get_user(li, (unsigned int *)regs->nip); |
1667 |
++ err |= get_user(b, (unsigned int *)(regs->nip+4)); |
1668 |
++ |
1669 |
++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { |
1670 |
++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; |
1671 |
++ unsigned long addr = b | 0xFC000000UL; |
1672 |
++ |
1673 |
++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
1674 |
++ err = get_user(rlwinm, (unsigned int *)addr); |
1675 |
++ err |= get_user(add, (unsigned int *)(addr+4)); |
1676 |
++ err |= get_user(li2, (unsigned int *)(addr+8)); |
1677 |
++ err |= get_user(addis2, (unsigned int *)(addr+12)); |
1678 |
++ err |= get_user(mtctr, (unsigned int *)(addr+16)); |
1679 |
++ err |= get_user(li3, (unsigned int *)(addr+20)); |
1680 |
++ err |= get_user(addis3, (unsigned int *)(addr+24)); |
1681 |
++ err |= get_user(bctr, (unsigned int *)(addr+28)); |
1682 |
++ |
1683 |
++ if (err) |
1684 |
++ break; |
1685 |
++ |
1686 |
++ if (rlwinm == 0x556C083CU && |
1687 |
++ add == 0x7D6C5A14U && |
1688 |
++ (li2 & 0xFFFF0000U) == 0x39800000U && |
1689 |
++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U && |
1690 |
++ mtctr == 0x7D8903A6U && |
1691 |
++ (li3 & 0xFFFF0000U) == 0x39800000U && |
1692 |
++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U && |
1693 |
++ bctr == 0x4E800420U) |
1694 |
++ { |
1695 |
++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1696 |
++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1697 |
++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; |
1698 |
++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1699 |
++ regs->ctr += (addis2 & 0xFFFFU) << 16; |
1700 |
++ regs->nip = regs->ctr; |
1701 |
++ return 4; |
1702 |
++ } |
1703 |
++ } |
1704 |
++ } while (0); |
1705 |
++ |
1706 |
++#if 0 |
1707 |
++ do { /* PaX: unpatched PLT emulation #2 */ |
1708 |
++ unsigned int lis, lwzu, b, bctr; |
1709 |
++ |
1710 |
++ err = get_user(lis, (unsigned int *)regs->nip); |
1711 |
++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4)); |
1712 |
++ err |= get_user(b, (unsigned int *)(regs->nip+8)); |
1713 |
++ err |= get_user(bctr, (unsigned int *)(regs->nip+12)); |
1714 |
++ |
1715 |
++ if (err) |
1716 |
++ break; |
1717 |
++ |
1718 |
++ if ((lis & 0xFFFF0000U) == 0x39600000U && |
1719 |
++ (lwzu & 0xU) == 0xU && |
1720 |
++ (b & 0xFC000003U) == 0x48000000U && |
1721 |
++ bctr == 0x4E800420U) |
1722 |
++ { |
1723 |
++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; |
1724 |
++ unsigned long addr = b | 0xFC000000UL; |
1725 |
++ |
1726 |
++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
1727 |
++ err = get_user(addis, (unsigned int*)addr); |
1728 |
++ err |= get_user(addi, (unsigned int*)(addr+4)); |
1729 |
++ err |= get_user(rlwinm, (unsigned int*)(addr+8)); |
1730 |
++ err |= get_user(add, (unsigned int*)(addr+12)); |
1731 |
++ err |= get_user(li2, (unsigned int*)(addr+16)); |
1732 |
++ err |= get_user(addis2, (unsigned int*)(addr+20)); |
1733 |
++ err |= get_user(mtctr, (unsigned int*)(addr+24)); |
1734 |
++ err |= get_user(li3, (unsigned int*)(addr+28)); |
1735 |
++ err |= get_user(addis3, (unsigned int*)(addr+32)); |
1736 |
++ err |= get_user(bctr, (unsigned int*)(addr+36)); |
1737 |
++ |
1738 |
++ if (err) |
1739 |
++ break; |
1740 |
++ |
1741 |
++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U && |
1742 |
++ (addi & 0xFFFF0000U) == 0x396B0000U && |
1743 |
++ rlwinm == 0x556C083CU && |
1744 |
++ add == 0x7D6C5A14U && |
1745 |
++ (li2 & 0xFFFF0000U) == 0x39800000U && |
1746 |
++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U && |
1747 |
++ mtctr == 0x7D8903A6U && |
1748 |
++ (li3 & 0xFFFF0000U) == 0x39800000U && |
1749 |
++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U && |
1750 |
++ bctr == 0x4E800420U) |
1751 |
++ { |
1752 |
++ regs->gpr[PT_R11] = |
1753 |
++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1754 |
++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1755 |
++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; |
1756 |
++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1757 |
++ regs->ctr += (addis2 & 0xFFFFU) << 16; |
1758 |
++ regs->nip = regs->ctr; |
1759 |
++ return 4; |
1760 |
++ } |
1761 |
++ } |
1762 |
++ } while (0); |
1763 |
++#endif |
1764 |
++ |
1765 |
++ do { /* PaX: unpatched PLT emulation #3 */ |
1766 |
++ unsigned int li, b; |
1767 |
++ |
1768 |
++ err = get_user(li, (unsigned int *)regs->nip); |
1769 |
++ err |= get_user(b, (unsigned int *)(regs->nip+4)); |
1770 |
++ |
1771 |
++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { |
1772 |
++ unsigned int addis, lwz, mtctr, bctr; |
1773 |
++ unsigned long addr = b | 0xFC000000UL; |
1774 |
++ |
1775 |
++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
1776 |
++ err = get_user(addis, (unsigned int *)addr); |
1777 |
++ err |= get_user(lwz, (unsigned int *)(addr+4)); |
1778 |
++ err |= get_user(mtctr, (unsigned int *)(addr+8)); |
1779 |
++ err |= get_user(bctr, (unsigned int *)(addr+12)); |
1780 |
++ |
1781 |
++ if (err) |
1782 |
++ break; |
1783 |
++ |
1784 |
++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U && |
1785 |
++ (lwz & 0xFFFF0000U) == 0x816B0000U && |
1786 |
++ mtctr == 0x7D6903A6U && |
1787 |
++ bctr == 0x4E800420U) |
1788 |
++ { |
1789 |
++ unsigned int r11; |
1790 |
++ |
1791 |
++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1792 |
++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
1793 |
++ |
1794 |
++ err = get_user(r11, (unsigned int *)addr); |
1795 |
++ if (err) |
1796 |
++ break; |
1797 |
++ |
1798 |
++ regs->gpr[PT_R11] = r11; |
1799 |
++ regs->ctr = r11; |
1800 |
++ regs->nip = r11; |
1801 |
++ return 4; |
1802 |
++ } |
1803 |
++ } |
1804 |
++ } while (0); |
1805 |
++#endif |
1806 |
++ |
1807 |
++#ifdef CONFIG_PAX_EMUSIGRT |
1808 |
++ do { /* PaX: sigreturn emulation */ |
1809 |
++ unsigned int li, sc; |
1810 |
++ |
1811 |
++ err = get_user(li, (unsigned int *)regs->nip); |
1812 |
++ err |= get_user(sc, (unsigned int *)(regs->nip+4)); |
1813 |
++ |
1814 |
++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) { |
1815 |
++ struct vm_area_struct *vma; |
1816 |
++ unsigned long call_syscall; |
1817 |
++ |
1818 |
++ down_read(¤t->mm->mmap_sem); |
1819 |
++ call_syscall = current->mm->call_syscall; |
1820 |
++ up_read(¤t->mm->mmap_sem); |
1821 |
++ if (likely(call_syscall)) |
1822 |
++ goto emulate; |
1823 |
++ |
1824 |
++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
1825 |
++ |
1826 |
++ down_write(¤t->mm->mmap_sem); |
1827 |
++ if (current->mm->call_syscall) { |
1828 |
++ call_syscall = current->mm->call_syscall; |
1829 |
++ up_write(¤t->mm->mmap_sem); |
1830 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
1831 |
++ goto emulate; |
1832 |
++ } |
1833 |
++ |
1834 |
++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
1835 |
++ if (!vma || (call_syscall & ~PAGE_MASK)) { |
1836 |
++ up_write(¤t->mm->mmap_sem); |
1837 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
1838 |
++ return 1; |
1839 |
++ } |
1840 |
++ |
1841 |
++ if (pax_insert_vma(vma, call_syscall)) { |
1842 |
++ up_write(¤t->mm->mmap_sem); |
1843 |
++ kmem_cache_free(vm_area_cachep, vma); |
1844 |
++ return 1; |
1845 |
++ } |
1846 |
++ |
1847 |
++ current->mm->call_syscall = call_syscall; |
1848 |
++ up_write(¤t->mm->mmap_sem); |
1849 |
++ |
1850 |
++emulate: |
1851 |
++ regs->gpr[PT_R0] = __NR_sigreturn; |
1852 |
++ regs->nip = call_syscall; |
1853 |
++ return 5; |
1854 |
++ } |
1855 |
++ } while (0); |
1856 |
++ |
1857 |
++ do { /* PaX: rt_sigreturn emulation */ |
1858 |
++ unsigned int li, sc; |
1859 |
++ |
1860 |
++ err = get_user(li, (unsigned int *)regs->nip); |
1861 |
++ err |= get_user(sc, (unsigned int *)(regs->nip+4)); |
1862 |
++ |
1863 |
++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) { |
1864 |
++ struct vm_area_struct *vma; |
1865 |
++ unsigned int call_syscall; |
1866 |
++ |
1867 |
++ down_read(¤t->mm->mmap_sem); |
1868 |
++ call_syscall = current->mm->call_syscall; |
1869 |
++ up_read(¤t->mm->mmap_sem); |
1870 |
++ if (likely(call_syscall)) |
1871 |
++ goto rt_emulate; |
1872 |
++ |
1873 |
++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
1874 |
++ |
1875 |
++ down_write(¤t->mm->mmap_sem); |
1876 |
++ if (current->mm->call_syscall) { |
1877 |
++ call_syscall = current->mm->call_syscall; |
1878 |
++ up_write(¤t->mm->mmap_sem); |
1879 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
1880 |
++ goto rt_emulate; |
1881 |
++ } |
1882 |
++ |
1883 |
++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
1884 |
++ if (!vma || (call_syscall & ~PAGE_MASK)) { |
1885 |
++ up_write(¤t->mm->mmap_sem); |
1886 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
1887 |
++ return 1; |
1888 |
++ } |
1889 |
++ |
1890 |
++ if (pax_insert_vma(vma, call_syscall)) { |
1891 |
++ up_write(¤t->mm->mmap_sem); |
1892 |
++ kmem_cache_free(vm_area_cachep, vma); |
1893 |
++ return 1; |
1894 |
++ } |
1895 |
++ |
1896 |
++ current->mm->call_syscall = call_syscall; |
1897 |
++ up_write(¤t->mm->mmap_sem); |
1898 |
++ |
1899 |
++rt_emulate: |
1900 |
++ regs->gpr[PT_R0] = __NR_rt_sigreturn; |
1901 |
++ regs->nip = call_syscall; |
1902 |
++ return 6; |
1903 |
++ } |
1904 |
++ } while (0); |
1905 |
++#endif |
1906 |
++ |
1907 |
++ return 1; |
1908 |
++} |
1909 |
++ |
1910 |
++void pax_report_insns(void *pc, void *sp) |
1911 |
++{ |
1912 |
++ unsigned long i; |
1913 |
++ |
1914 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
1915 |
++ for (i = 0; i < 5; i++) { |
1916 |
++ unsigned int c; |
1917 |
++ if (get_user(c, (unsigned int *)pc+i)) |
1918 |
++ printk("???????? "); |
1919 |
++ else |
1920 |
++ printk("%08x ", c); |
1921 |
++ } |
1922 |
++ printk("\n"); |
1923 |
++} |
1924 |
++#endif |
1925 |
++ |
1926 |
+ /* |
1927 |
+ * Check whether the instruction at regs->nip is a store using |
1928 |
+ * an update addressing form which will update r1. |
1929 |
+@@ -109,7 +471,7 @@ int do_page_fault(struct pt_regs *regs, |
1930 |
+ * indicate errors in DSISR but can validly be set in SRR1. |
1931 |
+ */ |
1932 |
+ if (TRAP(regs) == 0x400) |
1933 |
+- error_code &= 0x48200000; |
1934 |
++ error_code &= 0x58200000; |
1935 |
+ else |
1936 |
+ is_write = error_code & 0x02000000; |
1937 |
+ #endif /* CONFIG_4xx || CONFIG_BOOKE */ |
1938 |
+@@ -204,15 +566,14 @@ good_area: |
1939 |
+ pte_t *ptep; |
1940 |
+ pmd_t *pmdp; |
1941 |
+ |
1942 |
+-#if 0 |
1943 |
++#if 1 |
1944 |
+ /* It would be nice to actually enforce the VM execute |
1945 |
+ permission on CPUs which can do so, but far too |
1946 |
+ much stuff in userspace doesn't get the permissions |
1947 |
+ right, so we let any page be executed for now. */ |
1948 |
+ if (! (vma->vm_flags & VM_EXEC)) |
1949 |
+ goto bad_area; |
1950 |
+-#endif |
1951 |
+- |
1952 |
++#else |
1953 |
+ /* Since 4xx/Book-E supports per-page execute permission, |
1954 |
+ * we lazily flush dcache to icache. */ |
1955 |
+ ptep = NULL; |
1956 |
+@@ -235,6 +596,7 @@ good_area: |
1957 |
+ pte_unmap_unlock(ptep, ptl); |
1958 |
+ } |
1959 |
+ #endif |
1960 |
++#endif |
1961 |
+ /* a read */ |
1962 |
+ } else { |
1963 |
+ /* protection fault */ |
1964 |
+@@ -278,6 +640,33 @@ bad_area: |
1965 |
+ |
1966 |
+ /* User mode accesses cause a SIGSEGV */ |
1967 |
+ if (user_mode(regs)) { |
1968 |
++ |
1969 |
++#ifdef CONFIG_PAX_PAGEEXEC |
1970 |
++ if (mm->pax_flags & MF_PAX_PAGEEXEC) { |
1971 |
++ if ((TRAP(regs) == 0x400) && (regs->nip == address)) { |
1972 |
++ switch (pax_handle_fetch_fault(regs)) { |
1973 |
++ |
1974 |
++#ifdef CONFIG_PAX_EMUPLT |
1975 |
++ case 2: |
1976 |
++ case 3: |
1977 |
++ case 4: |
1978 |
++ return 0; |
1979 |
++#endif |
1980 |
++ |
1981 |
++#ifdef CONFIG_PAX_EMUSIGRT |
1982 |
++ case 5: |
1983 |
++ case 6: |
1984 |
++ return 0; |
1985 |
++#endif |
1986 |
++ |
1987 |
++ } |
1988 |
++ |
1989 |
++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]); |
1990 |
++ do_group_exit(SIGKILL); |
1991 |
++ } |
1992 |
++ } |
1993 |
++#endif |
1994 |
++ |
1995 |
+ _exception(SIGSEGV, regs, code, address); |
1996 |
+ return 0; |
1997 |
+ } |
1998 |
+diff -urNp linux-2.6.24.4/arch/s390/kernel/module.c linux-2.6.24.4/arch/s390/kernel/module.c |
1999 |
+--- linux-2.6.24.4/arch/s390/kernel/module.c 2008-03-24 14:49:18.000000000 -0400 |
2000 |
++++ linux-2.6.24.4/arch/s390/kernel/module.c 2008-03-26 17:56:55.000000000 -0400 |
2001 |
+@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr, |
2002 |
+ |
2003 |
+ /* Increase core size by size of got & plt and set start |
2004 |
+ offsets for got and plt. */ |
2005 |
+- me->core_size = ALIGN(me->core_size, 4); |
2006 |
+- me->arch.got_offset = me->core_size; |
2007 |
+- me->core_size += me->arch.got_size; |
2008 |
+- me->arch.plt_offset = me->core_size; |
2009 |
+- me->core_size += me->arch.plt_size; |
2010 |
++ me->core_size_rw = ALIGN(me->core_size_rw, 4); |
2011 |
++ me->arch.got_offset = me->core_size_rw; |
2012 |
++ me->core_size_rw += me->arch.got_size; |
2013 |
++ me->arch.plt_offset = me->core_size_rx; |
2014 |
++ me->core_size_rx += me->arch.plt_size; |
2015 |
+ return 0; |
2016 |
+ } |
2017 |
+ |
2018 |
+@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
2019 |
+ if (info->got_initialized == 0) { |
2020 |
+ Elf_Addr *gotent; |
2021 |
+ |
2022 |
+- gotent = me->module_core + me->arch.got_offset + |
2023 |
++ gotent = me->module_core_rw + me->arch.got_offset + |
2024 |
+ info->got_offset; |
2025 |
+ *gotent = val; |
2026 |
+ info->got_initialized = 1; |
2027 |
+@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
2028 |
+ else if (r_type == R_390_GOTENT || |
2029 |
+ r_type == R_390_GOTPLTENT) |
2030 |
+ *(unsigned int *) loc = |
2031 |
+- (val + (Elf_Addr) me->module_core - loc) >> 1; |
2032 |
++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1; |
2033 |
+ else if (r_type == R_390_GOT64 || |
2034 |
+ r_type == R_390_GOTPLT64) |
2035 |
+ *(unsigned long *) loc = val; |
2036 |
+@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
2037 |
+ case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */ |
2038 |
+ if (info->plt_initialized == 0) { |
2039 |
+ unsigned int *ip; |
2040 |
+- ip = me->module_core + me->arch.plt_offset + |
2041 |
++ ip = me->module_core_rx + me->arch.plt_offset + |
2042 |
+ info->plt_offset; |
2043 |
+ #ifndef CONFIG_64BIT |
2044 |
+ ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */ |
2045 |
+@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
2046 |
+ val = me->arch.plt_offset - me->arch.got_offset + |
2047 |
+ info->plt_offset + rela->r_addend; |
2048 |
+ else |
2049 |
+- val = (Elf_Addr) me->module_core + |
2050 |
++ val = (Elf_Addr) me->module_core_rx + |
2051 |
+ me->arch.plt_offset + info->plt_offset + |
2052 |
+ rela->r_addend - loc; |
2053 |
+ if (r_type == R_390_PLT16DBL) |
2054 |
+@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
2055 |
+ case R_390_GOTOFF32: /* 32 bit offset to GOT. */ |
2056 |
+ case R_390_GOTOFF64: /* 64 bit offset to GOT. */ |
2057 |
+ val = val + rela->r_addend - |
2058 |
+- ((Elf_Addr) me->module_core + me->arch.got_offset); |
2059 |
++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset); |
2060 |
+ if (r_type == R_390_GOTOFF16) |
2061 |
+ *(unsigned short *) loc = val; |
2062 |
+ else if (r_type == R_390_GOTOFF32) |
2063 |
+@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
2064 |
+ break; |
2065 |
+ case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */ |
2066 |
+ case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */ |
2067 |
+- val = (Elf_Addr) me->module_core + me->arch.got_offset + |
2068 |
++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset + |
2069 |
+ rela->r_addend - loc; |
2070 |
+ if (r_type == R_390_GOTPC) |
2071 |
+ *(unsigned int *) loc = val; |
2072 |
+diff -urNp linux-2.6.24.4/arch/sparc/kernel/ptrace.c linux-2.6.24.4/arch/sparc/kernel/ptrace.c |
2073 |
+--- linux-2.6.24.4/arch/sparc/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400 |
2074 |
++++ linux-2.6.24.4/arch/sparc/kernel/ptrace.c 2008-03-26 17:56:55.000000000 -0400 |
2075 |
+@@ -19,6 +19,7 @@ |
2076 |
+ #include <linux/smp_lock.h> |
2077 |
+ #include <linux/security.h> |
2078 |
+ #include <linux/signal.h> |
2079 |
++#include <linux/grsecurity.h> |
2080 |
+ |
2081 |
+ #include <asm/pgtable.h> |
2082 |
+ #include <asm/system.h> |
2083 |
+@@ -303,6 +304,11 @@ asmlinkage void do_ptrace(struct pt_regs |
2084 |
+ goto out; |
2085 |
+ } |
2086 |
+ |
2087 |
++ if (gr_handle_ptrace(child, request)) { |
2088 |
++ pt_error_return(regs, EPERM); |
2089 |
++ goto out_tsk; |
2090 |
++ } |
2091 |
++ |
2092 |
+ if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) |
2093 |
+ || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { |
2094 |
+ if (ptrace_attach(child)) { |
2095 |
+diff -urNp linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c |
2096 |
+--- linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c 2008-03-24 14:49:18.000000000 -0400 |
2097 |
++++ linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c 2008-03-26 17:56:55.000000000 -0400 |
2098 |
+@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str |
2099 |
+ if (ARCH_SUN4C_SUN4 && len > 0x20000000) |
2100 |
+ return -ENOMEM; |
2101 |
+ if (!addr) |
2102 |
+- addr = TASK_UNMAPPED_BASE; |
2103 |
++ addr = current->mm->mmap_base; |
2104 |
+ |
2105 |
+ if (flags & MAP_SHARED) |
2106 |
+ addr = COLOUR_ALIGN(addr); |
2107 |
+diff -urNp linux-2.6.24.4/arch/sparc/Makefile linux-2.6.24.4/arch/sparc/Makefile |
2108 |
+--- linux-2.6.24.4/arch/sparc/Makefile 2008-03-24 14:49:18.000000000 -0400 |
2109 |
++++ linux-2.6.24.4/arch/sparc/Makefile 2008-03-26 17:56:55.000000000 -0400 |
2110 |
+@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc |
2111 |
+ # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-) |
2112 |
+ INIT_Y := $(patsubst %/, %/built-in.o, $(init-y)) |
2113 |
+ CORE_Y := $(core-y) |
2114 |
+-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ |
2115 |
++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/ |
2116 |
+ CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y)) |
2117 |
+ DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y)) |
2118 |
+ NET_Y := $(patsubst %/, %/built-in.o, $(net-y)) |
2119 |
+diff -urNp linux-2.6.24.4/arch/sparc/mm/fault.c linux-2.6.24.4/arch/sparc/mm/fault.c |
2120 |
+--- linux-2.6.24.4/arch/sparc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400 |
2121 |
++++ linux-2.6.24.4/arch/sparc/mm/fault.c 2008-03-26 18:53:27.000000000 -0400 |
2122 |
+@@ -21,6 +21,10 @@ |
2123 |
+ #include <linux/interrupt.h> |
2124 |
+ #include <linux/module.h> |
2125 |
+ #include <linux/kdebug.h> |
2126 |
++#include <linux/slab.h> |
2127 |
++#include <linux/pagemap.h> |
2128 |
++#include <linux/compiler.h> |
2129 |
++#include <linux/binfmts.h> |
2130 |
+ |
2131 |
+ #include <asm/system.h> |
2132 |
+ #include <asm/page.h> |
2133 |
+@@ -216,6 +220,251 @@ static unsigned long compute_si_addr(str |
2134 |
+ return safe_compute_effective_address(regs, insn); |
2135 |
+ } |
2136 |
+ |
2137 |
++#ifdef CONFIG_PAX_PAGEEXEC |
2138 |
++void pax_emuplt_close(struct vm_area_struct *vma) |
2139 |
++{ |
2140 |
++ vma->vm_mm->call_dl_resolve = 0UL; |
2141 |
++} |
2142 |
++ |
2143 |
++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type) |
2144 |
++{ |
2145 |
++ struct page *page; |
2146 |
++ unsigned int *kaddr; |
2147 |
++ |
2148 |
++ page = alloc_page(GFP_HIGHUSER); |
2149 |
++ if (!page) |
2150 |
++ return NOPAGE_OOM; |
2151 |
++ |
2152 |
++ kaddr = kmap(page); |
2153 |
++ memset(kaddr, 0, PAGE_SIZE); |
2154 |
++ kaddr[0] = 0x9DE3BFA8U; /* save */ |
2155 |
++ flush_dcache_page(page); |
2156 |
++ kunmap(page); |
2157 |
++ if (type) |
2158 |
++ *type = VM_FAULT_MAJOR; |
2159 |
++ |
2160 |
++ return page; |
2161 |
++} |
2162 |
++ |
2163 |
++static struct vm_operations_struct pax_vm_ops = { |
2164 |
++ .close = pax_emuplt_close, |
2165 |
++ .nopage = pax_emuplt_nopage, |
2166 |
++}; |
2167 |
++ |
2168 |
++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) |
2169 |
++{ |
2170 |
++ int ret; |
2171 |
++ |
2172 |
++ vma->vm_mm = current->mm; |
2173 |
++ vma->vm_start = addr; |
2174 |
++ vma->vm_end = addr + PAGE_SIZE; |
2175 |
++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; |
2176 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
2177 |
++ vma->vm_ops = &pax_vm_ops; |
2178 |
++ |
2179 |
++ ret = insert_vm_struct(current->mm, vma); |
2180 |
++ if (ret) |
2181 |
++ return ret; |
2182 |
++ |
2183 |
++ ++current->mm->total_vm; |
2184 |
++ return 0; |
2185 |
++} |
2186 |
++ |
2187 |
++/* |
2188 |
++ * PaX: decide what to do with offenders (regs->pc = fault address) |
2189 |
++ * |
2190 |
++ * returns 1 when task should be killed |
2191 |
++ * 2 when patched PLT trampoline was detected |
2192 |
++ * 3 when unpatched PLT trampoline was detected |
2193 |
++ */ |
2194 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
2195 |
++{ |
2196 |
++ |
2197 |
++#ifdef CONFIG_PAX_EMUPLT |
2198 |
++ int err; |
2199 |
++ |
2200 |
++ do { /* PaX: patched PLT emulation #1 */ |
2201 |
++ unsigned int sethi1, sethi2, jmpl; |
2202 |
++ |
2203 |
++ err = get_user(sethi1, (unsigned int *)regs->pc); |
2204 |
++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4)); |
2205 |
++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8)); |
2206 |
++ |
2207 |
++ if (err) |
2208 |
++ break; |
2209 |
++ |
2210 |
++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && |
2211 |
++ (sethi2 & 0xFFC00000U) == 0x03000000U && |
2212 |
++ (jmpl & 0xFFFFE000U) == 0x81C06000U) |
2213 |
++ { |
2214 |
++ unsigned int addr; |
2215 |
++ |
2216 |
++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10; |
2217 |
++ addr = regs->u_regs[UREG_G1]; |
2218 |
++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); |
2219 |
++ regs->pc = addr; |
2220 |
++ regs->npc = addr+4; |
2221 |
++ return 2; |
2222 |
++ } |
2223 |
++ } while (0); |
2224 |
++ |
2225 |
++ { /* PaX: patched PLT emulation #2 */ |
2226 |
++ unsigned int ba; |
2227 |
++ |
2228 |
++ err = get_user(ba, (unsigned int *)regs->pc); |
2229 |
++ |
2230 |
++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) { |
2231 |
++ unsigned int addr; |
2232 |
++ |
2233 |
++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2); |
2234 |
++ regs->pc = addr; |
2235 |
++ regs->npc = addr+4; |
2236 |
++ return 2; |
2237 |
++ } |
2238 |
++ } |
2239 |
++ |
2240 |
++ do { /* PaX: patched PLT emulation #3 */ |
2241 |
++ unsigned int sethi, jmpl, nop; |
2242 |
++ |
2243 |
++ err = get_user(sethi, (unsigned int *)regs->pc); |
2244 |
++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4)); |
2245 |
++ err |= get_user(nop, (unsigned int *)(regs->pc+8)); |
2246 |
++ |
2247 |
++ if (err) |
2248 |
++ break; |
2249 |
++ |
2250 |
++ if ((sethi & 0xFFC00000U) == 0x03000000U && |
2251 |
++ (jmpl & 0xFFFFE000U) == 0x81C06000U && |
2252 |
++ nop == 0x01000000U) |
2253 |
++ { |
2254 |
++ unsigned int addr; |
2255 |
++ |
2256 |
++ addr = (sethi & 0x003FFFFFU) << 10; |
2257 |
++ regs->u_regs[UREG_G1] = addr; |
2258 |
++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); |
2259 |
++ regs->pc = addr; |
2260 |
++ regs->npc = addr+4; |
2261 |
++ return 2; |
2262 |
++ } |
2263 |
++ } while (0); |
2264 |
++ |
2265 |
++ do { /* PaX: unpatched PLT emulation step 1 */ |
2266 |
++ unsigned int sethi, ba, nop; |
2267 |
++ |
2268 |
++ err = get_user(sethi, (unsigned int *)regs->pc); |
2269 |
++ err |= get_user(ba, (unsigned int *)(regs->pc+4)); |
2270 |
++ err |= get_user(nop, (unsigned int *)(regs->pc+8)); |
2271 |
++ |
2272 |
++ if (err) |
2273 |
++ break; |
2274 |
++ |
2275 |
++ if ((sethi & 0xFFC00000U) == 0x03000000U && |
2276 |
++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) && |
2277 |
++ nop == 0x01000000U) |
2278 |
++ { |
2279 |
++ unsigned int addr, save, call; |
2280 |
++ |
2281 |
++ if ((ba & 0xFFC00000U) == 0x30800000U) |
2282 |
++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2); |
2283 |
++ else |
2284 |
++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2); |
2285 |
++ |
2286 |
++ err = get_user(save, (unsigned int *)addr); |
2287 |
++ err |= get_user(call, (unsigned int *)(addr+4)); |
2288 |
++ err |= get_user(nop, (unsigned int *)(addr+8)); |
2289 |
++ if (err) |
2290 |
++ break; |
2291 |
++ |
2292 |
++ if (save == 0x9DE3BFA8U && |
2293 |
++ (call & 0xC0000000U) == 0x40000000U && |
2294 |
++ nop == 0x01000000U) |
2295 |
++ { |
2296 |
++ struct vm_area_struct *vma; |
2297 |
++ unsigned long call_dl_resolve; |
2298 |
++ |
2299 |
++ down_read(¤t->mm->mmap_sem); |
2300 |
++ call_dl_resolve = current->mm->call_dl_resolve; |
2301 |
++ up_read(¤t->mm->mmap_sem); |
2302 |
++ if (likely(call_dl_resolve)) |
2303 |
++ goto emulate; |
2304 |
++ |
2305 |
++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
2306 |
++ |
2307 |
++ down_write(¤t->mm->mmap_sem); |
2308 |
++ if (current->mm->call_dl_resolve) { |
2309 |
++ call_dl_resolve = current->mm->call_dl_resolve; |
2310 |
++ up_write(¤t->mm->mmap_sem); |
2311 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
2312 |
++ goto emulate; |
2313 |
++ } |
2314 |
++ |
2315 |
++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
2316 |
++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) { |
2317 |
++ up_write(¤t->mm->mmap_sem); |
2318 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
2319 |
++ return 1; |
2320 |
++ } |
2321 |
++ |
2322 |
++ if (pax_insert_vma(vma, call_dl_resolve)) { |
2323 |
++ up_write(¤t->mm->mmap_sem); |
2324 |
++ kmem_cache_free(vm_area_cachep, vma); |
2325 |
++ return 1; |
2326 |
++ } |
2327 |
++ |
2328 |
++ current->mm->call_dl_resolve = call_dl_resolve; |
2329 |
++ up_write(¤t->mm->mmap_sem); |
2330 |
++ |
2331 |
++emulate: |
2332 |
++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; |
2333 |
++ regs->pc = call_dl_resolve; |
2334 |
++ regs->npc = addr+4; |
2335 |
++ return 3; |
2336 |
++ } |
2337 |
++ } |
2338 |
++ } while (0); |
2339 |
++ |
2340 |
++ do { /* PaX: unpatched PLT emulation step 2 */ |
2341 |
++ unsigned int save, call, nop; |
2342 |
++ |
2343 |
++ err = get_user(save, (unsigned int *)(regs->pc-4)); |
2344 |
++ err |= get_user(call, (unsigned int *)regs->pc); |
2345 |
++ err |= get_user(nop, (unsigned int *)(regs->pc+4)); |
2346 |
++ if (err) |
2347 |
++ break; |
2348 |
++ |
2349 |
++ if (save == 0x9DE3BFA8U && |
2350 |
++ (call & 0xC0000000U) == 0x40000000U && |
2351 |
++ nop == 0x01000000U) |
2352 |
++ { |
2353 |
++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2); |
2354 |
++ |
2355 |
++ regs->u_regs[UREG_RETPC] = regs->pc; |
2356 |
++ regs->pc = dl_resolve; |
2357 |
++ regs->npc = dl_resolve+4; |
2358 |
++ return 3; |
2359 |
++ } |
2360 |
++ } while (0); |
2361 |
++#endif |
2362 |
++ |
2363 |
++ return 1; |
2364 |
++} |
2365 |
++ |
2366 |
++void pax_report_insns(void *pc, void *sp) |
2367 |
++{ |
2368 |
++ unsigned long i; |
2369 |
++ |
2370 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
2371 |
++ for (i = 0; i < 5; i++) { |
2372 |
++ unsigned int c; |
2373 |
++ if (get_user(c, (unsigned int *)pc+i)) |
2374 |
++ printk("???????? "); |
2375 |
++ else |
2376 |
++ printk("%08x ", c); |
2377 |
++ } |
2378 |
++ printk("\n"); |
2379 |
++} |
2380 |
++#endif |
2381 |
++ |
2382 |
+ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, |
2383 |
+ unsigned long address) |
2384 |
+ { |
2385 |
+@@ -280,6 +529,24 @@ good_area: |
2386 |
+ if(!(vma->vm_flags & VM_WRITE)) |
2387 |
+ goto bad_area; |
2388 |
+ } else { |
2389 |
++ |
2390 |
++#ifdef CONFIG_PAX_PAGEEXEC |
2391 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) { |
2392 |
++ up_read(&mm->mmap_sem); |
2393 |
++ switch (pax_handle_fetch_fault(regs)) { |
2394 |
++ |
2395 |
++#ifdef CONFIG_PAX_EMUPLT |
2396 |
++ case 2: |
2397 |
++ case 3: |
2398 |
++ return; |
2399 |
++#endif |
2400 |
++ |
2401 |
++ } |
2402 |
++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]); |
2403 |
++ do_group_exit(SIGKILL); |
2404 |
++ } |
2405 |
++#endif |
2406 |
++ |
2407 |
+ /* Allow reads even for write-only mappings */ |
2408 |
+ if(!(vma->vm_flags & (VM_READ | VM_EXEC))) |
2409 |
+ goto bad_area; |
2410 |
+diff -urNp linux-2.6.24.4/arch/sparc/mm/init.c linux-2.6.24.4/arch/sparc/mm/init.c |
2411 |
+--- linux-2.6.24.4/arch/sparc/mm/init.c 2008-03-24 14:49:18.000000000 -0400 |
2412 |
++++ linux-2.6.24.4/arch/sparc/mm/init.c 2008-03-26 17:56:55.000000000 -0400 |
2413 |
+@@ -336,17 +336,17 @@ void __init paging_init(void) |
2414 |
+ |
2415 |
+ /* Initialize the protection map with non-constant, MMU dependent values. */ |
2416 |
+ protection_map[0] = PAGE_NONE; |
2417 |
+- protection_map[1] = PAGE_READONLY; |
2418 |
+- protection_map[2] = PAGE_COPY; |
2419 |
+- protection_map[3] = PAGE_COPY; |
2420 |
++ protection_map[1] = PAGE_READONLY_NOEXEC; |
2421 |
++ protection_map[2] = PAGE_COPY_NOEXEC; |
2422 |
++ protection_map[3] = PAGE_COPY_NOEXEC; |
2423 |
+ protection_map[4] = PAGE_READONLY; |
2424 |
+ protection_map[5] = PAGE_READONLY; |
2425 |
+ protection_map[6] = PAGE_COPY; |
2426 |
+ protection_map[7] = PAGE_COPY; |
2427 |
+ protection_map[8] = PAGE_NONE; |
2428 |
+- protection_map[9] = PAGE_READONLY; |
2429 |
+- protection_map[10] = PAGE_SHARED; |
2430 |
+- protection_map[11] = PAGE_SHARED; |
2431 |
++ protection_map[9] = PAGE_READONLY_NOEXEC; |
2432 |
++ protection_map[10] = PAGE_SHARED_NOEXEC; |
2433 |
++ protection_map[11] = PAGE_SHARED_NOEXEC; |
2434 |
+ protection_map[12] = PAGE_READONLY; |
2435 |
+ protection_map[13] = PAGE_READONLY; |
2436 |
+ protection_map[14] = PAGE_SHARED; |
2437 |
+diff -urNp linux-2.6.24.4/arch/sparc/mm/srmmu.c linux-2.6.24.4/arch/sparc/mm/srmmu.c |
2438 |
+--- linux-2.6.24.4/arch/sparc/mm/srmmu.c 2008-03-24 14:49:18.000000000 -0400 |
2439 |
++++ linux-2.6.24.4/arch/sparc/mm/srmmu.c 2008-03-26 17:56:55.000000000 -0400 |
2440 |
+@@ -2157,6 +2157,13 @@ void __init ld_mmu_srmmu(void) |
2441 |
+ PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED); |
2442 |
+ BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY)); |
2443 |
+ BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); |
2444 |
++ |
2445 |
++#ifdef CONFIG_PAX_PAGEEXEC |
2446 |
++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC); |
2447 |
++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC)); |
2448 |
++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC)); |
2449 |
++#endif |
2450 |
++ |
2451 |
+ BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); |
2452 |
+ page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); |
2453 |
+ |
2454 |
+diff -urNp linux-2.6.24.4/arch/sparc64/kernel/Makefile linux-2.6.24.4/arch/sparc64/kernel/Makefile |
2455 |
+--- linux-2.6.24.4/arch/sparc64/kernel/Makefile 2008-03-24 14:49:18.000000000 -0400 |
2456 |
++++ linux-2.6.24.4/arch/sparc64/kernel/Makefile 2008-03-26 17:56:55.000000000 -0400 |
2457 |
+@@ -3,7 +3,7 @@ |
2458 |
+ # |
2459 |
+ |
2460 |
+ EXTRA_AFLAGS := -ansi |
2461 |
+-EXTRA_CFLAGS := -Werror |
2462 |
++#EXTRA_CFLAGS := -Werror |
2463 |
+ |
2464 |
+ extra-y := head.o init_task.o vmlinux.lds |
2465 |
+ |
2466 |
+diff -urNp linux-2.6.24.4/arch/sparc64/kernel/ptrace.c linux-2.6.24.4/arch/sparc64/kernel/ptrace.c |
2467 |
+--- linux-2.6.24.4/arch/sparc64/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400 |
2468 |
++++ linux-2.6.24.4/arch/sparc64/kernel/ptrace.c 2008-03-26 17:56:55.000000000 -0400 |
2469 |
+@@ -22,6 +22,7 @@ |
2470 |
+ #include <linux/seccomp.h> |
2471 |
+ #include <linux/audit.h> |
2472 |
+ #include <linux/signal.h> |
2473 |
++#include <linux/grsecurity.h> |
2474 |
+ |
2475 |
+ #include <asm/asi.h> |
2476 |
+ #include <asm/pgtable.h> |
2477 |
+@@ -216,6 +217,11 @@ asmlinkage void do_ptrace(struct pt_regs |
2478 |
+ goto out; |
2479 |
+ } |
2480 |
+ |
2481 |
++ if (gr_handle_ptrace(child, (long)request)) { |
2482 |
++ pt_error_return(regs, EPERM); |
2483 |
++ goto out_tsk; |
2484 |
++ } |
2485 |
++ |
2486 |
+ if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) |
2487 |
+ || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { |
2488 |
+ if (ptrace_attach(child)) { |
2489 |
+diff -urNp linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c |
2490 |
+--- linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c 2008-03-24 14:49:18.000000000 -0400 |
2491 |
++++ linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c 2008-03-26 17:56:55.000000000 -0400 |
2492 |
+@@ -123,7 +123,7 @@ unsigned long arch_get_unmapped_area(str |
2493 |
+ /* We do not accept a shared mapping if it would violate |
2494 |
+ * cache aliasing constraints. |
2495 |
+ */ |
2496 |
+- if ((flags & MAP_SHARED) && |
2497 |
++ if ((filp || (flags & MAP_SHARED)) && |
2498 |
+ ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))) |
2499 |
+ return -EINVAL; |
2500 |
+ return addr; |
2501 |
+@@ -138,6 +138,10 @@ unsigned long arch_get_unmapped_area(str |
2502 |
+ if (filp || (flags & MAP_SHARED)) |
2503 |
+ do_color_align = 1; |
2504 |
+ |
2505 |
++#ifdef CONFIG_PAX_RANDMMAP |
2506 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
2507 |
++#endif |
2508 |
++ |
2509 |
+ if (addr) { |
2510 |
+ if (do_color_align) |
2511 |
+ addr = COLOUR_ALIGN(addr, pgoff); |
2512 |
+@@ -151,9 +155,9 @@ unsigned long arch_get_unmapped_area(str |
2513 |
+ } |
2514 |
+ |
2515 |
+ if (len > mm->cached_hole_size) { |
2516 |
+- start_addr = addr = mm->free_area_cache; |
2517 |
++ start_addr = addr = mm->free_area_cache; |
2518 |
+ } else { |
2519 |
+- start_addr = addr = TASK_UNMAPPED_BASE; |
2520 |
++ start_addr = addr = mm->mmap_base; |
2521 |
+ mm->cached_hole_size = 0; |
2522 |
+ } |
2523 |
+ |
2524 |
+@@ -173,8 +177,8 @@ full_search: |
2525 |
+ vma = find_vma(mm, VA_EXCLUDE_END); |
2526 |
+ } |
2527 |
+ if (unlikely(task_size < addr)) { |
2528 |
+- if (start_addr != TASK_UNMAPPED_BASE) { |
2529 |
+- start_addr = addr = TASK_UNMAPPED_BASE; |
2530 |
++ if (start_addr != mm->mmap_base) { |
2531 |
++ start_addr = addr = mm->mmap_base; |
2532 |
+ mm->cached_hole_size = 0; |
2533 |
+ goto full_search; |
2534 |
+ } |
2535 |
+@@ -214,7 +218,7 @@ arch_get_unmapped_area_topdown(struct fi |
2536 |
+ /* We do not accept a shared mapping if it would violate |
2537 |
+ * cache aliasing constraints. |
2538 |
+ */ |
2539 |
+- if ((flags & MAP_SHARED) && |
2540 |
++ if ((filp || (flags & MAP_SHARED)) && |
2541 |
+ ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))) |
2542 |
+ return -EINVAL; |
2543 |
+ return addr; |
2544 |
+@@ -377,6 +381,12 @@ void arch_pick_mmap_layout(struct mm_str |
2545 |
+ current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY || |
2546 |
+ sysctl_legacy_va_layout) { |
2547 |
+ mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; |
2548 |
++ |
2549 |
++#ifdef CONFIG_PAX_RANDMMAP |
2550 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
2551 |
++ mm->mmap_base += mm->delta_mmap; |
2552 |
++#endif |
2553 |
++ |
2554 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
2555 |
+ mm->unmap_area = arch_unmap_area; |
2556 |
+ } else { |
2557 |
+@@ -391,6 +401,12 @@ void arch_pick_mmap_layout(struct mm_str |
2558 |
+ gap = (task_size / 6 * 5); |
2559 |
+ |
2560 |
+ mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor); |
2561 |
++ |
2562 |
++#ifdef CONFIG_PAX_RANDMMAP |
2563 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
2564 |
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; |
2565 |
++#endif |
2566 |
++ |
2567 |
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
2568 |
+ mm->unmap_area = arch_unmap_area_topdown; |
2569 |
+ } |
2570 |
+diff -urNp linux-2.6.24.4/arch/sparc64/mm/fault.c linux-2.6.24.4/arch/sparc64/mm/fault.c |
2571 |
+--- linux-2.6.24.4/arch/sparc64/mm/fault.c 2008-03-24 14:49:18.000000000 -0400 |
2572 |
++++ linux-2.6.24.4/arch/sparc64/mm/fault.c 2008-03-26 18:53:27.000000000 -0400 |
2573 |
+@@ -20,6 +20,10 @@ |
2574 |
+ #include <linux/kprobes.h> |
2575 |
+ #include <linux/kallsyms.h> |
2576 |
+ #include <linux/kdebug.h> |
2577 |
++#include <linux/slab.h> |
2578 |
++#include <linux/pagemap.h> |
2579 |
++#include <linux/compiler.h> |
2580 |
++#include <linux/binfmts.h> |
2581 |
+ |
2582 |
+ #include <asm/page.h> |
2583 |
+ #include <asm/pgtable.h> |
2584 |
+@@ -262,6 +266,368 @@ cannot_handle: |
2585 |
+ unhandled_fault (address, current, regs); |
2586 |
+ } |
2587 |
+ |
2588 |
++#ifdef CONFIG_PAX_PAGEEXEC |
2589 |
++#ifdef CONFIG_PAX_EMUPLT |
2590 |
++static void pax_emuplt_close(struct vm_area_struct *vma) |
2591 |
++{ |
2592 |
++ vma->vm_mm->call_dl_resolve = 0UL; |
2593 |
++} |
2594 |
++ |
2595 |
++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type) |
2596 |
++{ |
2597 |
++ struct page *page; |
2598 |
++ unsigned int *kaddr; |
2599 |
++ |
2600 |
++ page = alloc_page(GFP_HIGHUSER); |
2601 |
++ if (!page) |
2602 |
++ return NOPAGE_OOM; |
2603 |
++ |
2604 |
++ kaddr = kmap(page); |
2605 |
++ memset(kaddr, 0, PAGE_SIZE); |
2606 |
++ kaddr[0] = 0x9DE3BFA8U; /* save */ |
2607 |
++ flush_dcache_page(page); |
2608 |
++ kunmap(page); |
2609 |
++ if (type) |
2610 |
++ *type = VM_FAULT_MAJOR; |
2611 |
++ return page; |
2612 |
++} |
2613 |
++ |
2614 |
++static struct vm_operations_struct pax_vm_ops = { |
2615 |
++ .close = pax_emuplt_close, |
2616 |
++ .nopage = pax_emuplt_nopage, |
2617 |
++}; |
2618 |
++ |
2619 |
++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) |
2620 |
++{ |
2621 |
++ int ret; |
2622 |
++ |
2623 |
++ vma->vm_mm = current->mm; |
2624 |
++ vma->vm_start = addr; |
2625 |
++ vma->vm_end = addr + PAGE_SIZE; |
2626 |
++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; |
2627 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
2628 |
++ vma->vm_ops = &pax_vm_ops; |
2629 |
++ |
2630 |
++ ret = insert_vm_struct(current->mm, vma); |
2631 |
++ if (ret) |
2632 |
++ return ret; |
2633 |
++ |
2634 |
++ ++current->mm->total_vm; |
2635 |
++ return 0; |
2636 |
++} |
2637 |
++#endif |
2638 |
++ |
2639 |
++/* |
2640 |
++ * PaX: decide what to do with offenders (regs->tpc = fault address) |
2641 |
++ * |
2642 |
++ * returns 1 when task should be killed |
2643 |
++ * 2 when patched PLT trampoline was detected |
2644 |
++ * 3 when unpatched PLT trampoline was detected |
2645 |
++ */ |
2646 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
2647 |
++{ |
2648 |
++ |
2649 |
++#ifdef CONFIG_PAX_EMUPLT |
2650 |
++ int err; |
2651 |
++ |
2652 |
++ do { /* PaX: patched PLT emulation #1 */ |
2653 |
++ unsigned int sethi1, sethi2, jmpl; |
2654 |
++ |
2655 |
++ err = get_user(sethi1, (unsigned int *)regs->tpc); |
2656 |
++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4)); |
2657 |
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8)); |
2658 |
++ |
2659 |
++ if (err) |
2660 |
++ break; |
2661 |
++ |
2662 |
++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && |
2663 |
++ (sethi2 & 0xFFC00000U) == 0x03000000U && |
2664 |
++ (jmpl & 0xFFFFE000U) == 0x81C06000U) |
2665 |
++ { |
2666 |
++ unsigned long addr; |
2667 |
++ |
2668 |
++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10; |
2669 |
++ addr = regs->u_regs[UREG_G1]; |
2670 |
++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); |
2671 |
++ regs->tpc = addr; |
2672 |
++ regs->tnpc = addr+4; |
2673 |
++ return 2; |
2674 |
++ } |
2675 |
++ } while (0); |
2676 |
++ |
2677 |
++ { /* PaX: patched PLT emulation #2 */ |
2678 |
++ unsigned int ba; |
2679 |
++ |
2680 |
++ err = get_user(ba, (unsigned int *)regs->tpc); |
2681 |
++ |
2682 |
++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) { |
2683 |
++ unsigned long addr; |
2684 |
++ |
2685 |
++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2); |
2686 |
++ regs->tpc = addr; |
2687 |
++ regs->tnpc = addr+4; |
2688 |
++ return 2; |
2689 |
++ } |
2690 |
++ } |
2691 |
++ |
2692 |
++ do { /* PaX: patched PLT emulation #3 */ |
2693 |
++ unsigned int sethi, jmpl, nop; |
2694 |
++ |
2695 |
++ err = get_user(sethi, (unsigned int *)regs->tpc); |
2696 |
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4)); |
2697 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+8)); |
2698 |
++ |
2699 |
++ if (err) |
2700 |
++ break; |
2701 |
++ |
2702 |
++ if ((sethi & 0xFFC00000U) == 0x03000000U && |
2703 |
++ (jmpl & 0xFFFFE000U) == 0x81C06000U && |
2704 |
++ nop == 0x01000000U) |
2705 |
++ { |
2706 |
++ unsigned long addr; |
2707 |
++ |
2708 |
++ addr = (sethi & 0x003FFFFFU) << 10; |
2709 |
++ regs->u_regs[UREG_G1] = addr; |
2710 |
++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); |
2711 |
++ regs->tpc = addr; |
2712 |
++ regs->tnpc = addr+4; |
2713 |
++ return 2; |
2714 |
++ } |
2715 |
++ } while (0); |
2716 |
++ |
2717 |
++ do { /* PaX: patched PLT emulation #4 */ |
2718 |
++ unsigned int mov1, call, mov2; |
2719 |
++ |
2720 |
++ err = get_user(mov1, (unsigned int *)regs->tpc); |
2721 |
++ err |= get_user(call, (unsigned int *)(regs->tpc+4)); |
2722 |
++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8)); |
2723 |
++ |
2724 |
++ if (err) |
2725 |
++ break; |
2726 |
++ |
2727 |
++ if (mov1 == 0x8210000FU && |
2728 |
++ (call & 0xC0000000U) == 0x40000000U && |
2729 |
++ mov2 == 0x9E100001U) |
2730 |
++ { |
2731 |
++ unsigned long addr; |
2732 |
++ |
2733 |
++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC]; |
2734 |
++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2); |
2735 |
++ regs->tpc = addr; |
2736 |
++ regs->tnpc = addr+4; |
2737 |
++ return 2; |
2738 |
++ } |
2739 |
++ } while (0); |
2740 |
++ |
2741 |
++ do { /* PaX: patched PLT emulation #5 */ |
2742 |
++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop; |
2743 |
++ |
2744 |
++ err = get_user(sethi1, (unsigned int *)regs->tpc); |
2745 |
++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4)); |
2746 |
++ err |= get_user(or1, (unsigned int *)(regs->tpc+8)); |
2747 |
++ err |= get_user(or2, (unsigned int *)(regs->tpc+12)); |
2748 |
++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16)); |
2749 |
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20)); |
2750 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+24)); |
2751 |
++ |
2752 |
++ if (err) |
2753 |
++ break; |
2754 |
++ |
2755 |
++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && |
2756 |
++ (sethi2 & 0xFFC00000U) == 0x0B000000U && |
2757 |
++ (or1 & 0xFFFFE000U) == 0x82106000U && |
2758 |
++ (or2 & 0xFFFFE000U) == 0x8A116000U && |
2759 |
++ sllx == 0x83287020 && |
2760 |
++ jmpl == 0x81C04005U && |
2761 |
++ nop == 0x01000000U) |
2762 |
++ { |
2763 |
++ unsigned long addr; |
2764 |
++ |
2765 |
++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU); |
2766 |
++ regs->u_regs[UREG_G1] <<= 32; |
2767 |
++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU); |
2768 |
++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5]; |
2769 |
++ regs->tpc = addr; |
2770 |
++ regs->tnpc = addr+4; |
2771 |
++ return 2; |
2772 |
++ } |
2773 |
++ } while (0); |
2774 |
++ |
2775 |
++ do { /* PaX: patched PLT emulation #6 */ |
2776 |
++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop; |
2777 |
++ |
2778 |
++ err = get_user(sethi1, (unsigned int *)regs->tpc); |
2779 |
++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4)); |
2780 |
++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8)); |
2781 |
++ err |= get_user(or, (unsigned int *)(regs->tpc+12)); |
2782 |
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16)); |
2783 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+20)); |
2784 |
++ |
2785 |
++ if (err) |
2786 |
++ break; |
2787 |
++ |
2788 |
++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && |
2789 |
++ (sethi2 & 0xFFC00000U) == 0x0B000000U && |
2790 |
++ sllx == 0x83287020 && |
2791 |
++ (or & 0xFFFFE000U) == 0x8A116000U && |
2792 |
++ jmpl == 0x81C04005U && |
2793 |
++ nop == 0x01000000U) |
2794 |
++ { |
2795 |
++ unsigned long addr; |
2796 |
++ |
2797 |
++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10; |
2798 |
++ regs->u_regs[UREG_G1] <<= 32; |
2799 |
++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU); |
2800 |
++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5]; |
2801 |
++ regs->tpc = addr; |
2802 |
++ regs->tnpc = addr+4; |
2803 |
++ return 2; |
2804 |
++ } |
2805 |
++ } while (0); |
2806 |
++ |
2807 |
++ do { /* PaX: patched PLT emulation #7 */ |
2808 |
++ unsigned int sethi, ba, nop; |
2809 |
++ |
2810 |
++ err = get_user(sethi, (unsigned int *)regs->tpc); |
2811 |
++ err |= get_user(ba, (unsigned int *)(regs->tpc+4)); |
2812 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+8)); |
2813 |
++ |
2814 |
++ if (err) |
2815 |
++ break; |
2816 |
++ |
2817 |
++ if ((sethi & 0xFFC00000U) == 0x03000000U && |
2818 |
++ (ba & 0xFFF00000U) == 0x30600000U && |
2819 |
++ nop == 0x01000000U) |
2820 |
++ { |
2821 |
++ unsigned long addr; |
2822 |
++ |
2823 |
++ addr = (sethi & 0x003FFFFFU) << 10; |
2824 |
++ regs->u_regs[UREG_G1] = addr; |
2825 |
++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2); |
2826 |
++ regs->tpc = addr; |
2827 |
++ regs->tnpc = addr+4; |
2828 |
++ return 2; |
2829 |
++ } |
2830 |
++ } while (0); |
2831 |
++ |
2832 |
++ do { /* PaX: unpatched PLT emulation step 1 */ |
2833 |
++ unsigned int sethi, ba, nop; |
2834 |
++ |
2835 |
++ err = get_user(sethi, (unsigned int *)regs->tpc); |
2836 |
++ err |= get_user(ba, (unsigned int *)(regs->tpc+4)); |
2837 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+8)); |
2838 |
++ |
2839 |
++ if (err) |
2840 |
++ break; |
2841 |
++ |
2842 |
++ if ((sethi & 0xFFC00000U) == 0x03000000U && |
2843 |
++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) && |
2844 |
++ nop == 0x01000000U) |
2845 |
++ { |
2846 |
++ unsigned long addr; |
2847 |
++ unsigned int save, call; |
2848 |
++ |
2849 |
++ if ((ba & 0xFFC00000U) == 0x30800000U) |
2850 |
++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2); |
2851 |
++ else |
2852 |
++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2); |
2853 |
++ |
2854 |
++ err = get_user(save, (unsigned int *)addr); |
2855 |
++ err |= get_user(call, (unsigned int *)(addr+4)); |
2856 |
++ err |= get_user(nop, (unsigned int *)(addr+8)); |
2857 |
++ if (err) |
2858 |
++ break; |
2859 |
++ |
2860 |
++ if (save == 0x9DE3BFA8U && |
2861 |
++ (call & 0xC0000000U) == 0x40000000U && |
2862 |
++ nop == 0x01000000U) |
2863 |
++ { |
2864 |
++ struct vm_area_struct *vma; |
2865 |
++ unsigned long call_dl_resolve; |
2866 |
++ |
2867 |
++ down_read(¤t->mm->mmap_sem); |
2868 |
++ call_dl_resolve = current->mm->call_dl_resolve; |
2869 |
++ up_read(¤t->mm->mmap_sem); |
2870 |
++ if (likely(call_dl_resolve)) |
2871 |
++ goto emulate; |
2872 |
++ |
2873 |
++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
2874 |
++ |
2875 |
++ down_write(¤t->mm->mmap_sem); |
2876 |
++ if (current->mm->call_dl_resolve) { |
2877 |
++ call_dl_resolve = current->mm->call_dl_resolve; |
2878 |
++ up_write(¤t->mm->mmap_sem); |
2879 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
2880 |
++ goto emulate; |
2881 |
++ } |
2882 |
++ |
2883 |
++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
2884 |
++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) { |
2885 |
++ up_write(¤t->mm->mmap_sem); |
2886 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
2887 |
++ return 1; |
2888 |
++ } |
2889 |
++ |
2890 |
++ if (pax_insert_vma(vma, call_dl_resolve)) { |
2891 |
++ up_write(¤t->mm->mmap_sem); |
2892 |
++ kmem_cache_free(vm_area_cachep, vma); |
2893 |
++ return 1; |
2894 |
++ } |
2895 |
++ |
2896 |
++ current->mm->call_dl_resolve = call_dl_resolve; |
2897 |
++ up_write(¤t->mm->mmap_sem); |
2898 |
++ |
2899 |
++emulate: |
2900 |
++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; |
2901 |
++ regs->tpc = call_dl_resolve; |
2902 |
++ regs->tnpc = addr+4; |
2903 |
++ return 3; |
2904 |
++ } |
2905 |
++ } |
2906 |
++ } while (0); |
2907 |
++ |
2908 |
++ do { /* PaX: unpatched PLT emulation step 2 */ |
2909 |
++ unsigned int save, call, nop; |
2910 |
++ |
2911 |
++ err = get_user(save, (unsigned int *)(regs->tpc-4)); |
2912 |
++ err |= get_user(call, (unsigned int *)regs->tpc); |
2913 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+4)); |
2914 |
++ if (err) |
2915 |
++ break; |
2916 |
++ |
2917 |
++ if (save == 0x9DE3BFA8U && |
2918 |
++ (call & 0xC0000000U) == 0x40000000U && |
2919 |
++ nop == 0x01000000U) |
2920 |
++ { |
2921 |
++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2); |
2922 |
++ |
2923 |
++ regs->u_regs[UREG_RETPC] = regs->tpc; |
2924 |
++ regs->tpc = dl_resolve; |
2925 |
++ regs->tnpc = dl_resolve+4; |
2926 |
++ return 3; |
2927 |
++ } |
2928 |
++ } while (0); |
2929 |
++#endif |
2930 |
++ |
2931 |
++ return 1; |
2932 |
++} |
2933 |
++ |
2934 |
++void pax_report_insns(void *pc, void *sp) |
2935 |
++{ |
2936 |
++ unsigned long i; |
2937 |
++ |
2938 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
2939 |
++ for (i = 0; i < 5; i++) { |
2940 |
++ unsigned int c; |
2941 |
++ if (get_user(c, (unsigned int *)pc+i)) |
2942 |
++ printk("???????? "); |
2943 |
++ else |
2944 |
++ printk("%08x ", c); |
2945 |
++ } |
2946 |
++ printk("\n"); |
2947 |
++} |
2948 |
++#endif |
2949 |
++ |
2950 |
+ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) |
2951 |
+ { |
2952 |
+ struct mm_struct *mm = current->mm; |
2953 |
+@@ -303,8 +669,10 @@ asmlinkage void __kprobes do_sparc64_fau |
2954 |
+ goto intr_or_no_mm; |
2955 |
+ |
2956 |
+ if (test_thread_flag(TIF_32BIT)) { |
2957 |
+- if (!(regs->tstate & TSTATE_PRIV)) |
2958 |
++ if (!(regs->tstate & TSTATE_PRIV)) { |
2959 |
+ regs->tpc &= 0xffffffff; |
2960 |
++ regs->tnpc &= 0xffffffff; |
2961 |
++ } |
2962 |
+ address &= 0xffffffff; |
2963 |
+ } |
2964 |
+ |
2965 |
+@@ -321,6 +689,29 @@ asmlinkage void __kprobes do_sparc64_fau |
2966 |
+ if (!vma) |
2967 |
+ goto bad_area; |
2968 |
+ |
2969 |
++#ifdef CONFIG_PAX_PAGEEXEC |
2970 |
++ /* PaX: detect ITLB misses on non-exec pages */ |
2971 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address && |
2972 |
++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB)) |
2973 |
++ { |
2974 |
++ if (address != regs->tpc) |
2975 |
++ goto good_area; |
2976 |
++ |
2977 |
++ up_read(&mm->mmap_sem); |
2978 |
++ switch (pax_handle_fetch_fault(regs)) { |
2979 |
++ |
2980 |
++#ifdef CONFIG_PAX_EMUPLT |
2981 |
++ case 2: |
2982 |
++ case 3: |
2983 |
++ return; |
2984 |
++#endif |
2985 |
++ |
2986 |
++ } |
2987 |
++ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS)); |
2988 |
++ do_group_exit(SIGKILL); |
2989 |
++ } |
2990 |
++#endif |
2991 |
++ |
2992 |
+ /* Pure DTLB misses do not tell us whether the fault causing |
2993 |
+ * load/store/atomic was a write or not, it only says that there |
2994 |
+ * was no match. So in such a case we (carefully) read the |
2995 |
+diff -urNp linux-2.6.24.4/arch/sparc64/mm/Makefile linux-2.6.24.4/arch/sparc64/mm/Makefile |
2996 |
+--- linux-2.6.24.4/arch/sparc64/mm/Makefile 2008-03-24 14:49:18.000000000 -0400 |
2997 |
++++ linux-2.6.24.4/arch/sparc64/mm/Makefile 2008-03-26 17:56:55.000000000 -0400 |
2998 |
+@@ -3,7 +3,7 @@ |
2999 |
+ # |
3000 |
+ |
3001 |
+ EXTRA_AFLAGS := -ansi |
3002 |
+-EXTRA_CFLAGS := -Werror |
3003 |
++#EXTRA_CFLAGS := -Werror |
3004 |
+ |
3005 |
+ obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o |
3006 |
+ |
3007 |
+diff -urNp linux-2.6.24.4/arch/v850/kernel/module.c linux-2.6.24.4/arch/v850/kernel/module.c |
3008 |
+--- linux-2.6.24.4/arch/v850/kernel/module.c 2008-03-24 14:49:18.000000000 -0400 |
3009 |
++++ linux-2.6.24.4/arch/v850/kernel/module.c 2008-03-26 17:56:55.000000000 -0400 |
3010 |
+@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat |
3011 |
+ tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */ |
3012 |
+ |
3013 |
+ /* Init, or core PLT? */ |
3014 |
+- if (location >= mod->module_core |
3015 |
+- && location < mod->module_core + mod->core_size) |
3016 |
++ if (location >= mod->module_core_rx |
3017 |
++ && location < mod->module_core_rx + mod->core_size_rx) |
3018 |
+ entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr; |
3019 |
+ else |
3020 |
+ entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr; |
3021 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/bitops.h linux-2.6.24.4/arch/x86/boot/bitops.h |
3022 |
+--- linux-2.6.24.4/arch/x86/boot/bitops.h 2008-03-24 14:49:18.000000000 -0400 |
3023 |
++++ linux-2.6.24.4/arch/x86/boot/bitops.h 2008-03-26 17:56:55.000000000 -0400 |
3024 |
+@@ -28,7 +28,7 @@ static inline int variable_test_bit(int |
3025 |
+ u8 v; |
3026 |
+ const u32 *p = (const u32 *)addr; |
3027 |
+ |
3028 |
+- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr)); |
3029 |
++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr)); |
3030 |
+ return v; |
3031 |
+ } |
3032 |
+ |
3033 |
+@@ -39,7 +39,7 @@ static inline int variable_test_bit(int |
3034 |
+ |
3035 |
+ static inline void set_bit(int nr, void *addr) |
3036 |
+ { |
3037 |
+- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr)); |
3038 |
++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr)); |
3039 |
+ } |
3040 |
+ |
3041 |
+ #endif /* BOOT_BITOPS_H */ |
3042 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/boot.h linux-2.6.24.4/arch/x86/boot/boot.h |
3043 |
+--- linux-2.6.24.4/arch/x86/boot/boot.h 2008-03-24 14:49:18.000000000 -0400 |
3044 |
++++ linux-2.6.24.4/arch/x86/boot/boot.h 2008-03-26 17:56:55.000000000 -0400 |
3045 |
+@@ -78,7 +78,7 @@ static inline void io_delay(void) |
3046 |
+ static inline u16 ds(void) |
3047 |
+ { |
3048 |
+ u16 seg; |
3049 |
+- asm("movw %%ds,%0" : "=rm" (seg)); |
3050 |
++ asm volatile("movw %%ds,%0" : "=rm" (seg)); |
3051 |
+ return seg; |
3052 |
+ } |
3053 |
+ |
3054 |
+@@ -174,7 +174,7 @@ static inline void wrgs32(u32 v, addr_t |
3055 |
+ static inline int memcmp(const void *s1, const void *s2, size_t len) |
3056 |
+ { |
3057 |
+ u8 diff; |
3058 |
+- asm("repe; cmpsb; setnz %0" |
3059 |
++ asm volatile("repe; cmpsb; setnz %0" |
3060 |
+ : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); |
3061 |
+ return diff; |
3062 |
+ } |
3063 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/compressed/head_32.S linux-2.6.24.4/arch/x86/boot/compressed/head_32.S |
3064 |
+--- linux-2.6.24.4/arch/x86/boot/compressed/head_32.S 2008-03-24 14:49:18.000000000 -0400 |
3065 |
++++ linux-2.6.24.4/arch/x86/boot/compressed/head_32.S 2008-03-26 17:56:55.000000000 -0400 |
3066 |
+@@ -70,7 +70,7 @@ startup_32: |
3067 |
+ addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx |
3068 |
+ andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx |
3069 |
+ #else |
3070 |
+- movl $LOAD_PHYSICAL_ADDR, %ebx |
3071 |
++ movl $____LOAD_PHYSICAL_ADDR, %ebx |
3072 |
+ #endif |
3073 |
+ |
3074 |
+ /* Replace the compressed data size with the uncompressed size */ |
3075 |
+@@ -105,7 +105,7 @@ startup_32: |
3076 |
+ addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp |
3077 |
+ andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp |
3078 |
+ #else |
3079 |
+- movl $LOAD_PHYSICAL_ADDR, %ebp |
3080 |
++ movl $____LOAD_PHYSICAL_ADDR, %ebp |
3081 |
+ #endif |
3082 |
+ |
3083 |
+ /* |
3084 |
+@@ -159,16 +159,15 @@ relocated: |
3085 |
+ * and where it was actually loaded. |
3086 |
+ */ |
3087 |
+ movl %ebp, %ebx |
3088 |
+- subl $LOAD_PHYSICAL_ADDR, %ebx |
3089 |
++ subl $____LOAD_PHYSICAL_ADDR, %ebx |
3090 |
+ jz 2f /* Nothing to be done if loaded at compiled addr. */ |
3091 |
+ /* |
3092 |
+ * Process relocations. |
3093 |
+ */ |
3094 |
+ |
3095 |
+ 1: subl $4, %edi |
3096 |
+- movl 0(%edi), %ecx |
3097 |
+- testl %ecx, %ecx |
3098 |
+- jz 2f |
3099 |
++ movl (%edi), %ecx |
3100 |
++ jecxz 2f |
3101 |
+ addl %ebx, -__PAGE_OFFSET(%ebx, %ecx) |
3102 |
+ jmp 1b |
3103 |
+ 2: |
3104 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/compressed/misc_32.c linux-2.6.24.4/arch/x86/boot/compressed/misc_32.c |
3105 |
+--- linux-2.6.24.4/arch/x86/boot/compressed/misc_32.c 2008-03-24 14:49:18.000000000 -0400 |
3106 |
++++ linux-2.6.24.4/arch/x86/boot/compressed/misc_32.c 2008-03-26 17:56:55.000000000 -0400 |
3107 |
+@@ -113,7 +113,8 @@ typedef unsigned char uch; |
3108 |
+ typedef unsigned short ush; |
3109 |
+ typedef unsigned long ulg; |
3110 |
+ |
3111 |
+-#define WSIZE 0x80000000 /* Window size must be at least 32k, |
3112 |
++#define WSIZE 0x80000000 |
3113 |
++ /* Window size must be at least 32k, |
3114 |
+ * and a power of two |
3115 |
+ * We don't actually have a window just |
3116 |
+ * a huge output buffer so I report |
3117 |
+@@ -370,7 +371,7 @@ asmlinkage void decompress_kernel(void * |
3118 |
+ if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff)) |
3119 |
+ error("Destination address too large"); |
3120 |
+ #ifndef CONFIG_RELOCATABLE |
3121 |
+- if ((u32)output != LOAD_PHYSICAL_ADDR) |
3122 |
++ if ((u32)output != ____LOAD_PHYSICAL_ADDR) |
3123 |
+ error("Wrong destination address"); |
3124 |
+ #endif |
3125 |
+ |
3126 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/compressed/relocs.c linux-2.6.24.4/arch/x86/boot/compressed/relocs.c |
3127 |
+--- linux-2.6.24.4/arch/x86/boot/compressed/relocs.c 2008-03-24 14:49:18.000000000 -0400 |
3128 |
++++ linux-2.6.24.4/arch/x86/boot/compressed/relocs.c 2008-03-26 17:56:55.000000000 -0400 |
3129 |
+@@ -10,9 +10,13 @@ |
3130 |
+ #define USE_BSD |
3131 |
+ #include <endian.h> |
3132 |
+ |
3133 |
++#include "../../../../include/linux/autoconf.h" |
3134 |
++ |
3135 |
++#define MAX_PHDRS 100 |
3136 |
+ #define MAX_SHDRS 100 |
3137 |
+ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
3138 |
+ static Elf32_Ehdr ehdr; |
3139 |
++static Elf32_Phdr phdr[MAX_PHDRS]; |
3140 |
+ static Elf32_Shdr shdr[MAX_SHDRS]; |
3141 |
+ static Elf32_Sym *symtab[MAX_SHDRS]; |
3142 |
+ static Elf32_Rel *reltab[MAX_SHDRS]; |
3143 |
+@@ -244,6 +248,34 @@ static void read_ehdr(FILE *fp) |
3144 |
+ } |
3145 |
+ } |
3146 |
+ |
3147 |
++static void read_phdrs(FILE *fp) |
3148 |
++{ |
3149 |
++ int i; |
3150 |
++ if (ehdr.e_phnum > MAX_PHDRS) { |
3151 |
++ die("%d program headers supported: %d\n", |
3152 |
++ ehdr.e_phnum, MAX_PHDRS); |
3153 |
++ } |
3154 |
++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) { |
3155 |
++ die("Seek to %d failed: %s\n", |
3156 |
++ ehdr.e_phoff, strerror(errno)); |
3157 |
++ } |
3158 |
++ if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) { |
3159 |
++ die("Cannot read ELF program headers: %s\n", |
3160 |
++ strerror(errno)); |
3161 |
++ } |
3162 |
++ for(i = 0; i < ehdr.e_phnum; i++) { |
3163 |
++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type); |
3164 |
++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset); |
3165 |
++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr); |
3166 |
++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr); |
3167 |
++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz); |
3168 |
++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz); |
3169 |
++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags); |
3170 |
++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align); |
3171 |
++ } |
3172 |
++ |
3173 |
++} |
3174 |
++ |
3175 |
+ static void read_shdrs(FILE *fp) |
3176 |
+ { |
3177 |
+ int i; |
3178 |
+@@ -330,6 +362,8 @@ static void read_symtabs(FILE *fp) |
3179 |
+ static void read_relocs(FILE *fp) |
3180 |
+ { |
3181 |
+ int i,j; |
3182 |
++ uint32_t base; |
3183 |
++ |
3184 |
+ for(i = 0; i < ehdr.e_shnum; i++) { |
3185 |
+ if (shdr[i].sh_type != SHT_REL) { |
3186 |
+ continue; |
3187 |
+@@ -347,8 +381,17 @@ static void read_relocs(FILE *fp) |
3188 |
+ die("Cannot read symbol table: %s\n", |
3189 |
+ strerror(errno)); |
3190 |
+ } |
3191 |
++ base = 0; |
3192 |
++ for (j = 0; j < ehdr.e_phnum; j++) { |
3193 |
++ if (phdr[j].p_type != PT_LOAD ) |
3194 |
++ continue; |
3195 |
++ 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) |
3196 |
++ continue; |
3197 |
++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr; |
3198 |
++ break; |
3199 |
++ } |
3200 |
+ for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { |
3201 |
+- reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset); |
3202 |
++ reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base; |
3203 |
+ reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info); |
3204 |
+ } |
3205 |
+ } |
3206 |
+@@ -485,6 +528,27 @@ static void walk_relocs(void (*visit)(El |
3207 |
+ if (sym->st_shndx == SHN_ABS) { |
3208 |
+ continue; |
3209 |
+ } |
3210 |
++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */ |
3211 |
++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10)) { |
3212 |
++ continue; |
3213 |
++ } |
3214 |
++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32) |
3215 |
++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */ |
3216 |
++ if (!strcmp(sec_name(sym->st_shndx), ".init.text")) { |
3217 |
++ continue; |
3218 |
++ } |
3219 |
++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text")) { |
3220 |
++ continue; |
3221 |
++ } |
3222 |
++ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) { |
3223 |
++ if (strcmp(sym_name(sym_strtab, sym), "__init_end") && |
3224 |
++ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET")) |
3225 |
++ continue; |
3226 |
++ } |
3227 |
++ if (!strcmp(sec_name(sym->st_shndx), ".text")) { |
3228 |
++ continue; |
3229 |
++ } |
3230 |
++#endif |
3231 |
+ if (r_type == R_386_PC32) { |
3232 |
+ /* PC relative relocations don't need to be adjusted */ |
3233 |
+ } |
3234 |
+@@ -612,6 +676,7 @@ int main(int argc, char **argv) |
3235 |
+ fname, strerror(errno)); |
3236 |
+ } |
3237 |
+ read_ehdr(fp); |
3238 |
++ read_phdrs(fp); |
3239 |
+ read_shdrs(fp); |
3240 |
+ read_strtabs(fp); |
3241 |
+ read_symtabs(fp); |
3242 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/cpucheck.c linux-2.6.24.4/arch/x86/boot/cpucheck.c |
3243 |
+--- linux-2.6.24.4/arch/x86/boot/cpucheck.c 2008-03-24 14:49:18.000000000 -0400 |
3244 |
++++ linux-2.6.24.4/arch/x86/boot/cpucheck.c 2008-03-26 17:56:55.000000000 -0400 |
3245 |
+@@ -84,7 +84,7 @@ static int has_fpu(void) |
3246 |
+ u16 fcw = -1, fsw = -1; |
3247 |
+ u32 cr0; |
3248 |
+ |
3249 |
+- asm("movl %%cr0,%0" : "=r" (cr0)); |
3250 |
++ asm volatile("movl %%cr0,%0" : "=r" (cr0)); |
3251 |
+ if (cr0 & (X86_CR0_EM|X86_CR0_TS)) { |
3252 |
+ cr0 &= ~(X86_CR0_EM|X86_CR0_TS); |
3253 |
+ asm volatile("movl %0,%%cr0" : : "r" (cr0)); |
3254 |
+@@ -100,7 +100,7 @@ static int has_eflag(u32 mask) |
3255 |
+ { |
3256 |
+ u32 f0, f1; |
3257 |
+ |
3258 |
+- asm("pushfl ; " |
3259 |
++ asm volatile("pushfl ; " |
3260 |
+ "pushfl ; " |
3261 |
+ "popl %0 ; " |
3262 |
+ "movl %0,%1 ; " |
3263 |
+@@ -125,7 +125,7 @@ static void get_flags(void) |
3264 |
+ set_bit(X86_FEATURE_FPU, cpu.flags); |
3265 |
+ |
3266 |
+ if (has_eflag(X86_EFLAGS_ID)) { |
3267 |
+- asm("cpuid" |
3268 |
++ asm volatile("cpuid" |
3269 |
+ : "=a" (max_intel_level), |
3270 |
+ "=b" (cpu_vendor[0]), |
3271 |
+ "=d" (cpu_vendor[1]), |
3272 |
+@@ -134,7 +134,7 @@ static void get_flags(void) |
3273 |
+ |
3274 |
+ if (max_intel_level >= 0x00000001 && |
3275 |
+ max_intel_level <= 0x0000ffff) { |
3276 |
+- asm("cpuid" |
3277 |
++ asm volatile("cpuid" |
3278 |
+ : "=a" (tfms), |
3279 |
+ "=c" (cpu.flags[4]), |
3280 |
+ "=d" (cpu.flags[0]) |
3281 |
+@@ -146,7 +146,7 @@ static void get_flags(void) |
3282 |
+ cpu.model += ((tfms >> 16) & 0xf) << 4; |
3283 |
+ } |
3284 |
+ |
3285 |
+- asm("cpuid" |
3286 |
++ asm volatile("cpuid" |
3287 |
+ : "=a" (max_amd_level) |
3288 |
+ : "a" (0x80000000) |
3289 |
+ : "ebx", "ecx", "edx"); |
3290 |
+@@ -154,7 +154,7 @@ static void get_flags(void) |
3291 |
+ if (max_amd_level >= 0x80000001 && |
3292 |
+ max_amd_level <= 0x8000ffff) { |
3293 |
+ u32 eax = 0x80000001; |
3294 |
+- asm("cpuid" |
3295 |
++ asm volatile("cpuid" |
3296 |
+ : "+a" (eax), |
3297 |
+ "=c" (cpu.flags[6]), |
3298 |
+ "=d" (cpu.flags[1]) |
3299 |
+@@ -213,9 +213,9 @@ int check_cpu(int *cpu_level_ptr, int *r |
3300 |
+ u32 ecx = MSR_K7_HWCR; |
3301 |
+ u32 eax, edx; |
3302 |
+ |
3303 |
+- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
3304 |
++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
3305 |
+ eax &= ~(1 << 15); |
3306 |
+- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
3307 |
++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
3308 |
+ |
3309 |
+ get_flags(); /* Make sure it really did something */ |
3310 |
+ err = check_flags(); |
3311 |
+@@ -228,9 +228,9 @@ int check_cpu(int *cpu_level_ptr, int *r |
3312 |
+ u32 ecx = MSR_VIA_FCR; |
3313 |
+ u32 eax, edx; |
3314 |
+ |
3315 |
+- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
3316 |
++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
3317 |
+ eax |= (1<<1)|(1<<7); |
3318 |
+- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
3319 |
++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
3320 |
+ |
3321 |
+ set_bit(X86_FEATURE_CX8, cpu.flags); |
3322 |
+ err = check_flags(); |
3323 |
+@@ -241,12 +241,12 @@ int check_cpu(int *cpu_level_ptr, int *r |
3324 |
+ u32 eax, edx; |
3325 |
+ u32 level = 1; |
3326 |
+ |
3327 |
+- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
3328 |
+- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx)); |
3329 |
+- asm("cpuid" |
3330 |
++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
3331 |
++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx)); |
3332 |
++ asm volatile("cpuid" |
3333 |
+ : "+a" (level), "=d" (cpu.flags[0]) |
3334 |
+ : : "ecx", "ebx"); |
3335 |
+- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
3336 |
++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
3337 |
+ |
3338 |
+ err = check_flags(); |
3339 |
+ } |
3340 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/edd.c linux-2.6.24.4/arch/x86/boot/edd.c |
3341 |
+--- linux-2.6.24.4/arch/x86/boot/edd.c 2008-03-24 14:49:18.000000000 -0400 |
3342 |
++++ linux-2.6.24.4/arch/x86/boot/edd.c 2008-03-26 17:56:55.000000000 -0400 |
3343 |
+@@ -78,7 +78,7 @@ static int get_edd_info(u8 devno, struct |
3344 |
+ ax = 0x4100; |
3345 |
+ bx = EDDMAGIC1; |
3346 |
+ dx = devno; |
3347 |
+- asm("pushfl; stc; int $0x13; setc %%al; popfl" |
3348 |
++ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl" |
3349 |
+ : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx) |
3350 |
+ : : "esi", "edi"); |
3351 |
+ |
3352 |
+@@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct |
3353 |
+ ei->params.length = sizeof(ei->params); |
3354 |
+ ax = 0x4800; |
3355 |
+ dx = devno; |
3356 |
+- asm("pushfl; int $0x13; popfl" |
3357 |
++ asm volatile("pushfl; int $0x13; popfl" |
3358 |
+ : "+a" (ax), "+d" (dx), "=m" (ei->params) |
3359 |
+ : "S" (&ei->params) |
3360 |
+ : "ebx", "ecx", "edi"); |
3361 |
+@@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct |
3362 |
+ ax = 0x0800; |
3363 |
+ dx = devno; |
3364 |
+ di = 0; |
3365 |
+- asm("pushw %%es; " |
3366 |
++ asm volatile("pushw %%es; " |
3367 |
+ "movw %%di,%%es; " |
3368 |
+ "pushfl; stc; int $0x13; setc %%al; popfl; " |
3369 |
+ "popw %%es" |
3370 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/main.c linux-2.6.24.4/arch/x86/boot/main.c |
3371 |
+--- linux-2.6.24.4/arch/x86/boot/main.c 2008-03-24 14:49:18.000000000 -0400 |
3372 |
++++ linux-2.6.24.4/arch/x86/boot/main.c 2008-03-26 17:56:55.000000000 -0400 |
3373 |
+@@ -75,7 +75,7 @@ static void keyboard_set_repeat(void) |
3374 |
+ */ |
3375 |
+ static void query_ist(void) |
3376 |
+ { |
3377 |
+- asm("int $0x15" |
3378 |
++ asm volatile("int $0x15" |
3379 |
+ : "=a" (boot_params.ist_info.signature), |
3380 |
+ "=b" (boot_params.ist_info.command), |
3381 |
+ "=c" (boot_params.ist_info.event), |
3382 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/mca.c linux-2.6.24.4/arch/x86/boot/mca.c |
3383 |
+--- linux-2.6.24.4/arch/x86/boot/mca.c 2008-03-24 14:49:18.000000000 -0400 |
3384 |
++++ linux-2.6.24.4/arch/x86/boot/mca.c 2008-03-26 17:56:55.000000000 -0400 |
3385 |
+@@ -21,7 +21,7 @@ int query_mca(void) |
3386 |
+ u8 err; |
3387 |
+ u16 es, bx, len; |
3388 |
+ |
3389 |
+- asm("pushw %%es ; " |
3390 |
++ asm volatile("pushw %%es ; " |
3391 |
+ "int $0x15 ; " |
3392 |
+ "setc %0 ; " |
3393 |
+ "movw %%es, %1 ; " |
3394 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/memory.c linux-2.6.24.4/arch/x86/boot/memory.c |
3395 |
+--- linux-2.6.24.4/arch/x86/boot/memory.c 2008-03-24 14:49:18.000000000 -0400 |
3396 |
++++ linux-2.6.24.4/arch/x86/boot/memory.c 2008-03-26 17:56:55.000000000 -0400 |
3397 |
+@@ -32,7 +32,7 @@ static int detect_memory_e820(void) |
3398 |
+ /* Important: %edx is clobbered by some BIOSes, |
3399 |
+ so it must be either used for the error output |
3400 |
+ or explicitly marked clobbered. */ |
3401 |
+- asm("int $0x15; setc %0" |
3402 |
++ asm volatile("int $0x15; setc %0" |
3403 |
+ : "=d" (err), "+b" (next), "=a" (id), "+c" (size), |
3404 |
+ "=m" (*desc) |
3405 |
+ : "D" (desc), "d" (SMAP), "a" (0xe820)); |
3406 |
+@@ -64,7 +64,7 @@ static int detect_memory_e801(void) |
3407 |
+ |
3408 |
+ bx = cx = dx = 0; |
3409 |
+ ax = 0xe801; |
3410 |
+- asm("stc; int $0x15; setc %0" |
3411 |
++ asm volatile("stc; int $0x15; setc %0" |
3412 |
+ : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx)); |
3413 |
+ |
3414 |
+ if (err) |
3415 |
+@@ -94,7 +94,7 @@ static int detect_memory_88(void) |
3416 |
+ u8 err; |
3417 |
+ |
3418 |
+ ax = 0x8800; |
3419 |
+- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax)); |
3420 |
++ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax)); |
3421 |
+ |
3422 |
+ boot_params.screen_info.ext_mem_k = ax; |
3423 |
+ |
3424 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/video.c linux-2.6.24.4/arch/x86/boot/video.c |
3425 |
+--- linux-2.6.24.4/arch/x86/boot/video.c 2008-03-24 14:49:18.000000000 -0400 |
3426 |
++++ linux-2.6.24.4/arch/x86/boot/video.c 2008-03-26 17:56:55.000000000 -0400 |
3427 |
+@@ -40,7 +40,7 @@ static void store_cursor_position(void) |
3428 |
+ |
3429 |
+ ax = 0x0300; |
3430 |
+ bx = 0; |
3431 |
+- asm(INT10 |
3432 |
++ asm volatile(INT10 |
3433 |
+ : "=d" (curpos), "+a" (ax), "+b" (bx) |
3434 |
+ : : "ecx", "esi", "edi"); |
3435 |
+ |
3436 |
+@@ -55,7 +55,7 @@ static void store_video_mode(void) |
3437 |
+ /* N.B.: the saving of the video page here is a bit silly, |
3438 |
+ since we pretty much assume page 0 everywhere. */ |
3439 |
+ ax = 0x0f00; |
3440 |
+- asm(INT10 |
3441 |
++ asm volatile(INT10 |
3442 |
+ : "+a" (ax), "=b" (page) |
3443 |
+ : : "ecx", "edx", "esi", "edi"); |
3444 |
+ |
3445 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/video-vesa.c linux-2.6.24.4/arch/x86/boot/video-vesa.c |
3446 |
+--- linux-2.6.24.4/arch/x86/boot/video-vesa.c 2008-03-24 14:49:18.000000000 -0400 |
3447 |
++++ linux-2.6.24.4/arch/x86/boot/video-vesa.c 2008-03-26 17:56:55.000000000 -0400 |
3448 |
+@@ -41,7 +41,7 @@ static int vesa_probe(void) |
3449 |
+ |
3450 |
+ ax = 0x4f00; |
3451 |
+ di = (size_t)&vginfo; |
3452 |
+- asm(INT10 |
3453 |
++ asm volatile(INT10 |
3454 |
+ : "+a" (ax), "+D" (di), "=m" (vginfo) |
3455 |
+ : : "ebx", "ecx", "edx", "esi"); |
3456 |
+ |
3457 |
+@@ -68,7 +68,7 @@ static int vesa_probe(void) |
3458 |
+ ax = 0x4f01; |
3459 |
+ cx = mode; |
3460 |
+ di = (size_t)&vminfo; |
3461 |
+- asm(INT10 |
3462 |
++ asm volatile(INT10 |
3463 |
+ : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo) |
3464 |
+ : : "ebx", "edx", "esi"); |
3465 |
+ |
3466 |
+@@ -115,7 +115,7 @@ static int vesa_set_mode(struct mode_inf |
3467 |
+ ax = 0x4f01; |
3468 |
+ cx = vesa_mode; |
3469 |
+ di = (size_t)&vminfo; |
3470 |
+- asm(INT10 |
3471 |
++ asm volatile(INT10 |
3472 |
+ : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo) |
3473 |
+ : : "ebx", "edx", "esi"); |
3474 |
+ |
3475 |
+@@ -193,19 +193,20 @@ static void vesa_dac_set_8bits(void) |
3476 |
+ /* Save the VESA protected mode info */ |
3477 |
+ static void vesa_store_pm_info(void) |
3478 |
+ { |
3479 |
+- u16 ax, bx, di, es; |
3480 |
++ u16 ax, bx, cx, di, es; |
3481 |
+ |
3482 |
+ ax = 0x4f0a; |
3483 |
+- bx = di = 0; |
3484 |
+- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es" |
3485 |
+- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di) |
3486 |
+- : : "ecx", "esi"); |
3487 |
++ bx = cx = di = 0; |
3488 |
++ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es" |
3489 |
++ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di) |
3490 |
++ : : "esi"); |
3491 |
+ |
3492 |
+ if (ax != 0x004f) |
3493 |
+ return; |
3494 |
+ |
3495 |
+ boot_params.screen_info.vesapm_seg = es; |
3496 |
+ boot_params.screen_info.vesapm_off = di; |
3497 |
++ boot_params.screen_info.vesapm_size = cx; |
3498 |
+ } |
3499 |
+ |
3500 |
+ /* |
3501 |
+@@ -259,7 +260,7 @@ void vesa_store_edid(void) |
3502 |
+ /* Note: The VBE DDC spec is different from the main VESA spec; |
3503 |
+ we genuinely have to assume all registers are destroyed here. */ |
3504 |
+ |
3505 |
+- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es" |
3506 |
++ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es" |
3507 |
+ : "+a" (ax), "+b" (bx) |
3508 |
+ : "c" (cx), "D" (di) |
3509 |
+ : "esi"); |
3510 |
+@@ -275,7 +276,7 @@ void vesa_store_edid(void) |
3511 |
+ cx = 0; /* Controller 0 */ |
3512 |
+ dx = 0; /* EDID block number */ |
3513 |
+ di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */ |
3514 |
+- asm(INT10 |
3515 |
++ asm volatile(INT10 |
3516 |
+ : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info) |
3517 |
+ : "c" (cx), "D" (di) |
3518 |
+ : "esi"); |
3519 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/video-vga.c linux-2.6.24.4/arch/x86/boot/video-vga.c |
3520 |
+--- linux-2.6.24.4/arch/x86/boot/video-vga.c 2008-03-24 14:49:18.000000000 -0400 |
3521 |
++++ linux-2.6.24.4/arch/x86/boot/video-vga.c 2008-03-26 17:56:55.000000000 -0400 |
3522 |
+@@ -225,7 +225,7 @@ static int vga_probe(void) |
3523 |
+ }; |
3524 |
+ u8 vga_flag; |
3525 |
+ |
3526 |
+- asm(INT10 |
3527 |
++ asm volatile(INT10 |
3528 |
+ : "=b" (boot_params.screen_info.orig_video_ega_bx) |
3529 |
+ : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */ |
3530 |
+ : "ecx", "edx", "esi", "edi"); |
3531 |
+@@ -233,7 +233,7 @@ static int vga_probe(void) |
3532 |
+ /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */ |
3533 |
+ if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) { |
3534 |
+ /* EGA/VGA */ |
3535 |
+- asm(INT10 |
3536 |
++ asm volatile(INT10 |
3537 |
+ : "=a" (vga_flag) |
3538 |
+ : "a" (0x1a00) |
3539 |
+ : "ebx", "ecx", "edx", "esi", "edi"); |
3540 |
+diff -urNp linux-2.6.24.4/arch/x86/boot/voyager.c linux-2.6.24.4/arch/x86/boot/voyager.c |
3541 |
+--- linux-2.6.24.4/arch/x86/boot/voyager.c 2008-03-24 14:49:18.000000000 -0400 |
3542 |
++++ linux-2.6.24.4/arch/x86/boot/voyager.c 2008-03-26 17:56:55.000000000 -0400 |
3543 |
+@@ -27,7 +27,7 @@ int query_voyager(void) |
3544 |
+ |
3545 |
+ data_ptr[0] = 0xff; /* Flag on config not found(?) */ |
3546 |
+ |
3547 |
+- asm("pushw %%es ; " |
3548 |
++ asm volatile("pushw %%es ; " |
3549 |
+ "int $0x15 ; " |
3550 |
+ "setc %0 ; " |
3551 |
+ "movw %%es, %1 ; " |
3552 |
+diff -urNp linux-2.6.24.4/arch/x86/ia32/ia32_binfmt.c linux-2.6.24.4/arch/x86/ia32/ia32_binfmt.c |
3553 |
+--- linux-2.6.24.4/arch/x86/ia32/ia32_binfmt.c 2008-03-24 14:49:18.000000000 -0400 |
3554 |
++++ linux-2.6.24.4/arch/x86/ia32/ia32_binfmt.c 2008-03-26 17:56:55.000000000 -0400 |
3555 |
+@@ -47,12 +47,12 @@ |
3556 |
+ #define AT_SYSINFO 32 |
3557 |
+ #define AT_SYSINFO_EHDR 33 |
3558 |
+ |
3559 |
+-int sysctl_vsyscall32 = 1; |
3560 |
++int sysctl_vsyscall32; |
3561 |
+ |
3562 |
+ #undef ARCH_DLINFO |
3563 |
+ #define ARCH_DLINFO do { \ |
3564 |
+ if (sysctl_vsyscall32) { \ |
3565 |
+- current->mm->context.vdso = (void *)VSYSCALL32_BASE; \ |
3566 |
++ current->mm->context.vdso = VSYSCALL32_BASE; \ |
3567 |
+ NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \ |
3568 |
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \ |
3569 |
+ } \ |
3570 |
+@@ -66,6 +66,17 @@ struct file; |
3571 |
+ |
3572 |
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) |
3573 |
+ |
3574 |
++#ifdef CONFIG_PAX_ASLR |
3575 |
++#undef PAX_ELF_ET_DYN_BASE |
3576 |
++#undef PAX_DELTA_MMAP_LEN |
3577 |
++#undef PAX_DELTA_STACK_LEN |
3578 |
++ |
3579 |
++#define PAX_ELF_ET_DYN_BASE 0x08048000UL |
3580 |
++ |
3581 |
++#define PAX_DELTA_MMAP_LEN 16 |
3582 |
++#define PAX_DELTA_STACK_LEN 16 |
3583 |
++#endif |
3584 |
++ |
3585 |
+ #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0) |
3586 |
+ |
3587 |
+ #define _GET_SEG(x) \ |
3588 |
+@@ -263,7 +274,7 @@ static ctl_table abi_table2[] = { |
3589 |
+ .mode = 0644, |
3590 |
+ .proc_handler = proc_dointvec |
3591 |
+ }, |
3592 |
+- {} |
3593 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
3594 |
+ }; |
3595 |
+ |
3596 |
+ static ctl_table abi_root_table2[] = { |
3597 |
+@@ -273,7 +284,7 @@ static ctl_table abi_root_table2[] = { |
3598 |
+ .mode = 0555, |
3599 |
+ .child = abi_table2 |
3600 |
+ }, |
3601 |
+- {} |
3602 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
3603 |
+ }; |
3604 |
+ |
3605 |
+ static __init int ia32_binfmt_init(void) |
3606 |
+diff -urNp linux-2.6.24.4/arch/x86/ia32/ia32_signal.c linux-2.6.24.4/arch/x86/ia32/ia32_signal.c |
3607 |
+--- linux-2.6.24.4/arch/x86/ia32/ia32_signal.c 2008-03-24 14:49:18.000000000 -0400 |
3608 |
++++ linux-2.6.24.4/arch/x86/ia32/ia32_signal.c 2008-03-26 17:56:55.000000000 -0400 |
3609 |
+@@ -573,6 +573,7 @@ int ia32_setup_rt_frame(int sig, struct |
3610 |
+ __NR_ia32_rt_sigreturn, |
3611 |
+ 0x80cd, |
3612 |
+ 0, |
3613 |
++ 0 |
3614 |
+ }; |
3615 |
+ err |= __copy_to_user(frame->retcode, &code, 8); |
3616 |
+ } |
3617 |
+diff -urNp linux-2.6.24.4/arch/x86/ia32/mmap32.c linux-2.6.24.4/arch/x86/ia32/mmap32.c |
3618 |
+--- linux-2.6.24.4/arch/x86/ia32/mmap32.c 2008-03-24 14:49:18.000000000 -0400 |
3619 |
++++ linux-2.6.24.4/arch/x86/ia32/mmap32.c 2008-03-26 17:56:55.000000000 -0400 |
3620 |
+@@ -69,10 +69,22 @@ void ia32_pick_mmap_layout(struct mm_str |
3621 |
+ (current->personality & ADDR_COMPAT_LAYOUT) || |
3622 |
+ current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) { |
3623 |
+ mm->mmap_base = TASK_UNMAPPED_BASE; |
3624 |
++ |
3625 |
++#ifdef CONFIG_PAX_RANDMMAP |
3626 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
3627 |
++ mm->mmap_base += mm->delta_mmap; |
3628 |
++#endif |
3629 |
++ |
3630 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
3631 |
+ mm->unmap_area = arch_unmap_area; |
3632 |
+ } else { |
3633 |
+ mm->mmap_base = mmap_base(mm); |
3634 |
++ |
3635 |
++#ifdef CONFIG_PAX_RANDMMAP |
3636 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
3637 |
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; |
3638 |
++#endif |
3639 |
++ |
3640 |
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
3641 |
+ mm->unmap_area = arch_unmap_area_topdown; |
3642 |
+ } |
3643 |
+diff -urNp linux-2.6.24.4/arch/x86/ia32/ptrace32.c linux-2.6.24.4/arch/x86/ia32/ptrace32.c |
3644 |
+--- linux-2.6.24.4/arch/x86/ia32/ptrace32.c 2008-03-24 14:49:18.000000000 -0400 |
3645 |
++++ linux-2.6.24.4/arch/x86/ia32/ptrace32.c 2008-03-26 17:56:55.000000000 -0400 |
3646 |
+@@ -382,7 +382,7 @@ asmlinkage long sys32_ptrace(long reques |
3647 |
+ /* no checking to be bug-to-bug compatible with i386. */ |
3648 |
+ /* but silence warning */ |
3649 |
+ if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u))) |
3650 |
+- ; |
3651 |
++ {} |
3652 |
+ set_stopped_child_used_math(child); |
3653 |
+ child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask; |
3654 |
+ ret = 0; |
3655 |
+diff -urNp linux-2.6.24.4/arch/x86/ia32/syscall32.c linux-2.6.24.4/arch/x86/ia32/syscall32.c |
3656 |
+--- linux-2.6.24.4/arch/x86/ia32/syscall32.c 2008-03-24 14:49:18.000000000 -0400 |
3657 |
++++ linux-2.6.24.4/arch/x86/ia32/syscall32.c 2008-03-26 17:56:55.000000000 -0400 |
3658 |
+@@ -30,6 +30,9 @@ int syscall32_setup_pages(struct linux_b |
3659 |
+ struct mm_struct *mm = current->mm; |
3660 |
+ int ret; |
3661 |
+ |
3662 |
++ if (!sysctl_vsyscall32) |
3663 |
++ return 0; |
3664 |
++ |
3665 |
+ down_write(&mm->mmap_sem); |
3666 |
+ /* |
3667 |
+ * MAYWRITE to allow gdb to COW and set breakpoints |
3668 |
+diff -urNp linux-2.6.24.4/arch/x86/Kconfig linux-2.6.24.4/arch/x86/Kconfig |
3669 |
+--- linux-2.6.24.4/arch/x86/Kconfig 2008-03-24 14:49:18.000000000 -0400 |
3670 |
++++ linux-2.6.24.4/arch/x86/Kconfig 2008-03-26 17:56:55.000000000 -0400 |
3671 |
+@@ -792,7 +792,7 @@ config PAGE_OFFSET |
3672 |
+ hex |
3673 |
+ default 0xB0000000 if VMSPLIT_3G_OPT |
3674 |
+ default 0x80000000 if VMSPLIT_2G |
3675 |
+- default 0x78000000 if VMSPLIT_2G_OPT |
3676 |
++ default 0x70000000 if VMSPLIT_2G_OPT |
3677 |
+ default 0x40000000 if VMSPLIT_1G |
3678 |
+ default 0xC0000000 |
3679 |
+ depends on X86_32 |
3680 |
+@@ -1096,8 +1096,7 @@ config CRASH_DUMP |
3681 |
+ config PHYSICAL_START |
3682 |
+ hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) |
3683 |
+ default "0x1000000" if X86_NUMAQ |
3684 |
+- default "0x200000" if X86_64 |
3685 |
+- default "0x100000" |
3686 |
++ default "0x200000" |
3687 |
+ help |
3688 |
+ This gives the physical address where the kernel is loaded. |
3689 |
+ |
3690 |
+@@ -1190,8 +1189,8 @@ config HOTPLUG_CPU |
3691 |
+ |
3692 |
+ config COMPAT_VDSO |
3693 |
+ bool "Compat VDSO support" |
3694 |
+- default y |
3695 |
+- depends on X86_32 |
3696 |
++ default n |
3697 |
++ depends on X86_32 && !PAX_NOEXEC |
3698 |
+ help |
3699 |
+ Map the VDSO to the predictable old-style address too. |
3700 |
+ ---help--- |
3701 |
+@@ -1387,7 +1386,7 @@ config PCI |
3702 |
+ choice |
3703 |
+ prompt "PCI access mode" |
3704 |
+ depends on X86_32 && PCI && !X86_VISWS |
3705 |
+- default PCI_GOANY |
3706 |
++ default PCI_GODIRECT |
3707 |
+ ---help--- |
3708 |
+ On PCI systems, the BIOS can be used to detect the PCI devices and |
3709 |
+ determine their configuration. However, some old PCI motherboards |
3710 |
+diff -urNp linux-2.6.24.4/arch/x86/Kconfig.cpu linux-2.6.24.4/arch/x86/Kconfig.cpu |
3711 |
+--- linux-2.6.24.4/arch/x86/Kconfig.cpu 2008-03-24 14:49:18.000000000 -0400 |
3712 |
++++ linux-2.6.24.4/arch/x86/Kconfig.cpu 2008-03-26 17:56:55.000000000 -0400 |
3713 |
+@@ -328,7 +328,7 @@ config X86_PPRO_FENCE |
3714 |
+ |
3715 |
+ config X86_F00F_BUG |
3716 |
+ bool |
3717 |
+- depends on M586MMX || M586TSC || M586 || M486 || M386 |
3718 |
++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC |
3719 |
+ default y |
3720 |
+ |
3721 |
+ config X86_WP_WORKS_OK |
3722 |
+@@ -353,7 +353,7 @@ config X86_POPAD_OK |
3723 |
+ |
3724 |
+ config X86_ALIGNMENT_16 |
3725 |
+ bool |
3726 |
+- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 |
3727 |
++ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 |
3728 |
+ default y |
3729 |
+ |
3730 |
+ config X86_GOOD_APIC |
3731 |
+diff -urNp linux-2.6.24.4/arch/x86/Kconfig.debug linux-2.6.24.4/arch/x86/Kconfig.debug |
3732 |
+--- linux-2.6.24.4/arch/x86/Kconfig.debug 2008-03-24 14:49:18.000000000 -0400 |
3733 |
++++ linux-2.6.24.4/arch/x86/Kconfig.debug 2008-03-26 17:56:55.000000000 -0400 |
3734 |
+@@ -49,7 +49,7 @@ config DEBUG_PAGEALLOC |
3735 |
+ |
3736 |
+ config DEBUG_RODATA |
3737 |
+ bool "Write protect kernel read-only data structures" |
3738 |
+- depends on DEBUG_KERNEL |
3739 |
++ depends on DEBUG_KERNEL && BROKEN |
3740 |
+ help |
3741 |
+ Mark the kernel read-only data as write-protected in the pagetables, |
3742 |
+ in order to catch accidental (and incorrect) writes to such const |
3743 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/acpi/boot.c linux-2.6.24.4/arch/x86/kernel/acpi/boot.c |
3744 |
+--- linux-2.6.24.4/arch/x86/kernel/acpi/boot.c 2008-03-24 14:49:18.000000000 -0400 |
3745 |
++++ linux-2.6.24.4/arch/x86/kernel/acpi/boot.c 2008-03-26 17:56:55.000000000 -0400 |
3746 |
+@@ -1155,7 +1155,7 @@ static struct dmi_system_id __initdata a |
3747 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), |
3748 |
+ }, |
3749 |
+ }, |
3750 |
+- {} |
3751 |
++ { NULL, NULL, {{0, NULL}}, NULL} |
3752 |
+ }; |
3753 |
+ |
3754 |
+ #endif /* __i386__ */ |
3755 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/acpi/sleep_32.c linux-2.6.24.4/arch/x86/kernel/acpi/sleep_32.c |
3756 |
+--- linux-2.6.24.4/arch/x86/kernel/acpi/sleep_32.c 2008-03-24 14:49:18.000000000 -0400 |
3757 |
++++ linux-2.6.24.4/arch/x86/kernel/acpi/sleep_32.c 2008-03-26 17:56:55.000000000 -0400 |
3758 |
+@@ -98,7 +98,7 @@ static __initdata struct dmi_system_id a |
3759 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), |
3760 |
+ }, |
3761 |
+ }, |
3762 |
+- {} |
3763 |
++ { NULL, NULL, {{0, NULL}}, NULL} |
3764 |
+ }; |
3765 |
+ |
3766 |
+ static int __init acpisleep_dmi_init(void) |
3767 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.24.4/arch/x86/kernel/acpi/wakeup_32.S |
3768 |
+--- linux-2.6.24.4/arch/x86/kernel/acpi/wakeup_32.S 2008-03-24 14:49:18.000000000 -0400 |
3769 |
++++ linux-2.6.24.4/arch/x86/kernel/acpi/wakeup_32.S 2008-03-26 17:56:55.000000000 -0400 |
3770 |
+@@ -2,6 +2,7 @@ |
3771 |
+ #include <linux/linkage.h> |
3772 |
+ #include <asm/segment.h> |
3773 |
+ #include <asm/page.h> |
3774 |
++#include <asm/msr-index.h> |
3775 |
+ |
3776 |
+ # |
3777 |
+ # wakeup_code runs in real mode, and at unknown address (determined at run-time). |
3778 |
+@@ -79,7 +80,7 @@ wakeup_code: |
3779 |
+ # restore efer setting |
3780 |
+ movl real_save_efer_edx - wakeup_code, %edx |
3781 |
+ movl real_save_efer_eax - wakeup_code, %eax |
3782 |
+- mov $0xc0000080, %ecx |
3783 |
++ mov $MSR_EFER, %ecx |
3784 |
+ wrmsr |
3785 |
+ 4: |
3786 |
+ # make sure %cr4 is set correctly (features, etc) |
3787 |
+@@ -196,13 +197,11 @@ wakeup_pmode_return: |
3788 |
+ # and restore the stack ... but you need gdt for this to work |
3789 |
+ movl saved_context_esp, %esp |
3790 |
+ |
3791 |
+- movl %cs:saved_magic, %eax |
3792 |
+- cmpl $0x12345678, %eax |
3793 |
++ cmpl $0x12345678, saved_magic |
3794 |
+ jne bogus_magic |
3795 |
+ |
3796 |
+ # jump to place where we left off |
3797 |
+- movl saved_eip,%eax |
3798 |
+- jmp *%eax |
3799 |
++ jmp *(saved_eip) |
3800 |
+ |
3801 |
+ bogus_magic: |
3802 |
+ jmp bogus_magic |
3803 |
+@@ -233,7 +232,7 @@ ENTRY(acpi_copy_wakeup_routine) |
3804 |
+ # save efer setting |
3805 |
+ pushl %eax |
3806 |
+ movl %eax, %ebx |
3807 |
+- mov $0xc0000080, %ecx |
3808 |
++ mov $MSR_EFER, %ecx |
3809 |
+ rdmsr |
3810 |
+ movl %edx, real_save_efer_edx - wakeup_start (%ebx) |
3811 |
+ movl %eax, real_save_efer_eax - wakeup_start (%ebx) |
3812 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/alternative.c linux-2.6.24.4/arch/x86/kernel/alternative.c |
3813 |
+--- linux-2.6.24.4/arch/x86/kernel/alternative.c 2008-03-24 14:49:18.000000000 -0400 |
3814 |
++++ linux-2.6.24.4/arch/x86/kernel/alternative.c 2008-03-26 17:56:55.000000000 -0400 |
3815 |
+@@ -389,7 +389,7 @@ void apply_paravirt(struct paravirt_patc |
3816 |
+ |
3817 |
+ BUG_ON(p->len > MAX_PATCH_LEN); |
3818 |
+ /* prep the buffer with the original instructions */ |
3819 |
+- memcpy(insnbuf, p->instr, p->len); |
3820 |
++ memcpy(insnbuf, ktla_ktva(p->instr), p->len); |
3821 |
+ used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf, |
3822 |
+ (unsigned long)p->instr, p->len); |
3823 |
+ |
3824 |
+@@ -467,7 +467,19 @@ void __init alternative_instructions(voi |
3825 |
+ */ |
3826 |
+ void __kprobes text_poke(void *addr, unsigned char *opcode, int len) |
3827 |
+ { |
3828 |
+- memcpy(addr, opcode, len); |
3829 |
++ |
3830 |
++#ifdef CONFIG_PAX_KERNEXEC |
3831 |
++ unsigned long cr0; |
3832 |
++ |
3833 |
++ pax_open_kernel(cr0); |
3834 |
++#endif |
3835 |
++ |
3836 |
++ memcpy(ktla_ktva(addr), opcode, len); |
3837 |
++ |
3838 |
++#ifdef CONFIG_PAX_KERNEXEC |
3839 |
++ pax_close_kernel(cr0); |
3840 |
++#endif |
3841 |
++ |
3842 |
+ sync_core(); |
3843 |
+ /* Could also do a CLFLUSH here to speed up CPU recovery; but |
3844 |
+ that causes hangs on some VIA CPUs. */ |
3845 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/apm_32.c linux-2.6.24.4/arch/x86/kernel/apm_32.c |
3846 |
+--- linux-2.6.24.4/arch/x86/kernel/apm_32.c 2008-03-24 14:49:18.000000000 -0400 |
3847 |
++++ linux-2.6.24.4/arch/x86/kernel/apm_32.c 2008-03-26 17:56:55.000000000 -0400 |
3848 |
+@@ -407,7 +407,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq |
3849 |
+ static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); |
3850 |
+ static struct apm_user * user_list; |
3851 |
+ static DEFINE_SPINLOCK(user_list_lock); |
3852 |
+-static const struct desc_struct bad_bios_desc = { 0, 0x00409200 }; |
3853 |
++static const struct desc_struct bad_bios_desc = { 0, 0x00409300 }; |
3854 |
+ |
3855 |
+ static const char driver_version[] = "1.16ac"; /* no spaces */ |
3856 |
+ |
3857 |
+@@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb |
3858 |
+ struct desc_struct save_desc_40; |
3859 |
+ struct desc_struct *gdt; |
3860 |
+ |
3861 |
++#ifdef CONFIG_PAX_KERNEXEC |
3862 |
++ unsigned long cr0; |
3863 |
++#endif |
3864 |
++ |
3865 |
+ cpus = apm_save_cpus(); |
3866 |
+ |
3867 |
+ cpu = get_cpu(); |
3868 |
+ gdt = get_cpu_gdt_table(cpu); |
3869 |
+ save_desc_40 = gdt[0x40 / 8]; |
3870 |
++ |
3871 |
++#ifdef CONFIG_PAX_KERNEXEC |
3872 |
++ pax_open_kernel(cr0); |
3873 |
++#endif |
3874 |
++ |
3875 |
+ gdt[0x40 / 8] = bad_bios_desc; |
3876 |
+ |
3877 |
++#ifdef CONFIG_PAX_KERNEXEC |
3878 |
++ pax_close_kernel(cr0); |
3879 |
++#endif |
3880 |
++ |
3881 |
+ apm_irq_save(flags); |
3882 |
+ APM_DO_SAVE_SEGS; |
3883 |
+ apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi); |
3884 |
+ APM_DO_RESTORE_SEGS; |
3885 |
+ apm_irq_restore(flags); |
3886 |
++ |
3887 |
++#ifdef CONFIG_PAX_KERNEXEC |
3888 |
++ pax_open_kernel(cr0); |
3889 |
++#endif |
3890 |
++ |
3891 |
+ gdt[0x40 / 8] = save_desc_40; |
3892 |
++ |
3893 |
++#ifdef CONFIG_PAX_KERNEXEC |
3894 |
++ pax_close_kernel(cr0); |
3895 |
++#endif |
3896 |
++ |
3897 |
+ put_cpu(); |
3898 |
+ apm_restore_cpus(cpus); |
3899 |
+ |
3900 |
+@@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func, |
3901 |
+ struct desc_struct save_desc_40; |
3902 |
+ struct desc_struct *gdt; |
3903 |
+ |
3904 |
++#ifdef CONFIG_PAX_KERNEXEC |
3905 |
++ unsigned long cr0; |
3906 |
++#endif |
3907 |
++ |
3908 |
+ cpus = apm_save_cpus(); |
3909 |
+ |
3910 |
+ cpu = get_cpu(); |
3911 |
+ gdt = get_cpu_gdt_table(cpu); |
3912 |
+ save_desc_40 = gdt[0x40 / 8]; |
3913 |
++ |
3914 |
++#ifdef CONFIG_PAX_KERNEXEC |
3915 |
++ pax_open_kernel(cr0); |
3916 |
++#endif |
3917 |
++ |
3918 |
+ gdt[0x40 / 8] = bad_bios_desc; |
3919 |
+ |
3920 |
++#ifdef CONFIG_PAX_KERNEXEC |
3921 |
++ pax_close_kernel(cr0); |
3922 |
++#endif |
3923 |
++ |
3924 |
+ apm_irq_save(flags); |
3925 |
+ APM_DO_SAVE_SEGS; |
3926 |
+ error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax); |
3927 |
+ APM_DO_RESTORE_SEGS; |
3928 |
+ apm_irq_restore(flags); |
3929 |
++ |
3930 |
++#ifdef CONFIG_PAX_KERNEXEC |
3931 |
++ pax_open_kernel(cr0); |
3932 |
++#endif |
3933 |
++ |
3934 |
+ gdt[0x40 / 8] = save_desc_40; |
3935 |
++ |
3936 |
++#ifdef CONFIG_PAX_KERNEXEC |
3937 |
++ pax_close_kernel(cr0); |
3938 |
++#endif |
3939 |
++ |
3940 |
+ put_cpu(); |
3941 |
+ apm_restore_cpus(cpus); |
3942 |
+ return error; |
3943 |
+@@ -924,7 +970,7 @@ recalc: |
3944 |
+ |
3945 |
+ static void apm_power_off(void) |
3946 |
+ { |
3947 |
+- unsigned char po_bios_call[] = { |
3948 |
++ const unsigned char po_bios_call[] = { |
3949 |
+ 0xb8, 0x00, 0x10, /* movw $0x1000,ax */ |
3950 |
+ 0x8e, 0xd0, /* movw ax,ss */ |
3951 |
+ 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */ |
3952 |
+@@ -1864,7 +1910,10 @@ static const struct file_operations apm_ |
3953 |
+ static struct miscdevice apm_device = { |
3954 |
+ APM_MINOR_DEV, |
3955 |
+ "apm_bios", |
3956 |
+- &apm_bios_fops |
3957 |
++ &apm_bios_fops, |
3958 |
++ {NULL, NULL}, |
3959 |
++ NULL, |
3960 |
++ NULL |
3961 |
+ }; |
3962 |
+ |
3963 |
+ |
3964 |
+@@ -2177,7 +2226,7 @@ static struct dmi_system_id __initdata a |
3965 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, |
3966 |
+ }, |
3967 |
+ |
3968 |
+- { } |
3969 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL} |
3970 |
+ }; |
3971 |
+ |
3972 |
+ /* |
3973 |
+@@ -2196,6 +2245,10 @@ static int __init apm_init(void) |
3974 |
+ struct desc_struct *gdt; |
3975 |
+ int err; |
3976 |
+ |
3977 |
++#ifdef CONFIG_PAX_KERNEXEC |
3978 |
++ unsigned long cr0; |
3979 |
++#endif |
3980 |
++ |
3981 |
+ dmi_check_system(apm_dmi_table); |
3982 |
+ |
3983 |
+ if (apm_info.bios.version == 0 || paravirt_enabled()) { |
3984 |
+@@ -2269,9 +2322,18 @@ static int __init apm_init(void) |
3985 |
+ * This is for buggy BIOS's that refer to (real mode) segment 0x40 |
3986 |
+ * even though they are called in protected mode. |
3987 |
+ */ |
3988 |
++ |
3989 |
++#ifdef CONFIG_PAX_KERNEXEC |
3990 |
++ pax_open_kernel(cr0); |
3991 |
++#endif |
3992 |
++ |
3993 |
+ set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); |
3994 |
+ _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); |
3995 |
+ |
3996 |
++#ifdef CONFIG_PAX_KERNEXEC |
3997 |
++ pax_close_kernel(cr0); |
3998 |
++#endif |
3999 |
++ |
4000 |
+ /* |
4001 |
+ * Set up the long jump entry point to the APM BIOS, which is called |
4002 |
+ * from inline assembly. |
4003 |
+@@ -2290,6 +2352,11 @@ static int __init apm_init(void) |
4004 |
+ * code to that CPU. |
4005 |
+ */ |
4006 |
+ gdt = get_cpu_gdt_table(0); |
4007 |
++ |
4008 |
++#ifdef CONFIG_PAX_KERNEXEC |
4009 |
++ pax_open_kernel(cr0); |
4010 |
++#endif |
4011 |
++ |
4012 |
+ set_base(gdt[APM_CS >> 3], |
4013 |
+ __va((unsigned long)apm_info.bios.cseg << 4)); |
4014 |
+ set_base(gdt[APM_CS_16 >> 3], |
4015 |
+@@ -2297,6 +2364,10 @@ static int __init apm_init(void) |
4016 |
+ set_base(gdt[APM_DS >> 3], |
4017 |
+ __va((unsigned long)apm_info.bios.dseg << 4)); |
4018 |
+ |
4019 |
++#ifdef CONFIG_PAX_KERNEXEC |
4020 |
++ pax_close_kernel(cr0); |
4021 |
++#endif |
4022 |
++ |
4023 |
+ apm_proc = create_proc_entry("apm", 0, NULL); |
4024 |
+ if (apm_proc) |
4025 |
+ apm_proc->proc_fops = &apm_file_ops; |
4026 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/asm-offsets_32.c linux-2.6.24.4/arch/x86/kernel/asm-offsets_32.c |
4027 |
+--- linux-2.6.24.4/arch/x86/kernel/asm-offsets_32.c 2008-03-24 14:49:18.000000000 -0400 |
4028 |
++++ linux-2.6.24.4/arch/x86/kernel/asm-offsets_32.c 2008-03-26 17:56:55.000000000 -0400 |
4029 |
+@@ -110,6 +110,7 @@ void foo(void) |
4030 |
+ DEFINE(PTRS_PER_PTE, PTRS_PER_PTE); |
4031 |
+ DEFINE(PTRS_PER_PMD, PTRS_PER_PMD); |
4032 |
+ DEFINE(PTRS_PER_PGD, PTRS_PER_PGD); |
4033 |
++ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE); |
4034 |
+ |
4035 |
+ DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK); |
4036 |
+ |
4037 |
+@@ -125,6 +126,7 @@ void foo(void) |
4038 |
+ OFFSET(PV_CPU_iret, pv_cpu_ops, iret); |
4039 |
+ OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit); |
4040 |
+ OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0); |
4041 |
++ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0); |
4042 |
+ #endif |
4043 |
+ |
4044 |
+ #ifdef CONFIG_XEN |
4045 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/asm-offsets_64.c linux-2.6.24.4/arch/x86/kernel/asm-offsets_64.c |
4046 |
+--- linux-2.6.24.4/arch/x86/kernel/asm-offsets_64.c 2008-03-24 14:49:18.000000000 -0400 |
4047 |
++++ linux-2.6.24.4/arch/x86/kernel/asm-offsets_64.c 2008-03-26 17:56:55.000000000 -0400 |
4048 |
+@@ -108,6 +108,7 @@ int main(void) |
4049 |
+ ENTRY(cr8); |
4050 |
+ BLANK(); |
4051 |
+ #undef ENTRY |
4052 |
++ DEFINE(TSS_size, sizeof(struct tss_struct)); |
4053 |
+ DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); |
4054 |
+ BLANK(); |
4055 |
+ DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); |
4056 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/common.c linux-2.6.24.4/arch/x86/kernel/cpu/common.c |
4057 |
+--- linux-2.6.24.4/arch/x86/kernel/cpu/common.c 2008-03-24 14:49:18.000000000 -0400 |
4058 |
++++ linux-2.6.24.4/arch/x86/kernel/cpu/common.c 2008-03-26 17:56:55.000000000 -0400 |
4059 |
+@@ -4,7 +4,6 @@ |
4060 |
+ #include <linux/smp.h> |
4061 |
+ #include <linux/module.h> |
4062 |
+ #include <linux/percpu.h> |
4063 |
+-#include <linux/bootmem.h> |
4064 |
+ #include <asm/semaphore.h> |
4065 |
+ #include <asm/processor.h> |
4066 |
+ #include <asm/i387.h> |
4067 |
+@@ -21,39 +20,15 @@ |
4068 |
+ |
4069 |
+ #include "cpu.h" |
4070 |
+ |
4071 |
+-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { |
4072 |
+- [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 }, |
4073 |
+- [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 }, |
4074 |
+- [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 }, |
4075 |
+- [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 }, |
4076 |
+- /* |
4077 |
+- * Segments used for calling PnP BIOS have byte granularity. |
4078 |
+- * They code segments and data segments have fixed 64k limits, |
4079 |
+- * the transfer segment sizes are set at run time. |
4080 |
+- */ |
4081 |
+- [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */ |
4082 |
+- [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */ |
4083 |
+- [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */ |
4084 |
+- [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */ |
4085 |
+- [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */ |
4086 |
+- /* |
4087 |
+- * The APM segments have byte granularity and their bases |
4088 |
+- * are set at run time. All have 64k limits. |
4089 |
+- */ |
4090 |
+- [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */ |
4091 |
+- /* 16-bit code */ |
4092 |
+- [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 }, |
4093 |
+- [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */ |
4094 |
+- |
4095 |
+- [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 }, |
4096 |
+- [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 }, |
4097 |
+-} }; |
4098 |
+-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); |
4099 |
+- |
4100 |
+ static int cachesize_override __cpuinitdata = -1; |
4101 |
+ static int disable_x86_fxsr __cpuinitdata; |
4102 |
+ static int disable_x86_serial_nr __cpuinitdata = 1; |
4103 |
+-static int disable_x86_sep __cpuinitdata; |
4104 |
++ |
4105 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) |
4106 |
++int disable_x86_sep __cpuinitdata = 1; |
4107 |
++#else |
4108 |
++int disable_x86_sep __cpuinitdata; |
4109 |
++#endif |
4110 |
+ |
4111 |
+ struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; |
4112 |
+ |
4113 |
+@@ -262,9 +237,9 @@ void __init cpu_detect(struct cpuinfo_x8 |
4114 |
+ { |
4115 |
+ /* Get vendor name */ |
4116 |
+ cpuid(0x00000000, &c->cpuid_level, |
4117 |
+- (int *)&c->x86_vendor_id[0], |
4118 |
+- (int *)&c->x86_vendor_id[8], |
4119 |
+- (int *)&c->x86_vendor_id[4]); |
4120 |
++ (unsigned int *)&c->x86_vendor_id[0], |
4121 |
++ (unsigned int *)&c->x86_vendor_id[8], |
4122 |
++ (unsigned int *)&c->x86_vendor_id[4]); |
4123 |
+ |
4124 |
+ c->x86 = 4; |
4125 |
+ if (c->cpuid_level >= 0x00000001) { |
4126 |
+@@ -304,15 +279,14 @@ static void __init early_cpu_detect(void |
4127 |
+ |
4128 |
+ static void __cpuinit generic_identify(struct cpuinfo_x86 * c) |
4129 |
+ { |
4130 |
+- u32 tfms, xlvl; |
4131 |
+- int ebx; |
4132 |
++ u32 tfms, xlvl, ebx; |
4133 |
+ |
4134 |
+ if (have_cpuid_p()) { |
4135 |
+ /* Get vendor name */ |
4136 |
+ cpuid(0x00000000, &c->cpuid_level, |
4137 |
+- (int *)&c->x86_vendor_id[0], |
4138 |
+- (int *)&c->x86_vendor_id[8], |
4139 |
+- (int *)&c->x86_vendor_id[4]); |
4140 |
++ (unsigned int *)&c->x86_vendor_id[0], |
4141 |
++ (unsigned int *)&c->x86_vendor_id[8], |
4142 |
++ (unsigned int *)&c->x86_vendor_id[4]); |
4143 |
+ |
4144 |
+ get_cpu_vendor(c, 0); |
4145 |
+ /* Initialize the standard set of capabilities */ |
4146 |
+@@ -644,7 +618,7 @@ void switch_to_new_gdt(void) |
4147 |
+ { |
4148 |
+ struct Xgt_desc_struct gdt_descr; |
4149 |
+ |
4150 |
+- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); |
4151 |
++ gdt_descr.address = get_cpu_gdt_table(smp_processor_id()); |
4152 |
+ gdt_descr.size = GDT_SIZE - 1; |
4153 |
+ load_gdt(&gdt_descr); |
4154 |
+ asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory"); |
4155 |
+@@ -660,7 +634,7 @@ void __cpuinit cpu_init(void) |
4156 |
+ { |
4157 |
+ int cpu = smp_processor_id(); |
4158 |
+ struct task_struct *curr = current; |
4159 |
+- struct tss_struct * t = &per_cpu(init_tss, cpu); |
4160 |
++ struct tss_struct *t = init_tss + cpu; |
4161 |
+ struct thread_struct *thread = &curr->thread; |
4162 |
+ |
4163 |
+ if (cpu_test_and_set(cpu, cpu_initialized)) { |
4164 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c |
4165 |
+--- linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-03-24 14:49:18.000000000 -0400 |
4166 |
++++ linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-03-26 17:56:55.000000000 -0400 |
4167 |
+@@ -549,7 +549,7 @@ static const struct dmi_system_id sw_any |
4168 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"), |
4169 |
+ }, |
4170 |
+ }, |
4171 |
+- { } |
4172 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
4173 |
+ }; |
4174 |
+ #endif |
4175 |
+ |
4176 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c |
4177 |
+--- linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-03-24 14:49:18.000000000 -0400 |
4178 |
++++ linux-2.6.24.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-03-26 17:56:55.000000000 -0400 |
4179 |
+@@ -223,7 +223,7 @@ static struct cpu_model models[] = |
4180 |
+ { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL }, |
4181 |
+ { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL }, |
4182 |
+ |
4183 |
+- { NULL, } |
4184 |
++ { NULL, NULL, 0, NULL} |
4185 |
+ }; |
4186 |
+ #undef _BANIAS |
4187 |
+ #undef BANIAS |
4188 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/intel.c linux-2.6.24.4/arch/x86/kernel/cpu/intel.c |
4189 |
+--- linux-2.6.24.4/arch/x86/kernel/cpu/intel.c 2008-03-24 14:49:18.000000000 -0400 |
4190 |
++++ linux-2.6.24.4/arch/x86/kernel/cpu/intel.c 2008-03-26 17:56:55.000000000 -0400 |
4191 |
+@@ -104,6 +104,7 @@ static void __cpuinit trap_init_f00f_bug |
4192 |
+ * it uses the read-only mapped virtual address. |
4193 |
+ */ |
4194 |
+ idt_descr.address = fix_to_virt(FIX_F00F_IDT); |
4195 |
++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT); |
4196 |
+ load_idt(&idt_descr); |
4197 |
+ } |
4198 |
+ #endif |
4199 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/intel_cacheinfo.c linux-2.6.24.4/arch/x86/kernel/cpu/intel_cacheinfo.c |
4200 |
+--- linux-2.6.24.4/arch/x86/kernel/cpu/intel_cacheinfo.c 2008-03-24 14:49:18.000000000 -0400 |
4201 |
++++ linux-2.6.24.4/arch/x86/kernel/cpu/intel_cacheinfo.c 2008-03-26 17:56:55.000000000 -0400 |
4202 |
+@@ -352,8 +352,8 @@ unsigned int __cpuinit init_intel_cachei |
4203 |
+ */ |
4204 |
+ if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { |
4205 |
+ /* supports eax=2 call */ |
4206 |
+- int i, j, n; |
4207 |
+- int regs[4]; |
4208 |
++ int j, n; |
4209 |
++ unsigned int regs[4]; |
4210 |
+ unsigned char *dp = (unsigned char *)regs; |
4211 |
+ int only_trace = 0; |
4212 |
+ |
4213 |
+@@ -368,7 +368,7 @@ unsigned int __cpuinit init_intel_cachei |
4214 |
+ |
4215 |
+ /* If bit 31 is set, this is an unknown format */ |
4216 |
+ for ( j = 0 ; j < 3 ; j++ ) { |
4217 |
+- if ( regs[j] < 0 ) regs[j] = 0; |
4218 |
++ if ( (int)regs[j] < 0 ) regs[j] = 0; |
4219 |
+ } |
4220 |
+ |
4221 |
+ /* Byte 0 is level count, not a descriptor */ |
4222 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.24.4/arch/x86/kernel/cpu/mcheck/mce_64.c |
4223 |
+--- linux-2.6.24.4/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-03-24 14:49:18.000000000 -0400 |
4224 |
++++ linux-2.6.24.4/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-03-26 17:56:55.000000000 -0400 |
4225 |
+@@ -671,6 +671,7 @@ static struct miscdevice mce_log_device |
4226 |
+ MISC_MCELOG_MINOR, |
4227 |
+ "mcelog", |
4228 |
+ &mce_chrdev_ops, |
4229 |
++ {NULL, NULL}, NULL, NULL |
4230 |
+ }; |
4231 |
+ |
4232 |
+ static unsigned long old_cr4 __initdata; |
4233 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.24.4/arch/x86/kernel/cpu/mtrr/generic.c |
4234 |
+--- linux-2.6.24.4/arch/x86/kernel/cpu/mtrr/generic.c 2008-03-24 14:49:18.000000000 -0400 |
4235 |
++++ linux-2.6.24.4/arch/x86/kernel/cpu/mtrr/generic.c 2008-03-26 17:56:55.000000000 -0400 |
4236 |
+@@ -29,11 +29,11 @@ static struct fixed_range_block fixed_ra |
4237 |
+ { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */ |
4238 |
+ { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */ |
4239 |
+ { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */ |
4240 |
+- {} |
4241 |
++ { 0, 0 } |
4242 |
+ }; |
4243 |
+ |
4244 |
+ static unsigned long smp_changes_mask; |
4245 |
+-static struct mtrr_state mtrr_state = {}; |
4246 |
++static struct mtrr_state mtrr_state; |
4247 |
+ |
4248 |
+ #undef MODULE_PARAM_PREFIX |
4249 |
+ #define MODULE_PARAM_PREFIX "mtrr." |
4250 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/crash.c linux-2.6.24.4/arch/x86/kernel/crash.c |
4251 |
+--- linux-2.6.24.4/arch/x86/kernel/crash.c 2008-03-24 14:49:18.000000000 -0400 |
4252 |
++++ linux-2.6.24.4/arch/x86/kernel/crash.c 2008-03-26 17:56:55.000000000 -0400 |
4253 |
+@@ -62,7 +62,7 @@ static int crash_nmi_callback(struct not |
4254 |
+ local_irq_disable(); |
4255 |
+ |
4256 |
+ #ifdef CONFIG_X86_32 |
4257 |
+- if (!user_mode_vm(regs)) { |
4258 |
++ if (!user_mode(regs)) { |
4259 |
+ crash_fixup_ss_esp(&fixed_regs, regs); |
4260 |
+ regs = &fixed_regs; |
4261 |
+ } |
4262 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/doublefault_32.c linux-2.6.24.4/arch/x86/kernel/doublefault_32.c |
4263 |
+--- linux-2.6.24.4/arch/x86/kernel/doublefault_32.c 2008-03-24 14:49:18.000000000 -0400 |
4264 |
++++ linux-2.6.24.4/arch/x86/kernel/doublefault_32.c 2008-03-26 17:56:55.000000000 -0400 |
4265 |
+@@ -11,17 +11,17 @@ |
4266 |
+ |
4267 |
+ #define DOUBLEFAULT_STACKSIZE (1024) |
4268 |
+ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE]; |
4269 |
+-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE) |
4270 |
++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2) |
4271 |
+ |
4272 |
+ #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM) |
4273 |
+ |
4274 |
+ static void doublefault_fn(void) |
4275 |
+ { |
4276 |
+- struct Xgt_desc_struct gdt_desc = {0, 0}; |
4277 |
++ struct Xgt_desc_struct gdt_desc = {0, NULL, 0}; |
4278 |
+ unsigned long gdt, tss; |
4279 |
+ |
4280 |
+ store_gdt(&gdt_desc); |
4281 |
+- gdt = gdt_desc.address; |
4282 |
++ gdt = (unsigned long)gdt_desc.address; |
4283 |
+ |
4284 |
+ printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); |
4285 |
+ |
4286 |
+@@ -59,10 +59,10 @@ struct tss_struct doublefault_tss __cach |
4287 |
+ /* 0x2 bit is always set */ |
4288 |
+ .eflags = X86_EFLAGS_SF | 0x2, |
4289 |
+ .esp = STACK_START, |
4290 |
+- .es = __USER_DS, |
4291 |
++ .es = __KERNEL_DS, |
4292 |
+ .cs = __KERNEL_CS, |
4293 |
+ .ss = __KERNEL_DS, |
4294 |
+- .ds = __USER_DS, |
4295 |
++ .ds = __KERNEL_DS, |
4296 |
+ .fs = __KERNEL_PERCPU, |
4297 |
+ |
4298 |
+ .__cr3 = __pa(swapper_pg_dir) |
4299 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/efi_32.c linux-2.6.24.4/arch/x86/kernel/efi_32.c |
4300 |
+--- linux-2.6.24.4/arch/x86/kernel/efi_32.c 2008-03-24 14:49:18.000000000 -0400 |
4301 |
++++ linux-2.6.24.4/arch/x86/kernel/efi_32.c 2008-03-26 17:56:55.000000000 -0400 |
4302 |
+@@ -63,71 +63,38 @@ extern void * boot_ioremap(unsigned long |
4303 |
+ |
4304 |
+ static unsigned long efi_rt_eflags; |
4305 |
+ static DEFINE_SPINLOCK(efi_rt_lock); |
4306 |
+-static pgd_t efi_bak_pg_dir_pointer[2]; |
4307 |
++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096))); |
4308 |
+ |
4309 |
+-static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) |
4310 |
++static void __init efi_call_phys_prelog(void) __acquires(efi_rt_lock) |
4311 |
+ { |
4312 |
+- unsigned long cr4; |
4313 |
+- unsigned long temp; |
4314 |
+ struct Xgt_desc_struct gdt_descr; |
4315 |
+ |
4316 |
+ spin_lock(&efi_rt_lock); |
4317 |
+ local_irq_save(efi_rt_eflags); |
4318 |
+ |
4319 |
+- /* |
4320 |
+- * If I don't have PSE, I should just duplicate two entries in page |
4321 |
+- * directory. If I have PSE, I just need to duplicate one entry in |
4322 |
+- * page directory. |
4323 |
+- */ |
4324 |
+- cr4 = read_cr4(); |
4325 |
+- |
4326 |
+- if (cr4 & X86_CR4_PSE) { |
4327 |
+- efi_bak_pg_dir_pointer[0].pgd = |
4328 |
+- swapper_pg_dir[pgd_index(0)].pgd; |
4329 |
+- swapper_pg_dir[0].pgd = |
4330 |
+- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; |
4331 |
+- } else { |
4332 |
+- efi_bak_pg_dir_pointer[0].pgd = |
4333 |
+- swapper_pg_dir[pgd_index(0)].pgd; |
4334 |
+- efi_bak_pg_dir_pointer[1].pgd = |
4335 |
+- swapper_pg_dir[pgd_index(0x400000)].pgd; |
4336 |
+- swapper_pg_dir[pgd_index(0)].pgd = |
4337 |
+- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; |
4338 |
+- temp = PAGE_OFFSET + 0x400000; |
4339 |
+- swapper_pg_dir[pgd_index(0x400000)].pgd = |
4340 |
+- swapper_pg_dir[pgd_index(temp)].pgd; |
4341 |
+- } |
4342 |
++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS); |
4343 |
++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, |
4344 |
++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); |
4345 |
+ |
4346 |
+ /* |
4347 |
+ * After the lock is released, the original page table is restored. |
4348 |
+ */ |
4349 |
+ local_flush_tlb(); |
4350 |
+ |
4351 |
+- gdt_descr.address = __pa(get_cpu_gdt_table(0)); |
4352 |
++ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0)); |
4353 |
+ gdt_descr.size = GDT_SIZE - 1; |
4354 |
+ load_gdt(&gdt_descr); |
4355 |
+ } |
4356 |
+ |
4357 |
+-static void efi_call_phys_epilog(void) __releases(efi_rt_lock) |
4358 |
++static void __init efi_call_phys_epilog(void) __releases(efi_rt_lock) |
4359 |
+ { |
4360 |
+- unsigned long cr4; |
4361 |
+ struct Xgt_desc_struct gdt_descr; |
4362 |
+ |
4363 |
+- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); |
4364 |
++ gdt_descr.address = get_cpu_gdt_table(0); |
4365 |
+ gdt_descr.size = GDT_SIZE - 1; |
4366 |
+ load_gdt(&gdt_descr); |
4367 |
+ |
4368 |
+- cr4 = read_cr4(); |
4369 |
+- |
4370 |
+- if (cr4 & X86_CR4_PSE) { |
4371 |
+- swapper_pg_dir[pgd_index(0)].pgd = |
4372 |
+- efi_bak_pg_dir_pointer[0].pgd; |
4373 |
+- } else { |
4374 |
+- swapper_pg_dir[pgd_index(0)].pgd = |
4375 |
+- efi_bak_pg_dir_pointer[0].pgd; |
4376 |
+- swapper_pg_dir[pgd_index(0x400000)].pgd = |
4377 |
+- efi_bak_pg_dir_pointer[1].pgd; |
4378 |
+- } |
4379 |
++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS); |
4380 |
+ |
4381 |
+ /* |
4382 |
+ * After the lock is released, the original page table is restored. |
4383 |
+@@ -138,7 +105,7 @@ static void efi_call_phys_epilog(void) _ |
4384 |
+ spin_unlock(&efi_rt_lock); |
4385 |
+ } |
4386 |
+ |
4387 |
+-static efi_status_t |
4388 |
++static efi_status_t __init |
4389 |
+ phys_efi_set_virtual_address_map(unsigned long memory_map_size, |
4390 |
+ unsigned long descriptor_size, |
4391 |
+ u32 descriptor_version, |
4392 |
+@@ -154,7 +121,7 @@ phys_efi_set_virtual_address_map(unsigne |
4393 |
+ return status; |
4394 |
+ } |
4395 |
+ |
4396 |
+-static efi_status_t |
4397 |
++static noinline efi_status_t __init |
4398 |
+ phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) |
4399 |
+ { |
4400 |
+ efi_status_t status; |
4401 |
+@@ -198,7 +165,7 @@ inline int efi_set_rtc_mmss(unsigned lon |
4402 |
+ * services have been remapped and also during suspend, therefore, |
4403 |
+ * we'll need to call both in physical and virtual modes. |
4404 |
+ */ |
4405 |
+-inline unsigned long efi_get_time(void) |
4406 |
++unsigned long efi_get_time(void) |
4407 |
+ { |
4408 |
+ efi_status_t status; |
4409 |
+ efi_time_t eft; |
4410 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/efi_stub_32.S linux-2.6.24.4/arch/x86/kernel/efi_stub_32.S |
4411 |
+--- linux-2.6.24.4/arch/x86/kernel/efi_stub_32.S 2008-03-24 14:49:18.000000000 -0400 |
4412 |
++++ linux-2.6.24.4/arch/x86/kernel/efi_stub_32.S 2008-03-26 17:56:55.000000000 -0400 |
4413 |
+@@ -6,6 +6,7 @@ |
4414 |
+ */ |
4415 |
+ |
4416 |
+ #include <linux/linkage.h> |
4417 |
++#include <linux/init.h> |
4418 |
+ #include <asm/page.h> |
4419 |
+ |
4420 |
+ /* |
4421 |
+@@ -20,7 +21,7 @@ |
4422 |
+ * service functions will comply with gcc calling convention, too. |
4423 |
+ */ |
4424 |
+ |
4425 |
+-.text |
4426 |
++__INIT |
4427 |
+ ENTRY(efi_call_phys) |
4428 |
+ /* |
4429 |
+ * 0. The function can only be called in Linux kernel. So CS has been |
4430 |
+@@ -36,9 +37,7 @@ ENTRY(efi_call_phys) |
4431 |
+ * The mapping of lower virtual memory has been created in prelog and |
4432 |
+ * epilog. |
4433 |
+ */ |
4434 |
+- movl $1f, %edx |
4435 |
+- subl $__PAGE_OFFSET, %edx |
4436 |
+- jmp *%edx |
4437 |
++ jmp 1f-__PAGE_OFFSET |
4438 |
+ 1: |
4439 |
+ |
4440 |
+ /* |
4441 |
+@@ -47,14 +46,8 @@ ENTRY(efi_call_phys) |
4442 |
+ * parameter 2, ..., param n. To make things easy, we save the return |
4443 |
+ * address of efi_call_phys in a global variable. |
4444 |
+ */ |
4445 |
+- popl %edx |
4446 |
+- movl %edx, saved_return_addr |
4447 |
+- /* get the function pointer into ECX*/ |
4448 |
+- popl %ecx |
4449 |
+- movl %ecx, efi_rt_function_ptr |
4450 |
+- movl $2f, %edx |
4451 |
+- subl $__PAGE_OFFSET, %edx |
4452 |
+- pushl %edx |
4453 |
++ popl (saved_return_addr) |
4454 |
++ popl (efi_rt_function_ptr) |
4455 |
+ |
4456 |
+ /* |
4457 |
+ * 3. Clear PG bit in %CR0. |
4458 |
+@@ -73,9 +66,8 @@ ENTRY(efi_call_phys) |
4459 |
+ /* |
4460 |
+ * 5. Call the physical function. |
4461 |
+ */ |
4462 |
+- jmp *%ecx |
4463 |
++ call *(efi_rt_function_ptr-__PAGE_OFFSET) |
4464 |
+ |
4465 |
+-2: |
4466 |
+ /* |
4467 |
+ * 6. After EFI runtime service returns, control will return to |
4468 |
+ * following instruction. We'd better readjust stack pointer first. |
4469 |
+@@ -88,34 +80,27 @@ ENTRY(efi_call_phys) |
4470 |
+ movl %cr0, %edx |
4471 |
+ orl $0x80000000, %edx |
4472 |
+ movl %edx, %cr0 |
4473 |
+- jmp 1f |
4474 |
+-1: |
4475 |
++ |
4476 |
+ /* |
4477 |
+ * 8. Now restore the virtual mode from flat mode by |
4478 |
+ * adding EIP with PAGE_OFFSET. |
4479 |
+ */ |
4480 |
+- movl $1f, %edx |
4481 |
+- jmp *%edx |
4482 |
++ jmp 1f+__PAGE_OFFSET |
4483 |
+ 1: |
4484 |
+ |
4485 |
+ /* |
4486 |
+ * 9. Balance the stack. And because EAX contain the return value, |
4487 |
+ * we'd better not clobber it. |
4488 |
+ */ |
4489 |
+- leal efi_rt_function_ptr, %edx |
4490 |
+- movl (%edx), %ecx |
4491 |
+- pushl %ecx |
4492 |
++ pushl (efi_rt_function_ptr) |
4493 |
+ |
4494 |
+ /* |
4495 |
+- * 10. Push the saved return address onto the stack and return. |
4496 |
++ * 10. Return to the saved return address. |
4497 |
+ */ |
4498 |
+- leal saved_return_addr, %edx |
4499 |
+- movl (%edx), %ecx |
4500 |
+- pushl %ecx |
4501 |
+- ret |
4502 |
++ jmpl *(saved_return_addr) |
4503 |
+ .previous |
4504 |
+ |
4505 |
+-.data |
4506 |
++__INITDATA |
4507 |
+ saved_return_addr: |
4508 |
+ .long 0 |
4509 |
+ efi_rt_function_ptr: |
4510 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/entry_32.S linux-2.6.24.4/arch/x86/kernel/entry_32.S |
4511 |
+--- linux-2.6.24.4/arch/x86/kernel/entry_32.S 2008-03-24 14:49:18.000000000 -0400 |
4512 |
++++ linux-2.6.24.4/arch/x86/kernel/entry_32.S 2008-03-26 17:56:55.000000000 -0400 |
4513 |
+@@ -97,7 +97,7 @@ VM_MASK = 0x00020000 |
4514 |
+ #define resume_userspace_sig resume_userspace |
4515 |
+ #endif |
4516 |
+ |
4517 |
+-#define SAVE_ALL \ |
4518 |
++#define __SAVE_ALL(_DS) \ |
4519 |
+ cld; \ |
4520 |
+ pushl %fs; \ |
4521 |
+ CFI_ADJUST_CFA_OFFSET 4;\ |
4522 |
+@@ -129,12 +129,26 @@ VM_MASK = 0x00020000 |
4523 |
+ pushl %ebx; \ |
4524 |
+ CFI_ADJUST_CFA_OFFSET 4;\ |
4525 |
+ CFI_REL_OFFSET ebx, 0;\ |
4526 |
+- movl $(__USER_DS), %edx; \ |
4527 |
++ movl $(_DS), %edx; \ |
4528 |
+ movl %edx, %ds; \ |
4529 |
+ movl %edx, %es; \ |
4530 |
+ movl $(__KERNEL_PERCPU), %edx; \ |
4531 |
+ movl %edx, %fs |
4532 |
+ |
4533 |
++#ifdef CONFIG_PAX_KERNEXEC |
4534 |
++#define SAVE_ALL \ |
4535 |
++ __SAVE_ALL(__KERNEL_DS); \ |
4536 |
++ GET_CR0_INTO_EDX; \ |
4537 |
++ movl %edx, %esi; \ |
4538 |
++ orl $X86_CR0_WP, %edx; \ |
4539 |
++ xorl %edx, %esi; \ |
4540 |
++ SET_CR0_FROM_EDX |
4541 |
++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) |
4542 |
++#define SAVE_ALL __SAVE_ALL(__KERNEL_DS) |
4543 |
++#else |
4544 |
++#define SAVE_ALL __SAVE_ALL(__USER_DS) |
4545 |
++#endif |
4546 |
++ |
4547 |
+ #define RESTORE_INT_REGS \ |
4548 |
+ popl %ebx; \ |
4549 |
+ CFI_ADJUST_CFA_OFFSET -4;\ |
4550 |
+@@ -248,7 +262,17 @@ check_userspace: |
4551 |
+ movb PT_CS(%esp), %al |
4552 |
+ andl $(VM_MASK | SEGMENT_RPL_MASK), %eax |
4553 |
+ cmpl $USER_RPL, %eax |
4554 |
++ |
4555 |
++#ifdef CONFIG_PAX_KERNEXEC |
4556 |
++ jae resume_userspace |
4557 |
++ |
4558 |
++ GET_CR0_INTO_EDX |
4559 |
++ xorl %esi, %edx |
4560 |
++ SET_CR0_FROM_EDX |
4561 |
++ jmp resume_kernel |
4562 |
++#else |
4563 |
+ jb resume_kernel # not returning to v8086 or userspace |
4564 |
++#endif |
4565 |
+ |
4566 |
+ ENTRY(resume_userspace) |
4567 |
+ LOCKDEP_SYS_EXIT |
4568 |
+@@ -308,10 +332,9 @@ sysenter_past_esp: |
4569 |
+ /*CFI_REL_OFFSET cs, 0*/ |
4570 |
+ /* |
4571 |
+ * Push current_thread_info()->sysenter_return to the stack. |
4572 |
+- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words |
4573 |
+- * pushed above; +8 corresponds to copy_thread's esp0 setting. |
4574 |
+ */ |
4575 |
+- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) |
4576 |
++ GET_THREAD_INFO(%ebp) |
4577 |
++ pushl TI_sysenter_return(%ebp) |
4578 |
+ CFI_ADJUST_CFA_OFFSET 4 |
4579 |
+ CFI_REL_OFFSET eip, 0 |
4580 |
+ |
4581 |
+@@ -319,9 +342,17 @@ sysenter_past_esp: |
4582 |
+ * Load the potential sixth argument from user stack. |
4583 |
+ * Careful about security. |
4584 |
+ */ |
4585 |
++ movl 12(%esp),%ebp |
4586 |
++ |
4587 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
4588 |
++ mov 16(%esp),%ds |
4589 |
++1: movl %ds:(%ebp),%ebp |
4590 |
++#else |
4591 |
+ cmpl $__PAGE_OFFSET-3,%ebp |
4592 |
+ jae syscall_fault |
4593 |
+ 1: movl (%ebp),%ebp |
4594 |
++#endif |
4595 |
++ |
4596 |
+ .section __ex_table,"a" |
4597 |
+ .align 4 |
4598 |
+ .long 1b,syscall_fault |
4599 |
+@@ -345,20 +376,37 @@ sysenter_past_esp: |
4600 |
+ movl TI_flags(%ebp), %ecx |
4601 |
+ testw $_TIF_ALLWORK_MASK, %cx |
4602 |
+ jne syscall_exit_work |
4603 |
++ |
4604 |
++#ifdef CONFIG_PAX_RANDKSTACK |
4605 |
++ pushl %eax |
4606 |
++ CFI_ADJUST_CFA_OFFSET 4 |
4607 |
++ call pax_randomize_kstack |
4608 |
++ popl %eax |
4609 |
++ CFI_ADJUST_CFA_OFFSET -4 |
4610 |
++#endif |
4611 |
++ |
4612 |
+ /* if something modifies registers it must also disable sysexit */ |
4613 |
+ movl PT_EIP(%esp), %edx |
4614 |
+ movl PT_OLDESP(%esp), %ecx |
4615 |
+ xorl %ebp,%ebp |
4616 |
+ TRACE_IRQS_ON |
4617 |
+ 1: mov PT_FS(%esp), %fs |
4618 |
++2: mov PT_DS(%esp), %ds |
4619 |
++3: mov PT_ES(%esp), %es |
4620 |
+ ENABLE_INTERRUPTS_SYSEXIT |
4621 |
+ CFI_ENDPROC |
4622 |
+ .pushsection .fixup,"ax" |
4623 |
+-2: movl $0,PT_FS(%esp) |
4624 |
++4: movl $0,PT_FS(%esp) |
4625 |
+ jmp 1b |
4626 |
++5: movl $0,PT_DS(%esp) |
4627 |
++ jmp 2b |
4628 |
++6: movl $0,PT_ES(%esp) |
4629 |
++ jmp 3b |
4630 |
+ .section __ex_table,"a" |
4631 |
+ .align 4 |
4632 |
+- .long 1b,2b |
4633 |
++ .long 1b,4b |
4634 |
++ .long 2b,5b |
4635 |
++ .long 3b,6b |
4636 |
+ .popsection |
4637 |
+ ENDPROC(sysenter_entry) |
4638 |
+ |
4639 |
+@@ -392,6 +440,10 @@ no_singlestep: |
4640 |
+ testw $_TIF_ALLWORK_MASK, %cx # current->work |
4641 |
+ jne syscall_exit_work |
4642 |
+ |
4643 |
++#ifdef CONFIG_PAX_RANDKSTACK |
4644 |
++ call pax_randomize_kstack |
4645 |
++#endif |
4646 |
++ |
4647 |
+ restore_all: |
4648 |
+ movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS |
4649 |
+ # Warning: PT_OLDSS(%esp) contains the wrong/random values if we |
4650 |
+@@ -556,17 +608,24 @@ syscall_badsys: |
4651 |
+ END(syscall_badsys) |
4652 |
+ CFI_ENDPROC |
4653 |
+ |
4654 |
+-#define FIXUP_ESPFIX_STACK \ |
4655 |
+- /* since we are on a wrong stack, we cant make it a C code :( */ \ |
4656 |
+- PER_CPU(gdt_page, %ebx); \ |
4657 |
+- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ |
4658 |
+- addl %esp, %eax; \ |
4659 |
+- pushl $__KERNEL_DS; \ |
4660 |
+- CFI_ADJUST_CFA_OFFSET 4; \ |
4661 |
+- pushl %eax; \ |
4662 |
+- CFI_ADJUST_CFA_OFFSET 4; \ |
4663 |
+- lss (%esp), %esp; \ |
4664 |
++.macro FIXUP_ESPFIX_STACK |
4665 |
++ /* since we are on a wrong stack, we cant make it a C code :( */ |
4666 |
++#ifdef CONFIG_SMP |
4667 |
++ movl PER_CPU_VAR(cpu_number), %ebx; |
4668 |
++ shll $PAGE_SHIFT_asm, %ebx; |
4669 |
++ addl $cpu_gdt_table, %ebx; |
4670 |
++#else |
4671 |
++ movl $cpu_gdt_table, %ebx; |
4672 |
++#endif |
4673 |
++ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); |
4674 |
++ addl %esp, %eax; |
4675 |
++ pushl $__KERNEL_DS; |
4676 |
++ CFI_ADJUST_CFA_OFFSET 4; |
4677 |
++ pushl %eax; |
4678 |
++ CFI_ADJUST_CFA_OFFSET 4; |
4679 |
++ lss (%esp), %esp; |
4680 |
+ CFI_ADJUST_CFA_OFFSET -8; |
4681 |
++.endm |
4682 |
+ #define UNWIND_ESPFIX_STACK \ |
4683 |
+ movl %ss, %eax; \ |
4684 |
+ /* see if on espfix stack */ \ |
4685 |
+@@ -583,7 +642,7 @@ END(syscall_badsys) |
4686 |
+ * Build the entry stubs and pointer table with |
4687 |
+ * some assembler magic. |
4688 |
+ */ |
4689 |
+-.data |
4690 |
++.section .rodata,"a",@progbits |
4691 |
+ ENTRY(interrupt) |
4692 |
+ .text |
4693 |
+ |
4694 |
+@@ -683,12 +742,21 @@ error_code: |
4695 |
+ popl %ecx |
4696 |
+ CFI_ADJUST_CFA_OFFSET -4 |
4697 |
+ /*CFI_REGISTER es, ecx*/ |
4698 |
++ |
4699 |
++#ifdef CONFIG_PAX_KERNEXEC |
4700 |
++ GET_CR0_INTO_EDX |
4701 |
++ movl %edx, %esi |
4702 |
++ orl $X86_CR0_WP, %edx |
4703 |
++ xorl %edx, %esi |
4704 |
++ SET_CR0_FROM_EDX |
4705 |
++#endif |
4706 |
++ |
4707 |
+ movl PT_FS(%esp), %edi # get the function address |
4708 |
+ movl PT_ORIG_EAX(%esp), %edx # get the error code |
4709 |
+ movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart |
4710 |
+ mov %ecx, PT_FS(%esp) |
4711 |
+ /*CFI_REL_OFFSET fs, ES*/ |
4712 |
+- movl $(__USER_DS), %ecx |
4713 |
++ movl $(__KERNEL_DS), %ecx |
4714 |
+ movl %ecx, %ds |
4715 |
+ movl %ecx, %es |
4716 |
+ movl %esp,%eax # pt_regs pointer |
4717 |
+@@ -822,6 +890,13 @@ nmi_stack_correct: |
4718 |
+ xorl %edx,%edx # zero error code |
4719 |
+ movl %esp,%eax # pt_regs pointer |
4720 |
+ call do_nmi |
4721 |
++ |
4722 |
++#ifdef CONFIG_PAX_KERNEXEC |
4723 |
++ GET_CR0_INTO_EDX |
4724 |
++ xorl %esi, %edx |
4725 |
++ SET_CR0_FROM_EDX |
4726 |
++#endif |
4727 |
++ |
4728 |
+ jmp restore_nocheck_notrace |
4729 |
+ CFI_ENDPROC |
4730 |
+ |
4731 |
+@@ -862,6 +937,13 @@ nmi_espfix_stack: |
4732 |
+ FIXUP_ESPFIX_STACK # %eax == %esp |
4733 |
+ xorl %edx,%edx # zero error code |
4734 |
+ call do_nmi |
4735 |
++ |
4736 |
++#ifdef CONFIG_PAX_KERNEXEC |
4737 |
++ GET_CR0_INTO_EDX |
4738 |
++ xorl %esi, %edx |
4739 |
++ SET_CR0_FROM_EDX |
4740 |
++#endif |
4741 |
++ |
4742 |
+ RESTORE_REGS |
4743 |
+ lss 12+4(%esp), %esp # back to espfix stack |
4744 |
+ CFI_ADJUST_CFA_OFFSET -24 |
4745 |
+@@ -1110,7 +1192,6 @@ ENDPROC(xen_failsafe_callback) |
4746 |
+ |
4747 |
+ #endif /* CONFIG_XEN */ |
4748 |
+ |
4749 |
+-.section .rodata,"a" |
4750 |
+ #include "syscall_table_32.S" |
4751 |
+ |
4752 |
+ syscall_table_size=(.-sys_call_table) |
4753 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/entry_64.S linux-2.6.24.4/arch/x86/kernel/entry_64.S |
4754 |
+--- linux-2.6.24.4/arch/x86/kernel/entry_64.S 2008-03-24 14:49:18.000000000 -0400 |
4755 |
++++ linux-2.6.24.4/arch/x86/kernel/entry_64.S 2008-03-26 17:56:55.000000000 -0400 |
4756 |
+@@ -440,6 +440,7 @@ ENTRY(stub_execve) |
4757 |
+ CFI_REGISTER rip, r11 |
4758 |
+ SAVE_REST |
4759 |
+ FIXUP_TOP_OF_STACK %r11 |
4760 |
++ movq %rsp, %rcx |
4761 |
+ call sys_execve |
4762 |
+ RESTORE_TOP_OF_STACK %r11 |
4763 |
+ movq %rax,RAX(%rsp) |
4764 |
+@@ -735,17 +736,18 @@ END(spurious_interrupt) |
4765 |
+ xorl %ebx,%ebx |
4766 |
+ 1: |
4767 |
+ .if \ist |
4768 |
+- movq %gs:pda_data_offset, %rbp |
4769 |
++ imul $TSS_size, %gs:pda_cpunumber, %ebp |
4770 |
++ lea init_tss(%rbp), %rbp |
4771 |
+ .endif |
4772 |
+ movq %rsp,%rdi |
4773 |
+ movq ORIG_RAX(%rsp),%rsi |
4774 |
+ movq $-1,ORIG_RAX(%rsp) |
4775 |
+ .if \ist |
4776 |
+- subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) |
4777 |
++ subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) |
4778 |
+ .endif |
4779 |
+ call \sym |
4780 |
+ .if \ist |
4781 |
+- addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) |
4782 |
++ addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) |
4783 |
+ .endif |
4784 |
+ cli |
4785 |
+ .if \irqtrace |
4786 |
+@@ -1003,15 +1005,16 @@ ENDPROC(child_rip) |
4787 |
+ * rdi: name, rsi: argv, rdx: envp |
4788 |
+ * |
4789 |
+ * We want to fallback into: |
4790 |
+- * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs) |
4791 |
++ * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs) |
4792 |
+ * |
4793 |
+ * do_sys_execve asm fallback arguments: |
4794 |
+- * rdi: name, rsi: argv, rdx: envp, fake frame on the stack |
4795 |
++ * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack |
4796 |
+ */ |
4797 |
+ ENTRY(kernel_execve) |
4798 |
+ CFI_STARTPROC |
4799 |
+ FAKE_STACK_FRAME $0 |
4800 |
+ SAVE_ALL |
4801 |
++ movq %rsp,%rcx |
4802 |
+ call sys_execve |
4803 |
+ movq %rax, RAX(%rsp) |
4804 |
+ RESTORE_REST |
4805 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/head_32.S linux-2.6.24.4/arch/x86/kernel/head_32.S |
4806 |
+--- linux-2.6.24.4/arch/x86/kernel/head_32.S 2008-03-24 14:49:18.000000000 -0400 |
4807 |
++++ linux-2.6.24.4/arch/x86/kernel/head_32.S 2008-03-26 17:56:55.000000000 -0400 |
4808 |
+@@ -18,6 +18,7 @@ |
4809 |
+ #include <asm/thread_info.h> |
4810 |
+ #include <asm/asm-offsets.h> |
4811 |
+ #include <asm/setup.h> |
4812 |
++#include <asm/msr-index.h> |
4813 |
+ |
4814 |
+ /* |
4815 |
+ * References to members of the new_cpu_data structure. |
4816 |
+@@ -60,17 +61,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm) |
4817 |
+ LOW_PAGES = LOW_PAGES + 0x1000000 |
4818 |
+ #endif |
4819 |
+ |
4820 |
+-#if PTRS_PER_PMD > 1 |
4821 |
+-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD |
4822 |
+-#else |
4823 |
+-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD) |
4824 |
+-#endif |
4825 |
++PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE) |
4826 |
+ BOOTBITMAP_SIZE = LOW_PAGES / 8 |
4827 |
+ ALLOCATOR_SLOP = 4 |
4828 |
+ |
4829 |
+ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm |
4830 |
+ |
4831 |
+ /* |
4832 |
++ * Real beginning of normal "text" segment |
4833 |
++ */ |
4834 |
++ENTRY(stext) |
4835 |
++ENTRY(_stext) |
4836 |
++ |
4837 |
++.section .text.startup,"ax",@progbits |
4838 |
++ ljmp $(__BOOT_CS),$phys_startup_32 |
4839 |
++ |
4840 |
++/* |
4841 |
+ * 32-bit kernel entrypoint; only used by the boot CPU. On entry, |
4842 |
+ * %esi points to the real-mode code as a 32-bit pointer. |
4843 |
+ * CS and DS must be 4 GB flat segments, but we don't depend on |
4844 |
+@@ -78,6 +84,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + |
4845 |
+ * can. |
4846 |
+ */ |
4847 |
+ .section .text.head,"ax",@progbits |
4848 |
++ |
4849 |
++#ifdef CONFIG_PAX_KERNEXEC |
4850 |
++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */ |
4851 |
++.fill 4096,1,0xcc |
4852 |
++#endif |
4853 |
++ |
4854 |
+ ENTRY(startup_32) |
4855 |
+ /* check to see if KEEP_SEGMENTS flag is meaningful */ |
4856 |
+ cmpw $0x207, BP_version(%esi) |
4857 |
+@@ -99,6 +111,43 @@ ENTRY(startup_32) |
4858 |
+ movl %eax,%gs |
4859 |
+ 2: |
4860 |
+ |
4861 |
++ movl $__per_cpu_start,%eax |
4862 |
++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2) |
4863 |
++ rorl $16,%eax |
4864 |
++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4) |
4865 |
++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7) |
4866 |
++ movl $__per_cpu_end + PERCPU_MODULE_RESERVE,%eax |
4867 |
++ subl $__per_cpu_start,%eax |
4868 |
++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0) |
4869 |
++ |
4870 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
4871 |
++ /* check for VMware */ |
4872 |
++ movl $0x564d5868,%eax |
4873 |
++ xorl %ebx,%ebx |
4874 |
++ movl $0xa,%ecx |
4875 |
++ movl $0x5658,%edx |
4876 |
++ in (%dx),%eax |
4877 |
++ cmpl $0x564d5868,%ebx |
4878 |
++ jz 1f |
4879 |
++ |
4880 |
++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax |
4881 |
++ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4) |
4882 |
++1: |
4883 |
++#endif |
4884 |
++ |
4885 |
++#ifdef CONFIG_PAX_KERNEXEC |
4886 |
++ movl $KERNEL_TEXT_OFFSET,%eax |
4887 |
++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2) |
4888 |
++ rorl $16,%eax |
4889 |
++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4) |
4890 |
++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7) |
4891 |
++ |
4892 |
++ movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4) |
4893 |
++ movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7) |
4894 |
++ rorl $16,%eax |
4895 |
++ movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2) |
4896 |
++#endif |
4897 |
++ |
4898 |
+ /* |
4899 |
+ * Clear BSS first so that there are no surprises... |
4900 |
+ */ |
4901 |
+@@ -141,9 +190,7 @@ ENTRY(startup_32) |
4902 |
+ cmpl $num_subarch_entries, %eax |
4903 |
+ jae bad_subarch |
4904 |
+ |
4905 |
+- movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax |
4906 |
+- subl $__PAGE_OFFSET, %eax |
4907 |
+- jmp *%eax |
4908 |
++ jmp *(subarch_entries - __PAGE_OFFSET)(,%eax,4) |
4909 |
+ |
4910 |
+ bad_subarch: |
4911 |
+ WEAK(lguest_entry) |
4912 |
+@@ -151,11 +198,11 @@ WEAK(xen_entry) |
4913 |
+ /* Unknown implementation; there's really |
4914 |
+ nothing we can do at this point. */ |
4915 |
+ ud2a |
4916 |
+-.data |
4917 |
++.section .rodata,"a",@progbits |
4918 |
+ subarch_entries: |
4919 |
+- .long default_entry /* normal x86/PC */ |
4920 |
+- .long lguest_entry /* lguest hypervisor */ |
4921 |
+- .long xen_entry /* Xen hypervisor */ |
4922 |
++ .long default_entry - __PAGE_OFFSET /* normal x86/PC */ |
4923 |
++ .long lguest_entry - __PAGE_OFFSET /* lguest hypervisor */ |
4924 |
++ .long xen_entry - __PAGE_OFFSET /* Xen hypervisor */ |
4925 |
+ num_subarch_entries = (. - subarch_entries) / 4 |
4926 |
+ .previous |
4927 |
+ #endif /* CONFIG_PARAVIRT */ |
4928 |
+@@ -170,34 +217,55 @@ num_subarch_entries = (. - subarch_entri |
4929 |
+ * Warning: don't use %esi or the stack in this code. However, %esp |
4930 |
+ * can be used as a GPR if you really need it... |
4931 |
+ */ |
4932 |
+-page_pde_offset = (__PAGE_OFFSET >> 20); |
4933 |
++#ifdef CONFIG_X86_PAE |
4934 |
++page_pde_offset = ((__PAGE_OFFSET >> 21) * (PAGE_SIZE_asm / PTRS_PER_PTE)); |
4935 |
++#else |
4936 |
++page_pde_offset = ((__PAGE_OFFSET >> 22) * (PAGE_SIZE_asm / PTRS_PER_PTE)); |
4937 |
++#endif |
4938 |
+ |
4939 |
+ default_entry: |
4940 |
+ movl $(pg0 - __PAGE_OFFSET), %edi |
4941 |
++#ifdef CONFIG_X86_PAE |
4942 |
++ movl $(swapper_pm_dir - __PAGE_OFFSET), %edx |
4943 |
++#else |
4944 |
+ movl $(swapper_pg_dir - __PAGE_OFFSET), %edx |
4945 |
+- movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ |
4946 |
++#endif |
4947 |
++ movl $0x063, %eax /* 0x063 = PRESENT+RW+ACCESSED+DIRTY */ |
4948 |
+ 10: |
4949 |
+- leal 0x007(%edi),%ecx /* Create PDE entry */ |
4950 |
++ leal 0x063(%edi),%ecx /* Create PDE entry */ |
4951 |
+ movl %ecx,(%edx) /* Store identity PDE entry */ |
4952 |
+ movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */ |
4953 |
++#ifdef CONFIG_X86_PAE |
4954 |
++ movl $0,4(%edx) |
4955 |
++ movl $0,page_pde_offset+4(%edx) |
4956 |
++ addl $8,%edx |
4957 |
++ movl $512, %ecx |
4958 |
++#else |
4959 |
+ addl $4,%edx |
4960 |
+ movl $1024, %ecx |
4961 |
++#endif |
4962 |
+ 11: |
4963 |
+ stosl |
4964 |
++#ifdef CONFIG_X86_PAE |
4965 |
++ movl $0,(%edi) |
4966 |
++ addl $4,%edi |
4967 |
++#endif |
4968 |
+ addl $0x1000,%eax |
4969 |
+ loop 11b |
4970 |
+ /* End condition: we must map up to and including INIT_MAP_BEYOND_END */ |
4971 |
+- /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */ |
4972 |
+- leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp |
4973 |
++ /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */ |
4974 |
++ leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp |
4975 |
+ cmpl %ebp,%eax |
4976 |
+ jb 10b |
4977 |
+ movl %edi,(init_pg_tables_end - __PAGE_OFFSET) |
4978 |
+ |
4979 |
+ /* Do an early initialization of the fixmap area */ |
4980 |
+- movl $(swapper_pg_dir - __PAGE_OFFSET), %edx |
4981 |
+- movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax |
4982 |
+- addl $0x67, %eax /* 0x67 == _PAGE_TABLE */ |
4983 |
+- movl %eax, 4092(%edx) |
4984 |
++ /* 0x067 = PRESENT+RW+USER+ACCESSED+DIRTY */ |
4985 |
++#ifdef CONFIG_X86_PAE |
4986 |
++ movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pm_dir - __PAGE_OFFSET + 4096 - 8) |
4987 |
++#else |
4988 |
++ movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pg_dir - __PAGE_OFFSET + 4096 - 4) |
4989 |
++#endif |
4990 |
+ |
4991 |
+ xorl %ebx,%ebx /* This is the boot CPU (BSP) */ |
4992 |
+ jmp 3f |
4993 |
+@@ -223,6 +291,11 @@ ENTRY(startup_32_smp) |
4994 |
+ movl %eax,%fs |
4995 |
+ movl %eax,%gs |
4996 |
+ |
4997 |
++ /* This is a secondary processor (AP) */ |
4998 |
++ xorl %ebx,%ebx |
4999 |
++ incl %ebx |
5000 |
++#endif /* CONFIG_SMP */ |
5001 |
++ |
5002 |
+ /* |
5003 |
+ * New page tables may be in 4Mbyte page mode and may |
5004 |
+ * be using the global pages. |
5005 |
+@@ -238,42 +311,47 @@ ENTRY(startup_32_smp) |
5006 |
+ * not yet offset PAGE_OFFSET.. |
5007 |
+ */ |
5008 |
+ #define cr4_bits mmu_cr4_features-__PAGE_OFFSET |
5009 |
++3: |
5010 |
+ movl cr4_bits,%edx |
5011 |
+ andl %edx,%edx |
5012 |
+- jz 6f |
5013 |
++ jz 5f |
5014 |
+ movl %cr4,%eax # Turn on paging options (PSE,PAE,..) |
5015 |
+ orl %edx,%eax |
5016 |
+ movl %eax,%cr4 |
5017 |
+ |
5018 |
+- btl $5, %eax # check if PAE is enabled |
5019 |
+- jnc 6f |
5020 |
++#ifdef CONFIG_X86_PAE |
5021 |
++ movl %ebx,%edi |
5022 |
+ |
5023 |
+ /* Check if extended functions are implemented */ |
5024 |
+ movl $0x80000000, %eax |
5025 |
+ cpuid |
5026 |
+ cmpl $0x80000000, %eax |
5027 |
+- jbe 6f |
5028 |
++ jbe 4f |
5029 |
+ mov $0x80000001, %eax |
5030 |
+ cpuid |
5031 |
+ /* Execute Disable bit supported? */ |
5032 |
+ btl $20, %edx |
5033 |
+- jnc 6f |
5034 |
++ jnc 4f |
5035 |
+ |
5036 |
+ /* Setup EFER (Extended Feature Enable Register) */ |
5037 |
+- movl $0xc0000080, %ecx |
5038 |
++ movl $MSR_EFER, %ecx |
5039 |
+ rdmsr |
5040 |
+ |
5041 |
+ btsl $11, %eax |
5042 |
+ /* Make changes effective */ |
5043 |
+ wrmsr |
5044 |
+ |
5045 |
+-6: |
5046 |
+- /* This is a secondary processor (AP) */ |
5047 |
+- xorl %ebx,%ebx |
5048 |
+- incl %ebx |
5049 |
++ btsl $63-32,__supported_pte_mask+4-__PAGE_OFFSET |
5050 |
++ movl $1,nx_enabled-__PAGE_OFFSET |
5051 |
+ |
5052 |
+-#endif /* CONFIG_SMP */ |
5053 |
+-3: |
5054 |
++#if !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF) |
5055 |
++ movl $0,disable_x86_sep-__PAGE_OFFSET |
5056 |
++#endif |
5057 |
++ |
5058 |
++4: |
5059 |
++ movl %edi,%ebx |
5060 |
++#endif |
5061 |
++5: |
5062 |
+ |
5063 |
+ /* |
5064 |
+ * Enable paging |
5065 |
+@@ -298,9 +376,7 @@ ENTRY(startup_32_smp) |
5066 |
+ |
5067 |
+ #ifdef CONFIG_SMP |
5068 |
+ andl %ebx,%ebx |
5069 |
+- jz 1f /* Initial CPU cleans BSS */ |
5070 |
+- jmp checkCPUtype |
5071 |
+-1: |
5072 |
++ jnz checkCPUtype /* Initial CPU cleans BSS */ |
5073 |
+ #endif /* CONFIG_SMP */ |
5074 |
+ |
5075 |
+ /* |
5076 |
+@@ -377,12 +453,12 @@ is386: movl $2,%ecx # set MP |
5077 |
+ ljmp $(__KERNEL_CS),$1f |
5078 |
+ 1: movl $(__KERNEL_DS),%eax # reload all the segment registers |
5079 |
+ movl %eax,%ss # after changing gdt. |
5080 |
+- movl %eax,%fs # gets reset once there's real percpu |
5081 |
+- |
5082 |
+- movl $(__USER_DS),%eax # DS/ES contains default USER segment |
5083 |
+ movl %eax,%ds |
5084 |
+ movl %eax,%es |
5085 |
+ |
5086 |
++ movl $(__KERNEL_PERCPU), %eax |
5087 |
++ movl %eax,%fs # set this cpu's percpu |
5088 |
++ |
5089 |
+ xorl %eax,%eax # Clear GS and LDT |
5090 |
+ movl %eax,%gs |
5091 |
+ lldt %ax |
5092 |
+@@ -393,11 +469,7 @@ is386: movl $2,%ecx # set MP |
5093 |
+ movb ready, %cl |
5094 |
+ movb $1, ready |
5095 |
+ cmpb $0,%cl # the first CPU calls start_kernel |
5096 |
+- je 1f |
5097 |
+- movl $(__KERNEL_PERCPU), %eax |
5098 |
+- movl %eax,%fs # set this cpu's percpu |
5099 |
+- jmp initialize_secondary # all other CPUs call initialize_secondary |
5100 |
+-1: |
5101 |
++ jne initialize_secondary # all other CPUs call initialize_secondary |
5102 |
+ #endif /* CONFIG_SMP */ |
5103 |
+ jmp start_kernel |
5104 |
+ |
5105 |
+@@ -483,8 +555,8 @@ early_page_fault: |
5106 |
+ jmp early_fault |
5107 |
+ |
5108 |
+ early_fault: |
5109 |
+- cld |
5110 |
+ #ifdef CONFIG_PRINTK |
5111 |
++ cld |
5112 |
+ pusha |
5113 |
+ movl $(__KERNEL_DS),%eax |
5114 |
+ movl %eax,%ds |
5115 |
+@@ -509,8 +581,8 @@ hlt_loop: |
5116 |
+ /* This is the default interrupt "handler" :-) */ |
5117 |
+ ALIGN |
5118 |
+ ignore_int: |
5119 |
+- cld |
5120 |
+ #ifdef CONFIG_PRINTK |
5121 |
++ cld |
5122 |
+ pushl %eax |
5123 |
+ pushl %ecx |
5124 |
+ pushl %edx |
5125 |
+@@ -541,31 +613,58 @@ ignore_int: |
5126 |
+ #endif |
5127 |
+ iret |
5128 |
+ |
5129 |
+-.section .text |
5130 |
+-/* |
5131 |
+- * Real beginning of normal "text" segment |
5132 |
+- */ |
5133 |
+-ENTRY(stext) |
5134 |
+-ENTRY(_stext) |
5135 |
+- |
5136 |
+ /* |
5137 |
+ * BSS section |
5138 |
+ */ |
5139 |
+-.section ".bss.page_aligned","wa" |
5140 |
++.section .swapper_pg_dir,"a",@progbits |
5141 |
+ .align PAGE_SIZE_asm |
5142 |
+ ENTRY(swapper_pg_dir) |
5143 |
++#ifdef CONFIG_X86_PAE |
5144 |
++ .long swapper_pm_dir-__PAGE_OFFSET+1 |
5145 |
++ .long 0 |
5146 |
++ .long swapper_pm_dir+512*8-__PAGE_OFFSET+1 |
5147 |
++ .long 0 |
5148 |
++ .long swapper_pm_dir+512*16-__PAGE_OFFSET+1 |
5149 |
++ .long 0 |
5150 |
++ .long swapper_pm_dir+512*24-__PAGE_OFFSET+1 |
5151 |
++ .long 0 |
5152 |
++#else |
5153 |
+ .fill 1024,4,0 |
5154 |
++#endif |
5155 |
++ |
5156 |
++.section .swapper_pm_dir,"a",@progbits |
5157 |
++#ifdef CONFIG_X86_PAE |
5158 |
++ENTRY(swapper_pm_dir) |
5159 |
++ .fill 512,8,0 |
5160 |
++ .fill 512,8,0 |
5161 |
++ .fill 512,8,0 |
5162 |
++ .fill 512,8,0 |
5163 |
++#endif |
5164 |
++ |
5165 |
+ ENTRY(swapper_pg_pmd) |
5166 |
+ .fill 1024,4,0 |
5167 |
++ |
5168 |
++.section .empty_zero_page,"a",@progbits |
5169 |
+ ENTRY(empty_zero_page) |
5170 |
+ .fill 4096,1,0 |
5171 |
+ |
5172 |
+ /* |
5173 |
++ * The IDT has to be page-aligned to simplify the Pentium |
5174 |
++ * F0 0F bug workaround.. We have a special link segment |
5175 |
++ * for this. |
5176 |
++ */ |
5177 |
++.section .idt,"a",@progbits |
5178 |
++ENTRY(idt_table) |
5179 |
++ .fill 256,8,0 |
5180 |
++ |
5181 |
++/* |
5182 |
+ * This starts the data section. |
5183 |
+ */ |
5184 |
+ .data |
5185 |
++ |
5186 |
++.section .rodata,"a",@progbits |
5187 |
+ ENTRY(stack_start) |
5188 |
+- .long init_thread_union+THREAD_SIZE |
5189 |
++ .long init_thread_union+THREAD_SIZE-8 |
5190 |
+ .long __BOOT_DS |
5191 |
+ |
5192 |
+ ready: .byte 0 |
5193 |
+@@ -615,7 +714,7 @@ idt_descr: |
5194 |
+ .word 0 # 32 bit align gdt_desc.address |
5195 |
+ ENTRY(early_gdt_descr) |
5196 |
+ .word GDT_ENTRIES*8-1 |
5197 |
+- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */ |
5198 |
++ .long cpu_gdt_table /* Overwritten for secondary CPUs */ |
5199 |
+ |
5200 |
+ /* |
5201 |
+ * The boot_gdt must mirror the equivalent in setup.S and is |
5202 |
+@@ -624,5 +723,61 @@ ENTRY(early_gdt_descr) |
5203 |
+ .align L1_CACHE_BYTES |
5204 |
+ ENTRY(boot_gdt) |
5205 |
+ .fill GDT_ENTRY_BOOT_CS,8,0 |
5206 |
+- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ |
5207 |
+- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ |
5208 |
++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */ |
5209 |
++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */ |
5210 |
++ |
5211 |
++ .align PAGE_SIZE_asm |
5212 |
++ENTRY(cpu_gdt_table) |
5213 |
++ .quad 0x0000000000000000 /* NULL descriptor */ |
5214 |
++ .quad 0x0000000000000000 /* 0x0b reserved */ |
5215 |
++ .quad 0x0000000000000000 /* 0x13 reserved */ |
5216 |
++ .quad 0x0000000000000000 /* 0x1b reserved */ |
5217 |
++ .quad 0x0000000000000000 /* 0x20 unused */ |
5218 |
++ .quad 0x0000000000000000 /* 0x28 unused */ |
5219 |
++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */ |
5220 |
++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */ |
5221 |
++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */ |
5222 |
++ .quad 0x0000000000000000 /* 0x4b reserved */ |
5223 |
++ .quad 0x0000000000000000 /* 0x53 reserved */ |
5224 |
++ .quad 0x0000000000000000 /* 0x5b reserved */ |
5225 |
++ |
5226 |
++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */ |
5227 |
++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */ |
5228 |
++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */ |
5229 |
++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */ |
5230 |
++ |
5231 |
++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */ |
5232 |
++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */ |
5233 |
++ |
5234 |
++ /* |
5235 |
++ * Segments used for calling PnP BIOS have byte granularity. |
5236 |
++ * The code segments and data segments have fixed 64k limits, |
5237 |
++ * the transfer segment sizes are set at run time. |
5238 |
++ */ |
5239 |
++ .quad 0x00409b000000ffff /* 0x90 32-bit code */ |
5240 |
++ .quad 0x00009b000000ffff /* 0x98 16-bit code */ |
5241 |
++ .quad 0x000093000000ffff /* 0xa0 16-bit data */ |
5242 |
++ .quad 0x0000930000000000 /* 0xa8 16-bit data */ |
5243 |
++ .quad 0x0000930000000000 /* 0xb0 16-bit data */ |
5244 |
++ |
5245 |
++ /* |
5246 |
++ * The APM segments have byte granularity and their bases |
5247 |
++ * are set at run time. All have 64k limits. |
5248 |
++ */ |
5249 |
++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */ |
5250 |
++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */ |
5251 |
++ .quad 0x004093000000ffff /* 0xc8 APM DS data */ |
5252 |
++ |
5253 |
++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */ |
5254 |
++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */ |
5255 |
++ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */ |
5256 |
++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */ |
5257 |
++ .quad 0x0000000000000000 /* 0xf0 - unused */ |
5258 |
++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ |
5259 |
++ |
5260 |
++ /* Be sure this is zeroed to avoid false validations in Xen */ |
5261 |
++ .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0 |
5262 |
++ |
5263 |
++#ifdef CONFIG_SMP |
5264 |
++ .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */ |
5265 |
++#endif |
5266 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/head64.c linux-2.6.24.4/arch/x86/kernel/head64.c |
5267 |
+--- linux-2.6.24.4/arch/x86/kernel/head64.c 2008-03-24 14:49:18.000000000 -0400 |
5268 |
++++ linux-2.6.24.4/arch/x86/kernel/head64.c 2008-03-26 17:56:55.000000000 -0400 |
5269 |
+@@ -24,7 +24,7 @@ static void __init zap_identity_mappings |
5270 |
+ { |
5271 |
+ pgd_t *pgd = pgd_offset_k(0UL); |
5272 |
+ pgd_clear(pgd); |
5273 |
+- __flush_tlb(); |
5274 |
++ __flush_tlb_all(); |
5275 |
+ } |
5276 |
+ |
5277 |
+ /* Don't add a printk in there. printk relies on the PDA which is not initialized |
5278 |
+@@ -56,16 +56,17 @@ void __init x86_64_start_kernel(char * r |
5279 |
+ /* Make NULL pointers segfault */ |
5280 |
+ zap_identity_mappings(); |
5281 |
+ |
5282 |
++ for (i = 0; i < NR_CPUS; i++) |
5283 |
++ cpu_pda(i) = &boot_cpu_pda[i]; |
5284 |
++ |
5285 |
++ pda_init(0); |
5286 |
++ |
5287 |
+ for (i = 0; i < IDT_ENTRIES; i++) |
5288 |
+ set_intr_gate(i, early_idt_handler); |
5289 |
+ load_idt((const struct desc_ptr *)&idt_descr); |
5290 |
+ |
5291 |
+ early_printk("Kernel alive\n"); |
5292 |
+ |
5293 |
+- for (i = 0; i < NR_CPUS; i++) |
5294 |
+- cpu_pda(i) = &boot_cpu_pda[i]; |
5295 |
+- |
5296 |
+- pda_init(0); |
5297 |
+ copy_bootdata(__va(real_mode_data)); |
5298 |
+ #ifdef CONFIG_SMP |
5299 |
+ cpu_set(0, cpu_online_map); |
5300 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/head_64.S linux-2.6.24.4/arch/x86/kernel/head_64.S |
5301 |
+--- linux-2.6.24.4/arch/x86/kernel/head_64.S 2008-03-24 14:49:18.000000000 -0400 |
5302 |
++++ linux-2.6.24.4/arch/x86/kernel/head_64.S 2008-03-26 17:56:55.000000000 -0400 |
5303 |
+@@ -173,6 +173,10 @@ ENTRY(secondary_startup_64) |
5304 |
+ btl $20,%edi /* No Execute supported? */ |
5305 |
+ jnc 1f |
5306 |
+ btsl $_EFER_NX, %eax |
5307 |
++ movq $(init_level4_pgt), %rdi |
5308 |
++ addq phys_base(%rip), %rdi |
5309 |
++ btsq $_PAGE_BIT_NX, 8*258(%rdi) |
5310 |
++ btsq $_PAGE_BIT_NX, 8*388(%rdi) |
5311 |
+ 1: wrmsr /* Make changes effective */ |
5312 |
+ |
5313 |
+ /* Setup cr0 */ |
5314 |
+@@ -242,24 +246,25 @@ ENTRY(secondary_startup_64) |
5315 |
+ pushq %rax # target address in negative space |
5316 |
+ lretq |
5317 |
+ |
5318 |
++bad_address: |
5319 |
++ jmp bad_address |
5320 |
++ |
5321 |
+ /* SMP bootup changes these two */ |
5322 |
+-#ifndef CONFIG_HOTPLUG_CPU |
5323 |
+- .pushsection .init.data |
5324 |
++#ifdef CONFIG_HOTPLUG_CPU |
5325 |
++ __INITDATA_REFOK |
5326 |
++#else |
5327 |
++ __INITDATA |
5328 |
+ #endif |
5329 |
+ .align 8 |
5330 |
+ .globl initial_code |
5331 |
+ initial_code: |
5332 |
+ .quad x86_64_start_kernel |
5333 |
+-#ifndef CONFIG_HOTPLUG_CPU |
5334 |
+- .popsection |
5335 |
+-#endif |
5336 |
++ |
5337 |
+ .globl init_rsp |
5338 |
+ init_rsp: |
5339 |
+ .quad init_thread_union+THREAD_SIZE-8 |
5340 |
+ |
5341 |
+-bad_address: |
5342 |
+- jmp bad_address |
5343 |
+- |
5344 |
++ __INIT |
5345 |
+ ENTRY(early_idt_handler) |
5346 |
+ cmpl $2,early_recursion_flag(%rip) |
5347 |
+ jz 1f |
5348 |
+@@ -280,9 +285,12 @@ ENTRY(early_idt_handler) |
5349 |
+ #endif |
5350 |
+ 1: hlt |
5351 |
+ jmp 1b |
5352 |
++ |
5353 |
++ __INITDATA |
5354 |
+ early_recursion_flag: |
5355 |
+ .long 0 |
5356 |
+ |
5357 |
++ .section .rodata,"a",@progbits |
5358 |
+ early_idt_msg: |
5359 |
+ .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n" |
5360 |
+ early_idt_ripmsg: |
5361 |
+@@ -312,7 +320,9 @@ NEXT_PAGE(init_level4_pgt) |
5362 |
+ .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE |
5363 |
+ .fill 257,8,0 |
5364 |
+ .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE |
5365 |
+- .fill 252,8,0 |
5366 |
++ .fill 129,8,0 |
5367 |
++ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE |
5368 |
++ .fill 122,8,0 |
5369 |
+ /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ |
5370 |
+ .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE |
5371 |
+ |
5372 |
+@@ -320,6 +330,9 @@ NEXT_PAGE(level3_ident_pgt) |
5373 |
+ .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE |
5374 |
+ .fill 511,8,0 |
5375 |
+ |
5376 |
++NEXT_PAGE(level3_vmalloc_pgt) |
5377 |
++ .fill 512,8,0 |
5378 |
++ |
5379 |
+ NEXT_PAGE(level3_kernel_pgt) |
5380 |
+ .fill 510,8,0 |
5381 |
+ /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ |
5382 |
+@@ -355,19 +368,12 @@ NEXT_PAGE(level2_spare_pgt) |
5383 |
+ #undef PMDS |
5384 |
+ #undef NEXT_PAGE |
5385 |
+ |
5386 |
+- .data |
5387 |
+ .align 16 |
5388 |
+ .globl cpu_gdt_descr |
5389 |
+ cpu_gdt_descr: |
5390 |
+- .word gdt_end-cpu_gdt_table-1 |
5391 |
++ .word GDT_SIZE-1 |
5392 |
+ gdt: |
5393 |
+ .quad cpu_gdt_table |
5394 |
+-#ifdef CONFIG_SMP |
5395 |
+- .rept NR_CPUS-1 |
5396 |
+- .word 0 |
5397 |
+- .quad 0 |
5398 |
+- .endr |
5399 |
+-#endif |
5400 |
+ |
5401 |
+ ENTRY(phys_base) |
5402 |
+ /* This must match the first entry in level2_kernel_pgt */ |
5403 |
+@@ -377,8 +383,7 @@ ENTRY(phys_base) |
5404 |
+ * IRET will check the segment types kkeil 2000/10/28 |
5405 |
+ * Also sysret mandates a special GDT layout |
5406 |
+ */ |
5407 |
+- |
5408 |
+- .section .data.page_aligned, "aw" |
5409 |
++ |
5410 |
+ .align PAGE_SIZE |
5411 |
+ |
5412 |
+ /* The TLS descriptors are currently at a different place compared to i386. |
5413 |
+@@ -397,15 +402,15 @@ ENTRY(cpu_gdt_table) |
5414 |
+ .quad 0,0 /* LDT */ |
5415 |
+ .quad 0,0,0 /* three TLS descriptors */ |
5416 |
+ .quad 0x0000f40000000000 /* node/CPU stored in limit */ |
5417 |
+-gdt_end: |
5418 |
+ /* asm/segment.h:GDT_ENTRIES must match this */ |
5419 |
+ /* This should be a multiple of the cache line size */ |
5420 |
+- /* GDTs of other CPUs are now dynamically allocated */ |
5421 |
+ |
5422 |
+ /* zero the remaining page */ |
5423 |
+ .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0 |
5424 |
++#ifdef CONFIG_SMP |
5425 |
++ .fill (NR_CPUS-1) * (PAGE_SIZE),1,0 /* other CPU's GDT */ |
5426 |
++#endif |
5427 |
+ |
5428 |
+- .section .bss, "aw", @nobits |
5429 |
+ .align L1_CACHE_BYTES |
5430 |
+ ENTRY(idt_table) |
5431 |
+ .skip 256 * 16 |
5432 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/hpet.c linux-2.6.24.4/arch/x86/kernel/hpet.c |
5433 |
+--- linux-2.6.24.4/arch/x86/kernel/hpet.c 2008-03-24 14:49:18.000000000 -0400 |
5434 |
++++ linux-2.6.24.4/arch/x86/kernel/hpet.c 2008-03-26 17:56:55.000000000 -0400 |
5435 |
+@@ -137,7 +137,7 @@ static void hpet_reserve_platform_timers |
5436 |
+ hd.hd_irq[1] = HPET_LEGACY_RTC; |
5437 |
+ |
5438 |
+ for (i = 2; i < nrtimers; timer++, i++) |
5439 |
+- hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >> |
5440 |
++ hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >> |
5441 |
+ Tn_INT_ROUTE_CNF_SHIFT; |
5442 |
+ |
5443 |
+ hpet_alloc(&hd); |
5444 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/i386_ksyms_32.c linux-2.6.24.4/arch/x86/kernel/i386_ksyms_32.c |
5445 |
+--- linux-2.6.24.4/arch/x86/kernel/i386_ksyms_32.c 2008-03-24 14:49:18.000000000 -0400 |
5446 |
++++ linux-2.6.24.4/arch/x86/kernel/i386_ksyms_32.c 2008-03-26 17:56:55.000000000 -0400 |
5447 |
+@@ -4,12 +4,16 @@ |
5448 |
+ #include <asm/desc.h> |
5449 |
+ #include <asm/pgtable.h> |
5450 |
+ |
5451 |
++EXPORT_SYMBOL_GPL(cpu_gdt_table); |
5452 |
++ |
5453 |
+ EXPORT_SYMBOL(__down_failed); |
5454 |
+ EXPORT_SYMBOL(__down_failed_interruptible); |
5455 |
+ EXPORT_SYMBOL(__down_failed_trylock); |
5456 |
+ EXPORT_SYMBOL(__up_wakeup); |
5457 |
+ /* Networking helper routines. */ |
5458 |
+ EXPORT_SYMBOL(csum_partial_copy_generic); |
5459 |
++EXPORT_SYMBOL(csum_partial_copy_generic_to_user); |
5460 |
++EXPORT_SYMBOL(csum_partial_copy_generic_from_user); |
5461 |
+ |
5462 |
+ EXPORT_SYMBOL(__get_user_1); |
5463 |
+ EXPORT_SYMBOL(__get_user_2); |
5464 |
+@@ -31,3 +35,7 @@ EXPORT_SYMBOL(__read_lock_failed); |
5465 |
+ |
5466 |
+ EXPORT_SYMBOL(csum_partial); |
5467 |
+ EXPORT_SYMBOL(empty_zero_page); |
5468 |
++ |
5469 |
++#ifdef CONFIG_PAX_KERNEXEC |
5470 |
++EXPORT_SYMBOL(KERNEL_TEXT_OFFSET); |
5471 |
++#endif |
5472 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/init_task.c linux-2.6.24.4/arch/x86/kernel/init_task.c |
5473 |
+--- linux-2.6.24.4/arch/x86/kernel/init_task.c 2008-03-24 14:49:18.000000000 -0400 |
5474 |
++++ linux-2.6.24.4/arch/x86/kernel/init_task.c 2008-03-26 17:56:55.000000000 -0400 |
5475 |
+@@ -43,5 +43,4 @@ EXPORT_SYMBOL(init_task); |
5476 |
+ * section. Since TSS's are completely CPU-local, we want them |
5477 |
+ * on exact cacheline boundaries, to eliminate cacheline ping-pong. |
5478 |
+ */ |
5479 |
+-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS; |
5480 |
+- |
5481 |
++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS }; |
5482 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/ioport_32.c linux-2.6.24.4/arch/x86/kernel/ioport_32.c |
5483 |
+--- linux-2.6.24.4/arch/x86/kernel/ioport_32.c 2008-03-24 14:49:18.000000000 -0400 |
5484 |
++++ linux-2.6.24.4/arch/x86/kernel/ioport_32.c 2008-03-26 17:56:55.000000000 -0400 |
5485 |
+@@ -14,6 +14,7 @@ |
5486 |
+ #include <linux/slab.h> |
5487 |
+ #include <linux/thread_info.h> |
5488 |
+ #include <linux/syscalls.h> |
5489 |
++#include <linux/grsecurity.h> |
5490 |
+ |
5491 |
+ /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ |
5492 |
+ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) |
5493 |
+@@ -62,9 +63,16 @@ asmlinkage long sys_ioperm(unsigned long |
5494 |
+ |
5495 |
+ if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) |
5496 |
+ return -EINVAL; |
5497 |
++#ifdef CONFIG_GRKERNSEC_IO |
5498 |
++ if (turn_on) { |
5499 |
++ gr_handle_ioperm(); |
5500 |
++#else |
5501 |
+ if (turn_on && !capable(CAP_SYS_RAWIO)) |
5502 |
++#endif |
5503 |
+ return -EPERM; |
5504 |
+- |
5505 |
++#ifdef CONFIG_GRKERNSEC_IO |
5506 |
++ } |
5507 |
++#endif |
5508 |
+ /* |
5509 |
+ * If it's the first ioperm() call in this thread's lifetime, set the |
5510 |
+ * IO bitmap up. ioperm() is much less timing critical than clone(), |
5511 |
+@@ -87,7 +95,7 @@ asmlinkage long sys_ioperm(unsigned long |
5512 |
+ * because the ->io_bitmap_max value must match the bitmap |
5513 |
+ * contents: |
5514 |
+ */ |
5515 |
+- tss = &per_cpu(init_tss, get_cpu()); |
5516 |
++ tss = init_tss + get_cpu(); |
5517 |
+ |
5518 |
+ set_bitmap(t->io_bitmap_ptr, from, num, !turn_on); |
5519 |
+ |
5520 |
+@@ -141,8 +149,13 @@ asmlinkage long sys_iopl(unsigned long u |
5521 |
+ return -EINVAL; |
5522 |
+ /* Trying to gain more privileges? */ |
5523 |
+ if (level > old) { |
5524 |
++#ifdef CONFIG_GRKERNSEC_IO |
5525 |
++ gr_handle_iopl(); |
5526 |
++ return -EPERM; |
5527 |
++#else |
5528 |
+ if (!capable(CAP_SYS_RAWIO)) |
5529 |
+ return -EPERM; |
5530 |
++#endif |
5531 |
+ } |
5532 |
+ t->iopl = level << 12; |
5533 |
+ regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl; |
5534 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/ioport_64.c linux-2.6.24.4/arch/x86/kernel/ioport_64.c |
5535 |
+--- linux-2.6.24.4/arch/x86/kernel/ioport_64.c 2008-03-24 14:49:18.000000000 -0400 |
5536 |
++++ linux-2.6.24.4/arch/x86/kernel/ioport_64.c 2008-03-26 17:56:55.000000000 -0400 |
5537 |
+@@ -14,6 +14,7 @@ |
5538 |
+ #include <linux/slab.h> |
5539 |
+ #include <linux/thread_info.h> |
5540 |
+ #include <linux/syscalls.h> |
5541 |
++#include <linux/grsecurity.h> |
5542 |
+ |
5543 |
+ /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ |
5544 |
+ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) |
5545 |
+@@ -39,8 +40,17 @@ asmlinkage long sys_ioperm(unsigned long |
5546 |
+ |
5547 |
+ if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) |
5548 |
+ return -EINVAL; |
5549 |
++ |
5550 |
++#ifdef CONFIG_GRKERNSEC_IO |
5551 |
++ if (turn_on) { |
5552 |
++ gr_handle_ioperm(); |
5553 |
++#else |
5554 |
+ if (turn_on && !capable(CAP_SYS_RAWIO)) |
5555 |
++#endif |
5556 |
+ return -EPERM; |
5557 |
++#ifdef CONFIG_GRKERNSEC_IO |
5558 |
++ } |
5559 |
++#endif |
5560 |
+ |
5561 |
+ /* |
5562 |
+ * If it's the first ioperm() call in this thread's lifetime, set the |
5563 |
+@@ -64,7 +74,7 @@ asmlinkage long sys_ioperm(unsigned long |
5564 |
+ * because the ->io_bitmap_max value must match the bitmap |
5565 |
+ * contents: |
5566 |
+ */ |
5567 |
+- tss = &per_cpu(init_tss, get_cpu()); |
5568 |
++ tss = init_tss + get_cpu(); |
5569 |
+ |
5570 |
+ set_bitmap(t->io_bitmap_ptr, from, num, !turn_on); |
5571 |
+ |
5572 |
+@@ -109,8 +119,13 @@ asmlinkage long sys_iopl(unsigned int le |
5573 |
+ return -EINVAL; |
5574 |
+ /* Trying to gain more privileges? */ |
5575 |
+ if (level > old) { |
5576 |
++#ifdef CONFIG_GRKERNSEC_IO |
5577 |
++ gr_handle_iopl(); |
5578 |
++ return -EPERM; |
5579 |
++#else |
5580 |
+ if (!capable(CAP_SYS_RAWIO)) |
5581 |
+ return -EPERM; |
5582 |
++#endif |
5583 |
+ } |
5584 |
+ regs->eflags = (regs->eflags &~ X86_EFLAGS_IOPL) | (level << 12); |
5585 |
+ return 0; |
5586 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/irq_32.c linux-2.6.24.4/arch/x86/kernel/irq_32.c |
5587 |
+--- linux-2.6.24.4/arch/x86/kernel/irq_32.c 2008-03-24 14:49:18.000000000 -0400 |
5588 |
++++ linux-2.6.24.4/arch/x86/kernel/irq_32.c 2008-03-26 17:56:55.000000000 -0400 |
5589 |
+@@ -115,7 +115,7 @@ fastcall unsigned int do_IRQ(struct pt_r |
5590 |
+ int arg1, arg2, ebx; |
5591 |
+ |
5592 |
+ /* build the stack frame on the IRQ stack */ |
5593 |
+- isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); |
5594 |
++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8); |
5595 |
+ irqctx->tinfo.task = curctx->tinfo.task; |
5596 |
+ irqctx->tinfo.previous_esp = current_stack_pointer; |
5597 |
+ |
5598 |
+@@ -211,7 +211,7 @@ asmlinkage void do_softirq(void) |
5599 |
+ irqctx->tinfo.previous_esp = current_stack_pointer; |
5600 |
+ |
5601 |
+ /* build the stack frame on the softirq stack */ |
5602 |
+- isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); |
5603 |
++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8); |
5604 |
+ |
5605 |
+ asm volatile( |
5606 |
+ " xchgl %%ebx,%%esp \n" |
5607 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/kprobes_32.c linux-2.6.24.4/arch/x86/kernel/kprobes_32.c |
5608 |
+--- linux-2.6.24.4/arch/x86/kernel/kprobes_32.c 2008-03-24 14:49:18.000000000 -0400 |
5609 |
++++ linux-2.6.24.4/arch/x86/kernel/kprobes_32.c 2008-03-26 17:56:55.000000000 -0400 |
5610 |
+@@ -55,9 +55,24 @@ static __always_inline void set_jmp_op(v |
5611 |
+ char op; |
5612 |
+ long raddr; |
5613 |
+ } __attribute__((packed)) *jop; |
5614 |
+- jop = (struct __arch_jmp_op *)from; |
5615 |
++ |
5616 |
++#ifdef CONFIG_PAX_KERNEXEC |
5617 |
++ unsigned long cr0; |
5618 |
++#endif |
5619 |
++ |
5620 |
++ jop = (struct __arch_jmp_op *)(ktla_ktva(from)); |
5621 |
++ |
5622 |
++#ifdef CONFIG_PAX_KERNEXEC |
5623 |
++ pax_open_kernel(cr0); |
5624 |
++#endif |
5625 |
++ |
5626 |
+ jop->raddr = (long)(to) - ((long)(from) + 5); |
5627 |
+ jop->op = RELATIVEJUMP_INSTRUCTION; |
5628 |
++ |
5629 |
++#ifdef CONFIG_PAX_KERNEXEC |
5630 |
++ pax_close_kernel(cr0); |
5631 |
++#endif |
5632 |
++ |
5633 |
+ } |
5634 |
+ |
5635 |
+ /* |
5636 |
+@@ -159,14 +174,28 @@ static int __kprobes is_IF_modifier(kpro |
5637 |
+ |
5638 |
+ int __kprobes arch_prepare_kprobe(struct kprobe *p) |
5639 |
+ { |
5640 |
++ |
5641 |
++#ifdef CONFIG_PAX_KERNEXEC |
5642 |
++ unsigned long cr0; |
5643 |
++#endif |
5644 |
++ |
5645 |
+ /* insn: must be on special executable page on i386. */ |
5646 |
+ p->ainsn.insn = get_insn_slot(); |
5647 |
+ if (!p->ainsn.insn) |
5648 |
+ return -ENOMEM; |
5649 |
+ |
5650 |
+- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); |
5651 |
+- p->opcode = *p->addr; |
5652 |
+- if (can_boost(p->addr)) { |
5653 |
++#ifdef CONFIG_PAX_KERNEXEC |
5654 |
++ pax_open_kernel(cr0); |
5655 |
++#endif |
5656 |
++ |
5657 |
++ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); |
5658 |
++ |
5659 |
++#ifdef CONFIG_PAX_KERNEXEC |
5660 |
++ pax_close_kernel(cr0); |
5661 |
++#endif |
5662 |
++ |
5663 |
++ p->opcode = *(ktla_ktva(p->addr)); |
5664 |
++ if (can_boost(ktla_ktva(p->addr))) { |
5665 |
+ p->ainsn.boostable = 0; |
5666 |
+ } else { |
5667 |
+ p->ainsn.boostable = -1; |
5668 |
+@@ -225,7 +254,7 @@ static void __kprobes prepare_singlestep |
5669 |
+ if (p->opcode == BREAKPOINT_INSTRUCTION) |
5670 |
+ regs->eip = (unsigned long)p->addr; |
5671 |
+ else |
5672 |
+- regs->eip = (unsigned long)p->ainsn.insn; |
5673 |
++ regs->eip = ktva_ktla((unsigned long)p->ainsn.insn); |
5674 |
+ } |
5675 |
+ |
5676 |
+ /* Called with kretprobe_lock held */ |
5677 |
+@@ -331,7 +360,7 @@ ss_probe: |
5678 |
+ if (p->ainsn.boostable == 1 && !p->post_handler){ |
5679 |
+ /* Boost up -- we can execute copied instructions directly */ |
5680 |
+ reset_current_kprobe(); |
5681 |
+- regs->eip = (unsigned long)p->ainsn.insn; |
5682 |
++ regs->eip = ktva_ktla((unsigned long)p->ainsn.insn); |
5683 |
+ preempt_enable_no_resched(); |
5684 |
+ return 1; |
5685 |
+ } |
5686 |
+@@ -481,7 +510,7 @@ static void __kprobes resume_execution(s |
5687 |
+ struct pt_regs *regs, struct kprobe_ctlblk *kcb) |
5688 |
+ { |
5689 |
+ unsigned long *tos = (unsigned long *)®s->esp; |
5690 |
+- unsigned long copy_eip = (unsigned long)p->ainsn.insn; |
5691 |
++ unsigned long copy_eip = ktva_ktla((unsigned long)p->ainsn.insn); |
5692 |
+ unsigned long orig_eip = (unsigned long)p->addr; |
5693 |
+ |
5694 |
+ regs->eflags &= ~TF_MASK; |
5695 |
+@@ -655,7 +684,7 @@ int __kprobes kprobe_exceptions_notify(s |
5696 |
+ struct die_args *args = (struct die_args *)data; |
5697 |
+ int ret = NOTIFY_DONE; |
5698 |
+ |
5699 |
+- if (args->regs && user_mode_vm(args->regs)) |
5700 |
++ if (args->regs && user_mode(args->regs)) |
5701 |
+ return ret; |
5702 |
+ |
5703 |
+ switch (val) { |
5704 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/kprobes_64.c linux-2.6.24.4/arch/x86/kernel/kprobes_64.c |
5705 |
+--- linux-2.6.24.4/arch/x86/kernel/kprobes_64.c 2008-03-24 14:49:18.000000000 -0400 |
5706 |
++++ linux-2.6.24.4/arch/x86/kernel/kprobes_64.c 2008-03-26 17:56:55.000000000 -0400 |
5707 |
+@@ -190,7 +190,19 @@ static s32 __kprobes *is_riprel(u8 *insn |
5708 |
+ static void __kprobes arch_copy_kprobe(struct kprobe *p) |
5709 |
+ { |
5710 |
+ s32 *ripdisp; |
5711 |
++ |
5712 |
++#ifdef CONFIG_PAX_KERNEXEC |
5713 |
++ unsigned long cr0; |
5714 |
++ |
5715 |
++ pax_open_kernel(cr0); |
5716 |
++#endif |
5717 |
++ |
5718 |
+ memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE); |
5719 |
++ |
5720 |
++#ifdef CONFIG_PAX_KERNEXEC |
5721 |
++ pax_close_kernel(cr0); |
5722 |
++#endif |
5723 |
++ |
5724 |
+ ripdisp = is_riprel(p->ainsn.insn); |
5725 |
+ if (ripdisp) { |
5726 |
+ /* |
5727 |
+@@ -208,7 +220,17 @@ static void __kprobes arch_copy_kprobe(s |
5728 |
+ */ |
5729 |
+ s64 disp = (u8 *) p->addr + *ripdisp - (u8 *) p->ainsn.insn; |
5730 |
+ BUG_ON((s64) (s32) disp != disp); /* Sanity check. */ |
5731 |
++ |
5732 |
++#ifdef CONFIG_PAX_KERNEXEC |
5733 |
++ pax_open_kernel(cr0); |
5734 |
++#endif |
5735 |
++ |
5736 |
+ *ripdisp = disp; |
5737 |
++ |
5738 |
++#ifdef CONFIG_PAX_KERNEXEC |
5739 |
++ pax_close_kernel(cr0); |
5740 |
++#endif |
5741 |
++ |
5742 |
+ } |
5743 |
+ p->opcode = *p->addr; |
5744 |
+ } |
5745 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/ldt_32.c linux-2.6.24.4/arch/x86/kernel/ldt_32.c |
5746 |
+--- linux-2.6.24.4/arch/x86/kernel/ldt_32.c 2008-03-24 14:49:18.000000000 -0400 |
5747 |
++++ linux-2.6.24.4/arch/x86/kernel/ldt_32.c 2008-03-26 17:56:55.000000000 -0400 |
5748 |
+@@ -56,7 +56,7 @@ static int alloc_ldt(mm_context_t *pc, i |
5749 |
+ #ifdef CONFIG_SMP |
5750 |
+ cpumask_t mask; |
5751 |
+ preempt_disable(); |
5752 |
+- load_LDT(pc); |
5753 |
++ load_LDT_nolock(pc); |
5754 |
+ mask = cpumask_of_cpu(smp_processor_id()); |
5755 |
+ if (!cpus_equal(current->mm->cpu_vm_mask, mask)) |
5756 |
+ smp_call_function(flush_ldt, NULL, 1, 1); |
5757 |
+@@ -100,6 +100,22 @@ int init_new_context(struct task_struct |
5758 |
+ retval = copy_ldt(&mm->context, &old_mm->context); |
5759 |
+ mutex_unlock(&old_mm->context.lock); |
5760 |
+ } |
5761 |
++ |
5762 |
++ if (tsk == current) { |
5763 |
++ mm->context.vdso = ~0UL; |
5764 |
++ |
5765 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
5766 |
++ mm->context.user_cs_base = 0UL; |
5767 |
++ mm->context.user_cs_limit = ~0UL; |
5768 |
++ |
5769 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP) |
5770 |
++ cpus_clear(mm->context.cpu_user_cs_mask); |
5771 |
++#endif |
5772 |
++ |
5773 |
++#endif |
5774 |
++ |
5775 |
++ } |
5776 |
++ |
5777 |
+ return retval; |
5778 |
+ } |
5779 |
+ |
5780 |
+@@ -210,6 +226,13 @@ static int write_ldt(void __user * ptr, |
5781 |
+ } |
5782 |
+ } |
5783 |
+ |
5784 |
++#ifdef CONFIG_PAX_SEGMEXEC |
5785 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) { |
5786 |
++ error = -EINVAL; |
5787 |
++ goto out_unlock; |
5788 |
++ } |
5789 |
++#endif |
5790 |
++ |
5791 |
+ entry_1 = LDT_entry_a(&ldt_info); |
5792 |
+ entry_2 = LDT_entry_b(&ldt_info); |
5793 |
+ if (oldmode) |
5794 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/machine_kexec_32.c linux-2.6.24.4/arch/x86/kernel/machine_kexec_32.c |
5795 |
+--- linux-2.6.24.4/arch/x86/kernel/machine_kexec_32.c 2008-03-24 14:49:18.000000000 -0400 |
5796 |
++++ linux-2.6.24.4/arch/x86/kernel/machine_kexec_32.c 2008-03-26 17:56:55.000000000 -0400 |
5797 |
+@@ -30,25 +30,25 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED |
5798 |
+ static u32 kexec_pte0[1024] PAGE_ALIGNED; |
5799 |
+ static u32 kexec_pte1[1024] PAGE_ALIGNED; |
5800 |
+ |
5801 |
+-static void set_idt(void *newidt, __u16 limit) |
5802 |
++static void set_idt(struct desc_struct *newidt, __u16 limit) |
5803 |
+ { |
5804 |
+ struct Xgt_desc_struct curidt; |
5805 |
+ |
5806 |
+ /* ia32 supports unaliged loads & stores */ |
5807 |
+ curidt.size = limit; |
5808 |
+- curidt.address = (unsigned long)newidt; |
5809 |
++ curidt.address = newidt; |
5810 |
+ |
5811 |
+ load_idt(&curidt); |
5812 |
+ }; |
5813 |
+ |
5814 |
+ |
5815 |
+-static void set_gdt(void *newgdt, __u16 limit) |
5816 |
++static void set_gdt(struct desc_struct *newgdt, __u16 limit) |
5817 |
+ { |
5818 |
+ struct Xgt_desc_struct curgdt; |
5819 |
+ |
5820 |
+ /* ia32 supports unaligned loads & stores */ |
5821 |
+ curgdt.size = limit; |
5822 |
+- curgdt.address = (unsigned long)newgdt; |
5823 |
++ curgdt.address = newgdt; |
5824 |
+ |
5825 |
+ load_gdt(&curgdt); |
5826 |
+ }; |
5827 |
+@@ -111,10 +111,10 @@ NORET_TYPE void machine_kexec(struct kim |
5828 |
+ local_irq_disable(); |
5829 |
+ |
5830 |
+ control_page = page_address(image->control_code_page); |
5831 |
+- memcpy(control_page, relocate_kernel, PAGE_SIZE); |
5832 |
++ memcpy(control_page, ktla_ktva(relocate_kernel), PAGE_SIZE); |
5833 |
+ |
5834 |
+ page_list[PA_CONTROL_PAGE] = __pa(control_page); |
5835 |
+- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; |
5836 |
++ page_list[VA_CONTROL_PAGE] = ktla_ktva((unsigned long)relocate_kernel); |
5837 |
+ page_list[PA_PGD] = __pa(kexec_pgd); |
5838 |
+ page_list[VA_PGD] = (unsigned long)kexec_pgd; |
5839 |
+ #ifdef CONFIG_X86_PAE |
5840 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/Makefile_64 linux-2.6.24.4/arch/x86/kernel/Makefile_64 |
5841 |
+--- linux-2.6.24.4/arch/x86/kernel/Makefile_64 2008-03-24 14:49:18.000000000 -0400 |
5842 |
++++ linux-2.6.24.4/arch/x86/kernel/Makefile_64 2008-03-26 17:56:55.000000000 -0400 |
5843 |
+@@ -42,4 +42,6 @@ obj-$(CONFIG_PCI) += early-quirks.o |
5844 |
+ obj-y += topology.o |
5845 |
+ obj-y += pcspeaker.o |
5846 |
+ |
5847 |
+-CFLAGS_vsyscall_64.o := $(PROFILING) -g0 |
5848 |
++CFLAGS_vsyscall_64.o := $(PROFILING) -g0 -fno-stack-protector |
5849 |
++CFLAGS_hpet.o := -fno-stack-protector |
5850 |
++CFLAGS_tsc_64.o := -fno-stack-protector |
5851 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/module_32.c linux-2.6.24.4/arch/x86/kernel/module_32.c |
5852 |
+--- linux-2.6.24.4/arch/x86/kernel/module_32.c 2008-03-24 14:49:18.000000000 -0400 |
5853 |
++++ linux-2.6.24.4/arch/x86/kernel/module_32.c 2008-03-26 17:56:55.000000000 -0400 |
5854 |
+@@ -23,6 +23,8 @@ |
5855 |
+ #include <linux/kernel.h> |
5856 |
+ #include <linux/bug.h> |
5857 |
+ |
5858 |
++#include <asm/desc.h> |
5859 |
++ |
5860 |
+ #if 0 |
5861 |
+ #define DEBUGP printk |
5862 |
+ #else |
5863 |
+@@ -33,9 +35,30 @@ void *module_alloc(unsigned long size) |
5864 |
+ { |
5865 |
+ if (size == 0) |
5866 |
+ return NULL; |
5867 |
++ |
5868 |
++#ifdef CONFIG_PAX_KERNEXEC |
5869 |
++ return vmalloc(size); |
5870 |
++#else |
5871 |
+ return vmalloc_exec(size); |
5872 |
++#endif |
5873 |
++ |
5874 |
+ } |
5875 |
+ |
5876 |
++#ifdef CONFIG_PAX_KERNEXEC |
5877 |
++void *module_alloc_exec(unsigned long size) |
5878 |
++{ |
5879 |
++ struct vm_struct *area; |
5880 |
++ |
5881 |
++ if (size == 0) |
5882 |
++ return NULL; |
5883 |
++ |
5884 |
++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END); |
5885 |
++ if (area) |
5886 |
++ return area->addr; |
5887 |
++ |
5888 |
++ return NULL; |
5889 |
++} |
5890 |
++#endif |
5891 |
+ |
5892 |
+ /* Free memory returned from module_alloc */ |
5893 |
+ void module_free(struct module *mod, void *module_region) |
5894 |
+@@ -45,6 +68,45 @@ void module_free(struct module *mod, voi |
5895 |
+ table entries. */ |
5896 |
+ } |
5897 |
+ |
5898 |
++#ifdef CONFIG_PAX_KERNEXEC |
5899 |
++void module_free_exec(struct module *mod, void *module_region) |
5900 |
++{ |
5901 |
++ struct vm_struct **p, *tmp; |
5902 |
++ |
5903 |
++ if (!module_region) |
5904 |
++ return; |
5905 |
++ |
5906 |
++ if ((PAGE_SIZE-1) & (unsigned long)module_region) { |
5907 |
++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region); |
5908 |
++ WARN_ON(1); |
5909 |
++ return; |
5910 |
++ } |
5911 |
++ |
5912 |
++ write_lock(&vmlist_lock); |
5913 |
++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) |
5914 |
++ if (tmp->addr == module_region) |
5915 |
++ break; |
5916 |
++ |
5917 |
++ if (tmp) { |
5918 |
++ unsigned long cr0; |
5919 |
++ |
5920 |
++ pax_open_kernel(cr0); |
5921 |
++ memset(tmp->addr, 0xCC, tmp->size); |
5922 |
++ pax_close_kernel(cr0); |
5923 |
++ |
5924 |
++ *p = tmp->next; |
5925 |
++ kfree(tmp); |
5926 |
++ } |
5927 |
++ write_unlock(&vmlist_lock); |
5928 |
++ |
5929 |
++ if (!tmp) { |
5930 |
++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n", |
5931 |
++ module_region); |
5932 |
++ WARN_ON(1); |
5933 |
++ } |
5934 |
++} |
5935 |
++#endif |
5936 |
++ |
5937 |
+ /* We don't need anything special. */ |
5938 |
+ int module_frob_arch_sections(Elf_Ehdr *hdr, |
5939 |
+ Elf_Shdr *sechdrs, |
5940 |
+@@ -63,14 +125,20 @@ int apply_relocate(Elf32_Shdr *sechdrs, |
5941 |
+ unsigned int i; |
5942 |
+ Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr; |
5943 |
+ Elf32_Sym *sym; |
5944 |
+- uint32_t *location; |
5945 |
++ uint32_t *plocation, location; |
5946 |
++ |
5947 |
++#ifdef CONFIG_PAX_KERNEXEC |
5948 |
++ unsigned long cr0; |
5949 |
++#endif |
5950 |
+ |
5951 |
+ DEBUGP("Applying relocate section %u to %u\n", relsec, |
5952 |
+ sechdrs[relsec].sh_info); |
5953 |
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { |
5954 |
+ /* This is where to make the change */ |
5955 |
+- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr |
5956 |
+- + rel[i].r_offset; |
5957 |
++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset; |
5958 |
++ location = (uint32_t)plocation; |
5959 |
++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR) |
5960 |
++ plocation = ktla_ktva((void *)plocation); |
5961 |
+ /* This is the symbol it is referring to. Note that all |
5962 |
+ undefined symbols have been resolved. */ |
5963 |
+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr |
5964 |
+@@ -78,12 +146,32 @@ int apply_relocate(Elf32_Shdr *sechdrs, |
5965 |
+ |
5966 |
+ switch (ELF32_R_TYPE(rel[i].r_info)) { |
5967 |
+ case R_386_32: |
5968 |
++ |
5969 |
++#ifdef CONFIG_PAX_KERNEXEC |
5970 |
++ pax_open_kernel(cr0); |
5971 |
++#endif |
5972 |
++ |
5973 |
+ /* We add the value into the location given */ |
5974 |
+- *location += sym->st_value; |
5975 |
++ *plocation += sym->st_value; |
5976 |
++ |
5977 |
++#ifdef CONFIG_PAX_KERNEXEC |
5978 |
++ pax_close_kernel(cr0); |
5979 |
++#endif |
5980 |
++ |
5981 |
+ break; |
5982 |
+ case R_386_PC32: |
5983 |
++ |
5984 |
++#ifdef CONFIG_PAX_KERNEXEC |
5985 |
++ pax_open_kernel(cr0); |
5986 |
++#endif |
5987 |
++ |
5988 |
+ /* Add the value, subtract its postition */ |
5989 |
+- *location += sym->st_value - (uint32_t)location; |
5990 |
++ *plocation += sym->st_value - location; |
5991 |
++ |
5992 |
++#ifdef CONFIG_PAX_KERNEXEC |
5993 |
++ pax_close_kernel(cr0); |
5994 |
++#endif |
5995 |
++ |
5996 |
+ break; |
5997 |
+ default: |
5998 |
+ printk(KERN_ERR "module %s: Unknown relocation: %u\n", |
5999 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/module_64.c linux-2.6.24.4/arch/x86/kernel/module_64.c |
6000 |
+--- linux-2.6.24.4/arch/x86/kernel/module_64.c 2008-03-24 14:49:18.000000000 -0400 |
6001 |
++++ linux-2.6.24.4/arch/x86/kernel/module_64.c 2008-03-26 17:56:55.000000000 -0400 |
6002 |
+@@ -39,7 +39,7 @@ void module_free(struct module *mod, voi |
6003 |
+ table entries. */ |
6004 |
+ } |
6005 |
+ |
6006 |
+-void *module_alloc(unsigned long size) |
6007 |
++static void *__module_alloc(unsigned long size, pgprot_t prot) |
6008 |
+ { |
6009 |
+ struct vm_struct *area; |
6010 |
+ |
6011 |
+@@ -53,8 +53,31 @@ void *module_alloc(unsigned long size) |
6012 |
+ if (!area) |
6013 |
+ return NULL; |
6014 |
+ |
6015 |
+- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC); |
6016 |
++ return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot); |
6017 |
++} |
6018 |
++ |
6019 |
++#ifdef CONFIG_PAX_KERNEXEC |
6020 |
++void *module_alloc(unsigned long size) |
6021 |
++{ |
6022 |
++ return __module_alloc(size, PAGE_KERNEL); |
6023 |
++} |
6024 |
++ |
6025 |
++void module_free_exec(struct module *mod, void *module_region) |
6026 |
++{ |
6027 |
++ module_free(mod, module_region); |
6028 |
++} |
6029 |
++ |
6030 |
++void *module_alloc_exec(unsigned long size) |
6031 |
++{ |
6032 |
++ return __module_alloc(size, PAGE_KERNEL_RX); |
6033 |
+ } |
6034 |
++#else |
6035 |
++void *module_alloc(unsigned long size) |
6036 |
++{ |
6037 |
++ return __module_alloc(size, PAGE_KERNEL_EXEC); |
6038 |
++} |
6039 |
++#endif |
6040 |
++ |
6041 |
+ #endif |
6042 |
+ |
6043 |
+ /* We don't need anything special. */ |
6044 |
+@@ -76,7 +99,11 @@ int apply_relocate_add(Elf64_Shdr *sechd |
6045 |
+ Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr; |
6046 |
+ Elf64_Sym *sym; |
6047 |
+ void *loc; |
6048 |
+- u64 val; |
6049 |
++ u64 val; |
6050 |
++ |
6051 |
++#ifdef CONFIG_PAX_KERNEXEC |
6052 |
++ unsigned long cr0; |
6053 |
++#endif |
6054 |
+ |
6055 |
+ DEBUGP("Applying relocate section %u to %u\n", relsec, |
6056 |
+ sechdrs[relsec].sh_info); |
6057 |
+@@ -100,21 +127,61 @@ int apply_relocate_add(Elf64_Shdr *sechd |
6058 |
+ case R_X86_64_NONE: |
6059 |
+ break; |
6060 |
+ case R_X86_64_64: |
6061 |
++ |
6062 |
++#ifdef CONFIG_PAX_KERNEXEC |
6063 |
++ pax_open_kernel(cr0); |
6064 |
++#endif |
6065 |
++ |
6066 |
+ *(u64 *)loc = val; |
6067 |
++ |
6068 |
++#ifdef CONFIG_PAX_KERNEXEC |
6069 |
++ pax_close_kernel(cr0); |
6070 |
++#endif |
6071 |
++ |
6072 |
+ break; |
6073 |
+ case R_X86_64_32: |
6074 |
++ |
6075 |
++#ifdef CONFIG_PAX_KERNEXEC |
6076 |
++ pax_open_kernel(cr0); |
6077 |
++#endif |
6078 |
++ |
6079 |
+ *(u32 *)loc = val; |
6080 |
++ |
6081 |
++#ifdef CONFIG_PAX_KERNEXEC |
6082 |
++ pax_close_kernel(cr0); |
6083 |
++#endif |
6084 |
++ |
6085 |
+ if (val != *(u32 *)loc) |
6086 |
+ goto overflow; |
6087 |
+ break; |
6088 |
+ case R_X86_64_32S: |
6089 |
++ |
6090 |
++#ifdef CONFIG_PAX_KERNEXEC |
6091 |
++ pax_open_kernel(cr0); |
6092 |
++#endif |
6093 |
++ |
6094 |
+ *(s32 *)loc = val; |
6095 |
++ |
6096 |
++#ifdef CONFIG_PAX_KERNEXEC |
6097 |
++ pax_close_kernel(cr0); |
6098 |
++#endif |
6099 |
++ |
6100 |
+ if ((s64)val != *(s32 *)loc) |
6101 |
+ goto overflow; |
6102 |
+ break; |
6103 |
+ case R_X86_64_PC32: |
6104 |
+ val -= (u64)loc; |
6105 |
++ |
6106 |
++#ifdef CONFIG_PAX_KERNEXEC |
6107 |
++ pax_open_kernel(cr0); |
6108 |
++#endif |
6109 |
++ |
6110 |
+ *(u32 *)loc = val; |
6111 |
++ |
6112 |
++#ifdef CONFIG_PAX_KERNEXEC |
6113 |
++ pax_close_kernel(cr0); |
6114 |
++#endif |
6115 |
++ |
6116 |
+ #if 0 |
6117 |
+ if ((s64)val != *(s32 *)loc) |
6118 |
+ goto overflow; |
6119 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/paravirt_32.c linux-2.6.24.4/arch/x86/kernel/paravirt_32.c |
6120 |
+--- linux-2.6.24.4/arch/x86/kernel/paravirt_32.c 2008-03-24 14:49:18.000000000 -0400 |
6121 |
++++ linux-2.6.24.4/arch/x86/kernel/paravirt_32.c 2008-03-26 17:56:55.000000000 -0400 |
6122 |
+@@ -39,7 +39,7 @@ void _paravirt_nop(void) |
6123 |
+ { |
6124 |
+ } |
6125 |
+ |
6126 |
+-static void __init default_banner(void) |
6127 |
++static void default_banner(void) |
6128 |
+ { |
6129 |
+ printk(KERN_INFO "Booting paravirtualized kernel on %s\n", |
6130 |
+ pv_info.name); |
6131 |
+@@ -206,7 +206,7 @@ unsigned paravirt_patch_insns(void *insn |
6132 |
+ if (insn_len > len || start == NULL) |
6133 |
+ insn_len = len; |
6134 |
+ else |
6135 |
+- memcpy(insnbuf, start, insn_len); |
6136 |
++ memcpy(insnbuf, ktla_ktva(start), insn_len); |
6137 |
+ |
6138 |
+ return insn_len; |
6139 |
+ } |
6140 |
+@@ -324,21 +324,21 @@ enum paravirt_lazy_mode paravirt_get_laz |
6141 |
+ return x86_read_percpu(paravirt_lazy_mode); |
6142 |
+ } |
6143 |
+ |
6144 |
+-struct pv_info pv_info = { |
6145 |
++struct pv_info pv_info __read_only = { |
6146 |
+ .name = "bare hardware", |
6147 |
+ .paravirt_enabled = 0, |
6148 |
+ .kernel_rpl = 0, |
6149 |
+ .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */ |
6150 |
+ }; |
6151 |
+ |
6152 |
+-struct pv_init_ops pv_init_ops = { |
6153 |
++struct pv_init_ops pv_init_ops __read_only = { |
6154 |
+ .patch = native_patch, |
6155 |
+ .banner = default_banner, |
6156 |
+ .arch_setup = paravirt_nop, |
6157 |
+ .memory_setup = machine_specific_memory_setup, |
6158 |
+ }; |
6159 |
+ |
6160 |
+-struct pv_time_ops pv_time_ops = { |
6161 |
++struct pv_time_ops pv_time_ops __read_only = { |
6162 |
+ .time_init = hpet_time_init, |
6163 |
+ .get_wallclock = native_get_wallclock, |
6164 |
+ .set_wallclock = native_set_wallclock, |
6165 |
+@@ -346,7 +346,7 @@ struct pv_time_ops pv_time_ops = { |
6166 |
+ .get_cpu_khz = native_calculate_cpu_khz, |
6167 |
+ }; |
6168 |
+ |
6169 |
+-struct pv_irq_ops pv_irq_ops = { |
6170 |
++struct pv_irq_ops pv_irq_ops __read_only = { |
6171 |
+ .init_IRQ = native_init_IRQ, |
6172 |
+ .save_fl = native_save_fl, |
6173 |
+ .restore_fl = native_restore_fl, |
6174 |
+@@ -356,7 +356,7 @@ struct pv_irq_ops pv_irq_ops = { |
6175 |
+ .halt = native_halt, |
6176 |
+ }; |
6177 |
+ |
6178 |
+-struct pv_cpu_ops pv_cpu_ops = { |
6179 |
++struct pv_cpu_ops pv_cpu_ops __read_only = { |
6180 |
+ .cpuid = native_cpuid, |
6181 |
+ .get_debugreg = native_get_debugreg, |
6182 |
+ .set_debugreg = native_set_debugreg, |
6183 |
+@@ -396,7 +396,7 @@ struct pv_cpu_ops pv_cpu_ops = { |
6184 |
+ }, |
6185 |
+ }; |
6186 |
+ |
6187 |
+-struct pv_apic_ops pv_apic_ops = { |
6188 |
++struct pv_apic_ops pv_apic_ops __read_only = { |
6189 |
+ #ifdef CONFIG_X86_LOCAL_APIC |
6190 |
+ .apic_write = native_apic_write, |
6191 |
+ .apic_write_atomic = native_apic_write_atomic, |
6192 |
+@@ -407,7 +407,7 @@ struct pv_apic_ops pv_apic_ops = { |
6193 |
+ #endif |
6194 |
+ }; |
6195 |
+ |
6196 |
+-struct pv_mmu_ops pv_mmu_ops = { |
6197 |
++struct pv_mmu_ops pv_mmu_ops __read_only = { |
6198 |
+ .pagetable_setup_start = native_pagetable_setup_start, |
6199 |
+ .pagetable_setup_done = native_pagetable_setup_done, |
6200 |
+ |
6201 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/process_32.c linux-2.6.24.4/arch/x86/kernel/process_32.c |
6202 |
+--- linux-2.6.24.4/arch/x86/kernel/process_32.c 2008-03-24 14:49:18.000000000 -0400 |
6203 |
++++ linux-2.6.24.4/arch/x86/kernel/process_32.c 2008-03-26 17:56:55.000000000 -0400 |
6204 |
+@@ -66,15 +66,17 @@ EXPORT_SYMBOL(boot_option_idle_override) |
6205 |
+ DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; |
6206 |
+ EXPORT_PER_CPU_SYMBOL(current_task); |
6207 |
+ |
6208 |
++#ifdef CONFIG_SMP |
6209 |
+ DEFINE_PER_CPU(int, cpu_number); |
6210 |
+ EXPORT_PER_CPU_SYMBOL(cpu_number); |
6211 |
++#endif |
6212 |
+ |
6213 |
+ /* |
6214 |
+ * Return saved PC of a blocked thread. |
6215 |
+ */ |
6216 |
+ unsigned long thread_saved_pc(struct task_struct *tsk) |
6217 |
+ { |
6218 |
+- return ((unsigned long *)tsk->thread.esp)[3]; |
6219 |
++ return tsk->thread.eip; |
6220 |
+ } |
6221 |
+ |
6222 |
+ /* |
6223 |
+@@ -313,7 +315,7 @@ void __show_registers(struct pt_regs *re |
6224 |
+ unsigned long esp; |
6225 |
+ unsigned short ss, gs; |
6226 |
+ |
6227 |
+- if (user_mode_vm(regs)) { |
6228 |
++ if (user_mode(regs)) { |
6229 |
+ esp = regs->esp; |
6230 |
+ ss = regs->xss & 0xffff; |
6231 |
+ savesegment(gs, gs); |
6232 |
+@@ -391,8 +393,8 @@ int kernel_thread(int (*fn)(void *), voi |
6233 |
+ regs.ebx = (unsigned long) fn; |
6234 |
+ regs.edx = (unsigned long) arg; |
6235 |
+ |
6236 |
+- regs.xds = __USER_DS; |
6237 |
+- regs.xes = __USER_DS; |
6238 |
++ regs.xds = __KERNEL_DS; |
6239 |
++ regs.xes = __KERNEL_DS; |
6240 |
+ regs.xfs = __KERNEL_PERCPU; |
6241 |
+ regs.orig_eax = -1; |
6242 |
+ regs.eip = (unsigned long) kernel_thread_helper; |
6243 |
+@@ -414,7 +416,7 @@ void exit_thread(void) |
6244 |
+ struct task_struct *tsk = current; |
6245 |
+ struct thread_struct *t = &tsk->thread; |
6246 |
+ int cpu = get_cpu(); |
6247 |
+- struct tss_struct *tss = &per_cpu(init_tss, cpu); |
6248 |
++ struct tss_struct *tss = init_tss + cpu; |
6249 |
+ |
6250 |
+ kfree(t->io_bitmap_ptr); |
6251 |
+ t->io_bitmap_ptr = NULL; |
6252 |
+@@ -435,6 +437,7 @@ void flush_thread(void) |
6253 |
+ { |
6254 |
+ struct task_struct *tsk = current; |
6255 |
+ |
6256 |
++ __asm__("mov %0,%%gs\n" : : "r" (0) : "memory"); |
6257 |
+ memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8); |
6258 |
+ memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); |
6259 |
+ clear_tsk_thread_flag(tsk, TIF_DEBUG); |
6260 |
+@@ -468,7 +471,7 @@ int copy_thread(int nr, unsigned long cl |
6261 |
+ struct task_struct *tsk; |
6262 |
+ int err; |
6263 |
+ |
6264 |
+- childregs = task_pt_regs(p); |
6265 |
++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8; |
6266 |
+ *childregs = *regs; |
6267 |
+ childregs->eax = 0; |
6268 |
+ childregs->esp = esp; |
6269 |
+@@ -510,6 +513,11 @@ int copy_thread(int nr, unsigned long cl |
6270 |
+ if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) |
6271 |
+ goto out; |
6272 |
+ |
6273 |
++#ifdef CONFIG_PAX_SEGMEXEC |
6274 |
++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE)) |
6275 |
++ goto out; |
6276 |
++#endif |
6277 |
++ |
6278 |
+ desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; |
6279 |
+ desc->a = LDT_entry_a(&info); |
6280 |
+ desc->b = LDT_entry_b(&info); |
6281 |
+@@ -696,7 +704,7 @@ struct task_struct fastcall * __switch_t |
6282 |
+ struct thread_struct *prev = &prev_p->thread, |
6283 |
+ *next = &next_p->thread; |
6284 |
+ int cpu = smp_processor_id(); |
6285 |
+- struct tss_struct *tss = &per_cpu(init_tss, cpu); |
6286 |
++ struct tss_struct *tss = init_tss + cpu; |
6287 |
+ |
6288 |
+ /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ |
6289 |
+ |
6290 |
+@@ -724,6 +732,11 @@ struct task_struct fastcall * __switch_t |
6291 |
+ */ |
6292 |
+ savesegment(gs, prev->gs); |
6293 |
+ |
6294 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
6295 |
++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit)) |
6296 |
++ __set_fs(task_thread_info(next_p)->addr_limit, cpu); |
6297 |
++#endif |
6298 |
++ |
6299 |
+ /* |
6300 |
+ * Load the per-thread Thread-Local Storage descriptor. |
6301 |
+ */ |
6302 |
+@@ -888,6 +901,12 @@ asmlinkage int sys_set_thread_area(struc |
6303 |
+ |
6304 |
+ if (copy_from_user(&info, u_info, sizeof(info))) |
6305 |
+ return -EFAULT; |
6306 |
++ |
6307 |
++#ifdef CONFIG_PAX_SEGMEXEC |
6308 |
++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE)) |
6309 |
++ return -EINVAL; |
6310 |
++#endif |
6311 |
++ |
6312 |
+ idx = info.entry_number; |
6313 |
+ |
6314 |
+ /* |
6315 |
+@@ -976,9 +995,27 @@ asmlinkage int sys_get_thread_area(struc |
6316 |
+ return 0; |
6317 |
+ } |
6318 |
+ |
6319 |
+-unsigned long arch_align_stack(unsigned long sp) |
6320 |
++#ifdef CONFIG_PAX_RANDKSTACK |
6321 |
++asmlinkage void pax_randomize_kstack(void) |
6322 |
+ { |
6323 |
+- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) |
6324 |
+- sp -= get_random_int() % 8192; |
6325 |
+- return sp & ~0xf; |
6326 |
++ struct thread_struct *thread = ¤t->thread; |
6327 |
++ unsigned long time; |
6328 |
++ |
6329 |
++ if (!randomize_va_space) |
6330 |
++ return; |
6331 |
++ |
6332 |
++ rdtscl(time); |
6333 |
++ |
6334 |
++ /* P4 seems to return a 0 LSB, ignore it */ |
6335 |
++#ifdef CONFIG_MPENTIUM4 |
6336 |
++ time &= 0x1EUL; |
6337 |
++ time <<= 2; |
6338 |
++#else |
6339 |
++ time &= 0xFUL; |
6340 |
++ time <<= 3; |
6341 |
++#endif |
6342 |
++ |
6343 |
++ thread->esp0 ^= time; |
6344 |
++ load_esp0(init_tss + smp_processor_id(), thread); |
6345 |
+ } |
6346 |
++#endif |
6347 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/process_64.c linux-2.6.24.4/arch/x86/kernel/process_64.c |
6348 |
+--- linux-2.6.24.4/arch/x86/kernel/process_64.c 2008-03-24 14:49:18.000000000 -0400 |
6349 |
++++ linux-2.6.24.4/arch/x86/kernel/process_64.c 2008-03-26 17:56:55.000000000 -0400 |
6350 |
+@@ -210,6 +210,8 @@ static inline void play_dead(void) |
6351 |
+ void cpu_idle (void) |
6352 |
+ { |
6353 |
+ current_thread_info()->status |= TS_POLLING; |
6354 |
++ current->stack_canary = pax_get_random_long(); |
6355 |
++ write_pda(stack_canary, current->stack_canary); |
6356 |
+ /* endless idle loop with no priority at all */ |
6357 |
+ while (1) { |
6358 |
+ tick_nohz_stop_sched_tick(); |
6359 |
+@@ -390,7 +392,7 @@ void exit_thread(void) |
6360 |
+ struct thread_struct *t = &me->thread; |
6361 |
+ |
6362 |
+ if (me->thread.io_bitmap_ptr) { |
6363 |
+- struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); |
6364 |
++ struct tss_struct *tss = init_tss + get_cpu(); |
6365 |
+ |
6366 |
+ kfree(t->io_bitmap_ptr); |
6367 |
+ t->io_bitmap_ptr = NULL; |
6368 |
+@@ -597,7 +599,7 @@ __switch_to(struct task_struct *prev_p, |
6369 |
+ struct thread_struct *prev = &prev_p->thread, |
6370 |
+ *next = &next_p->thread; |
6371 |
+ int cpu = smp_processor_id(); |
6372 |
+- struct tss_struct *tss = &per_cpu(init_tss, cpu); |
6373 |
++ struct tss_struct *tss = init_tss + cpu; |
6374 |
+ |
6375 |
+ /* we're going to use this soon, after a few expensive things */ |
6376 |
+ if (next_p->fpu_counter>5) |
6377 |
+@@ -672,7 +674,6 @@ __switch_to(struct task_struct *prev_p, |
6378 |
+ write_pda(kernelstack, |
6379 |
+ (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); |
6380 |
+ #ifdef CONFIG_CC_STACKPROTECTOR |
6381 |
+- write_pda(stack_canary, next_p->stack_canary); |
6382 |
+ /* |
6383 |
+ * Build time only check to make sure the stack_canary is at |
6384 |
+ * offset 40 in the pda; this is a gcc ABI requirement |
6385 |
+@@ -701,7 +702,7 @@ __switch_to(struct task_struct *prev_p, |
6386 |
+ */ |
6387 |
+ asmlinkage |
6388 |
+ long sys_execve(char __user *name, char __user * __user *argv, |
6389 |
+- char __user * __user *envp, struct pt_regs regs) |
6390 |
++ char __user * __user *envp, struct pt_regs *regs) |
6391 |
+ { |
6392 |
+ long error; |
6393 |
+ char * filename; |
6394 |
+@@ -710,7 +711,7 @@ long sys_execve(char __user *name, char |
6395 |
+ error = PTR_ERR(filename); |
6396 |
+ if (IS_ERR(filename)) |
6397 |
+ return error; |
6398 |
+- error = do_execve(filename, argv, envp, ®s); |
6399 |
++ error = do_execve(filename, argv, envp, regs); |
6400 |
+ if (error == 0) { |
6401 |
+ task_lock(current); |
6402 |
+ current->ptrace &= ~PT_DTRACE; |
6403 |
+@@ -906,10 +907,3 @@ int dump_task_regs(struct task_struct *t |
6404 |
+ |
6405 |
+ return 1; |
6406 |
+ } |
6407 |
+- |
6408 |
+-unsigned long arch_align_stack(unsigned long sp) |
6409 |
+-{ |
6410 |
+- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) |
6411 |
+- sp -= get_random_int() % 8192; |
6412 |
+- return sp & ~0xf; |
6413 |
+-} |
6414 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/ptrace_32.c linux-2.6.24.4/arch/x86/kernel/ptrace_32.c |
6415 |
+--- linux-2.6.24.4/arch/x86/kernel/ptrace_32.c 2008-03-24 14:49:18.000000000 -0400 |
6416 |
++++ linux-2.6.24.4/arch/x86/kernel/ptrace_32.c 2008-03-26 17:56:55.000000000 -0400 |
6417 |
+@@ -160,22 +160,20 @@ static unsigned long convert_eip_to_line |
6418 |
+ * and APM bios ones we just ignore here. |
6419 |
+ */ |
6420 |
+ if (seg & LDT_SEGMENT) { |
6421 |
+- u32 *desc; |
6422 |
++ struct desc_struct *desc; |
6423 |
+ unsigned long base; |
6424 |
+ |
6425 |
+- seg &= ~7UL; |
6426 |
++ seg >>= 3; |
6427 |
+ |
6428 |
+ mutex_lock(&child->mm->context.lock); |
6429 |
+- if (unlikely((seg >> 3) >= child->mm->context.size)) |
6430 |
+- addr = -1L; /* bogus selector, access would fault */ |
6431 |
++ if (unlikely(seg >= child->mm->context.size)) |
6432 |
++ addr = -EINVAL; |
6433 |
+ else { |
6434 |
+- desc = child->mm->context.ldt + seg; |
6435 |
+- base = ((desc[0] >> 16) | |
6436 |
+- ((desc[1] & 0xff) << 16) | |
6437 |
+- (desc[1] & 0xff000000)); |
6438 |
++ desc = &child->mm->context.ldt[seg]; |
6439 |
++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000); |
6440 |
+ |
6441 |
+ /* 16-bit code segment? */ |
6442 |
+- if (!((desc[1] >> 22) & 1)) |
6443 |
++ if (!((desc->b >> 22) & 1)) |
6444 |
+ addr &= 0xffff; |
6445 |
+ addr += base; |
6446 |
+ } |
6447 |
+@@ -190,6 +188,9 @@ static inline int is_setting_trap_flag(s |
6448 |
+ unsigned char opcode[15]; |
6449 |
+ unsigned long addr = convert_eip_to_linear(child, regs); |
6450 |
+ |
6451 |
++ if (addr == -EINVAL) |
6452 |
++ return 0; |
6453 |
++ |
6454 |
+ copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); |
6455 |
+ for (i = 0; i < copied; i++) { |
6456 |
+ switch (opcode[i]) { |
6457 |
+@@ -340,6 +341,11 @@ ptrace_set_thread_area(struct task_struc |
6458 |
+ if (copy_from_user(&info, user_desc, sizeof(info))) |
6459 |
+ return -EFAULT; |
6460 |
+ |
6461 |
++#ifdef CONFIG_PAX_SEGMEXEC |
6462 |
++ if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE)) |
6463 |
++ return -EINVAL; |
6464 |
++#endif |
6465 |
++ |
6466 |
+ if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) |
6467 |
+ return -EINVAL; |
6468 |
+ |
6469 |
+@@ -419,7 +425,17 @@ long arch_ptrace(struct task_struct *chi |
6470 |
+ if(addr == (long) &dummy->u_debugreg[5]) break; |
6471 |
+ if(addr < (long) &dummy->u_debugreg[4] && |
6472 |
+ ((unsigned long) data) >= TASK_SIZE-3) break; |
6473 |
+- |
6474 |
++ |
6475 |
++#ifdef CONFIG_GRKERNSEC |
6476 |
++ if(addr >= (long) &dummy->u_debugreg[0] && |
6477 |
++ addr <= (long) &dummy->u_debugreg[3]) { |
6478 |
++ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2; |
6479 |
++ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3; |
6480 |
++ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3; |
6481 |
++ if ((type & 1) && (data & align)) |
6482 |
++ break; |
6483 |
++ } |
6484 |
++#endif |
6485 |
+ /* Sanity-check data. Take one half-byte at once with |
6486 |
+ * check = (val >> (16 + 4*i)) & 0xf. It contains the |
6487 |
+ * R/Wi and LENi bits; bits 0 and 1 are R/Wi, and bits |
6488 |
+@@ -630,7 +646,7 @@ void send_sigtrap(struct task_struct *ts |
6489 |
+ info.si_code = TRAP_BRKPT; |
6490 |
+ |
6491 |
+ /* User-mode eip? */ |
6492 |
+- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL; |
6493 |
++ info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL; |
6494 |
+ |
6495 |
+ /* Send us the fake SIGTRAP */ |
6496 |
+ force_sig_info(SIGTRAP, &info, tsk); |
6497 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/ptrace_64.c linux-2.6.24.4/arch/x86/kernel/ptrace_64.c |
6498 |
+--- linux-2.6.24.4/arch/x86/kernel/ptrace_64.c 2008-03-24 14:49:18.000000000 -0400 |
6499 |
++++ linux-2.6.24.4/arch/x86/kernel/ptrace_64.c 2008-03-26 17:56:55.000000000 -0400 |
6500 |
+@@ -98,22 +98,20 @@ unsigned long convert_rip_to_linear(stru |
6501 |
+ * and APM bios ones we just ignore here. |
6502 |
+ */ |
6503 |
+ if (seg & LDT_SEGMENT) { |
6504 |
+- u32 *desc; |
6505 |
++ struct desc_struct *desc; |
6506 |
+ unsigned long base; |
6507 |
+ |
6508 |
+- seg &= ~7UL; |
6509 |
++ seg >>= 3; |
6510 |
+ |
6511 |
+ mutex_lock(&child->mm->context.lock); |
6512 |
+- if (unlikely((seg >> 3) >= child->mm->context.size)) |
6513 |
+- addr = -1L; /* bogus selector, access would fault */ |
6514 |
++ if (unlikely(seg >= child->mm->context.size)) |
6515 |
++ addr = -EINVAL; /* bogus selector, access would fault */ |
6516 |
+ else { |
6517 |
+- desc = child->mm->context.ldt + seg; |
6518 |
+- base = ((desc[0] >> 16) | |
6519 |
+- ((desc[1] & 0xff) << 16) | |
6520 |
+- (desc[1] & 0xff000000)); |
6521 |
++ desc = &child->mm->context.ldt[seg]; |
6522 |
++ base = desc->base0 | (desc->base1 << 16) | (desc->base2 << 24); |
6523 |
+ |
6524 |
+ /* 16-bit code segment? */ |
6525 |
+- if (!((desc[1] >> 22) & 1)) |
6526 |
++ if (!desc->d) |
6527 |
+ addr &= 0xffff; |
6528 |
+ addr += base; |
6529 |
+ } |
6530 |
+@@ -129,6 +127,9 @@ static int is_setting_trap_flag(struct t |
6531 |
+ unsigned char opcode[15]; |
6532 |
+ unsigned long addr = convert_rip_to_linear(child, regs); |
6533 |
+ |
6534 |
++ if (addr == -EINVAL) |
6535 |
++ return 0; |
6536 |
++ |
6537 |
+ copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); |
6538 |
+ for (i = 0; i < copied; i++) { |
6539 |
+ switch (opcode[i]) { |
6540 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/reboot_32.c linux-2.6.24.4/arch/x86/kernel/reboot_32.c |
6541 |
+--- linux-2.6.24.4/arch/x86/kernel/reboot_32.c 2008-03-24 14:49:18.000000000 -0400 |
6542 |
++++ linux-2.6.24.4/arch/x86/kernel/reboot_32.c 2008-03-26 17:56:55.000000000 -0400 |
6543 |
+@@ -23,7 +23,7 @@ |
6544 |
+ void (*pm_power_off)(void); |
6545 |
+ EXPORT_SYMBOL(pm_power_off); |
6546 |
+ |
6547 |
+-static int reboot_mode; |
6548 |
++static unsigned short reboot_mode; |
6549 |
+ static int reboot_thru_bios; |
6550 |
+ |
6551 |
+ #ifdef CONFIG_SMP |
6552 |
+@@ -135,7 +135,7 @@ static struct dmi_system_id __initdata r |
6553 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), |
6554 |
+ }, |
6555 |
+ }, |
6556 |
+- { } |
6557 |
++ { NULL, NULL, {{0, NULL}}, NULL} |
6558 |
+ }; |
6559 |
+ |
6560 |
+ static int __init reboot_init(void) |
6561 |
+@@ -153,18 +153,18 @@ core_initcall(reboot_init); |
6562 |
+ doesn't work with at least one type of 486 motherboard. It is easy |
6563 |
+ to stop this code working; hence the copious comments. */ |
6564 |
+ |
6565 |
+-static unsigned long long |
6566 |
+-real_mode_gdt_entries [3] = |
6567 |
++static struct desc_struct |
6568 |
++real_mode_gdt_entries [3] __read_only = |
6569 |
+ { |
6570 |
+- 0x0000000000000000ULL, /* Null descriptor */ |
6571 |
+- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */ |
6572 |
+- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ |
6573 |
++ {0x00000000, 0x00000000}, /* Null descriptor */ |
6574 |
++ {0x0000ffff, 0x00009b00}, /* 16-bit real-mode 64k code at 0x00000000 */ |
6575 |
++ {0x0100ffff, 0x00009300} /* 16-bit real-mode 64k data at 0x00000100 */ |
6576 |
+ }; |
6577 |
+ |
6578 |
+-static struct Xgt_desc_struct |
6579 |
+-real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries }, |
6580 |
+-real_mode_idt = { 0x3ff, 0 }, |
6581 |
+-no_idt = { 0, 0 }; |
6582 |
++static const struct Xgt_desc_struct |
6583 |
++real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (struct desc_struct *)__pa(real_mode_gdt_entries), 0 }, |
6584 |
++real_mode_idt = { 0x3ff, NULL, 0 }, |
6585 |
++no_idt = { 0, NULL, 0 }; |
6586 |
+ |
6587 |
+ |
6588 |
+ /* This is 16-bit protected mode code to disable paging and the cache, |
6589 |
+@@ -186,7 +186,7 @@ no_idt = { 0, 0 }; |
6590 |
+ More could be done here to set up the registers as if a CPU reset had |
6591 |
+ occurred; hopefully real BIOSs don't assume much. */ |
6592 |
+ |
6593 |
+-static unsigned char real_mode_switch [] = |
6594 |
++static const unsigned char real_mode_switch [] = |
6595 |
+ { |
6596 |
+ 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */ |
6597 |
+ 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */ |
6598 |
+@@ -200,7 +200,7 @@ static unsigned char real_mode_switch [] |
6599 |
+ 0x24, 0x10, /* f: andb $0x10,al */ |
6600 |
+ 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */ |
6601 |
+ }; |
6602 |
+-static unsigned char jump_to_bios [] = |
6603 |
++static const unsigned char jump_to_bios [] = |
6604 |
+ { |
6605 |
+ 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */ |
6606 |
+ }; |
6607 |
+@@ -210,7 +210,7 @@ static unsigned char jump_to_bios [] = |
6608 |
+ * specified by the code and length parameters. |
6609 |
+ * We assume that length will aways be less that 100! |
6610 |
+ */ |
6611 |
+-void machine_real_restart(unsigned char *code, int length) |
6612 |
++void machine_real_restart(const unsigned char *code, unsigned int length) |
6613 |
+ { |
6614 |
+ local_irq_disable(); |
6615 |
+ |
6616 |
+@@ -232,8 +232,8 @@ void machine_real_restart(unsigned char |
6617 |
+ from the kernel segment. This assumes the kernel segment starts at |
6618 |
+ virtual address PAGE_OFFSET. */ |
6619 |
+ |
6620 |
+- memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, |
6621 |
+- sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS); |
6622 |
++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, |
6623 |
++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); |
6624 |
+ |
6625 |
+ /* |
6626 |
+ * Use `swapper_pg_dir' as our page directory. |
6627 |
+@@ -246,7 +246,7 @@ void machine_real_restart(unsigned char |
6628 |
+ REBOOT.COM programs, and the previous reset routine did this |
6629 |
+ too. */ |
6630 |
+ |
6631 |
+- *((unsigned short *)0x472) = reboot_mode; |
6632 |
++ *(unsigned short *)(__va(0x472)) = reboot_mode; |
6633 |
+ |
6634 |
+ /* For the switch to real mode, copy some code to low memory. It has |
6635 |
+ to be in the first 64k because it is running in 16-bit mode, and it |
6636 |
+@@ -254,9 +254,8 @@ void machine_real_restart(unsigned char |
6637 |
+ off paging. Copy it near the end of the first page, out of the way |
6638 |
+ of BIOS variables. */ |
6639 |
+ |
6640 |
+- memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100), |
6641 |
+- real_mode_switch, sizeof (real_mode_switch)); |
6642 |
+- memcpy ((void *) (0x1000 - 100), code, length); |
6643 |
++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch)); |
6644 |
++ memcpy(__va(0x1000 - 100), code, length); |
6645 |
+ |
6646 |
+ /* Set up the IDT for real mode. */ |
6647 |
+ |
6648 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/setup_32.c linux-2.6.24.4/arch/x86/kernel/setup_32.c |
6649 |
+--- linux-2.6.24.4/arch/x86/kernel/setup_32.c 2008-03-24 14:49:18.000000000 -0400 |
6650 |
++++ linux-2.6.24.4/arch/x86/kernel/setup_32.c 2008-03-26 17:56:55.000000000 -0400 |
6651 |
+@@ -61,6 +61,7 @@ |
6652 |
+ #include <setup_arch.h> |
6653 |
+ #include <bios_ebda.h> |
6654 |
+ #include <asm/cacheflush.h> |
6655 |
++#include <asm/boot.h> |
6656 |
+ |
6657 |
+ /* This value is set up by the early boot code to point to the value |
6658 |
+ immediately after the boot time page tables. It contains a *physical* |
6659 |
+@@ -82,7 +83,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini |
6660 |
+ struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; |
6661 |
+ EXPORT_SYMBOL(boot_cpu_data); |
6662 |
+ |
6663 |
++#ifdef CONFIG_X86_PAE |
6664 |
++unsigned long mmu_cr4_features = X86_CR4_PAE; |
6665 |
++#else |
6666 |
+ unsigned long mmu_cr4_features; |
6667 |
++#endif |
6668 |
+ |
6669 |
+ /* for MCA, but anyone else can use it if they want */ |
6670 |
+ unsigned int machine_id; |
6671 |
+@@ -436,8 +441,8 @@ void __init setup_bootmem_allocator(void |
6672 |
+ * the (very unlikely) case of us accidentally initializing the |
6673 |
+ * bootmem allocator with an invalid RAM area. |
6674 |
+ */ |
6675 |
+- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) + |
6676 |
+- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text)); |
6677 |
++ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) + |
6678 |
++ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR); |
6679 |
+ |
6680 |
+ /* |
6681 |
+ * reserve physical page 0 - it's a special BIOS page on many boxes, |
6682 |
+@@ -590,14 +595,14 @@ void __init setup_arch(char **cmdline_p) |
6683 |
+ |
6684 |
+ if (!boot_params.hdr.root_flags) |
6685 |
+ root_mountflags &= ~MS_RDONLY; |
6686 |
+- init_mm.start_code = (unsigned long) _text; |
6687 |
+- init_mm.end_code = (unsigned long) _etext; |
6688 |
++ init_mm.start_code = ktla_ktva((unsigned long) _text); |
6689 |
++ init_mm.end_code = ktla_ktva((unsigned long) _etext); |
6690 |
+ init_mm.end_data = (unsigned long) _edata; |
6691 |
+ init_mm.brk = init_pg_tables_end + PAGE_OFFSET; |
6692 |
+ |
6693 |
+- code_resource.start = virt_to_phys(_text); |
6694 |
+- code_resource.end = virt_to_phys(_etext)-1; |
6695 |
+- data_resource.start = virt_to_phys(_etext); |
6696 |
++ code_resource.start = virt_to_phys(ktla_ktva(_text)); |
6697 |
++ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1; |
6698 |
++ data_resource.start = virt_to_phys(_data); |
6699 |
+ data_resource.end = virt_to_phys(_edata)-1; |
6700 |
+ bss_resource.start = virt_to_phys(&__bss_start); |
6701 |
+ bss_resource.end = virt_to_phys(&__bss_stop)-1; |
6702 |
+@@ -692,3 +697,23 @@ void __init setup_arch(char **cmdline_p) |
6703 |
+ #endif |
6704 |
+ #endif |
6705 |
+ } |
6706 |
++ |
6707 |
++unsigned long __per_cpu_offset[NR_CPUS] __read_only; |
6708 |
++ |
6709 |
++EXPORT_SYMBOL(__per_cpu_offset); |
6710 |
++ |
6711 |
++void __init setup_per_cpu_areas(void) |
6712 |
++{ |
6713 |
++ unsigned long size, i; |
6714 |
++ char *ptr; |
6715 |
++ |
6716 |
++ /* Copy section for each CPU (we discard the original) */ |
6717 |
++ size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE); |
6718 |
++ ptr = alloc_bootmem_pages(size * num_possible_cpus()); |
6719 |
++ |
6720 |
++ for_each_possible_cpu(i) { |
6721 |
++ __per_cpu_offset[i] = (unsigned long)ptr; |
6722 |
++ memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); |
6723 |
++ ptr += size; |
6724 |
++ } |
6725 |
++} |
6726 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/setup64.c linux-2.6.24.4/arch/x86/kernel/setup64.c |
6727 |
+--- linux-2.6.24.4/arch/x86/kernel/setup64.c 2008-03-24 14:49:18.000000000 -0400 |
6728 |
++++ linux-2.6.24.4/arch/x86/kernel/setup64.c 2008-03-26 17:56:55.000000000 -0400 |
6729 |
+@@ -32,12 +32,12 @@ struct x8664_pda *_cpu_pda[NR_CPUS] __re |
6730 |
+ EXPORT_SYMBOL(_cpu_pda); |
6731 |
+ struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned; |
6732 |
+ |
6733 |
+-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; |
6734 |
++const struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; |
6735 |
+ |
6736 |
+ char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); |
6737 |
+ |
6738 |
+ unsigned long __supported_pte_mask __read_mostly = ~0UL; |
6739 |
+-static int do_not_nx __cpuinitdata = 0; |
6740 |
++EXPORT_SYMBOL(__supported_pte_mask); |
6741 |
+ |
6742 |
+ /* noexec=on|off |
6743 |
+ Control non executable mappings for 64bit processes. |
6744 |
+@@ -51,16 +51,14 @@ static int __init nonx_setup(char *str) |
6745 |
+ return -EINVAL; |
6746 |
+ if (!strncmp(str, "on", 2)) { |
6747 |
+ __supported_pte_mask |= _PAGE_NX; |
6748 |
+- do_not_nx = 0; |
6749 |
+ } else if (!strncmp(str, "off", 3)) { |
6750 |
+- do_not_nx = 1; |
6751 |
+ __supported_pte_mask &= ~_PAGE_NX; |
6752 |
+ } |
6753 |
+ return 0; |
6754 |
+ } |
6755 |
+ early_param("noexec", nonx_setup); |
6756 |
+ |
6757 |
+-int force_personality32 = 0; |
6758 |
++int force_personality32; |
6759 |
+ |
6760 |
+ /* noexec32=on|off |
6761 |
+ Control non executable heap for 32bit processes. |
6762 |
+@@ -177,7 +175,7 @@ void __cpuinit check_efer(void) |
6763 |
+ unsigned long efer; |
6764 |
+ |
6765 |
+ rdmsrl(MSR_EFER, efer); |
6766 |
+- if (!(efer & EFER_NX) || do_not_nx) { |
6767 |
++ if (!(efer & EFER_NX)) { |
6768 |
+ __supported_pte_mask &= ~_PAGE_NX; |
6769 |
+ } |
6770 |
+ } |
6771 |
+@@ -200,12 +198,13 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist |
6772 |
+ void __cpuinit cpu_init (void) |
6773 |
+ { |
6774 |
+ int cpu = stack_smp_processor_id(); |
6775 |
+- struct tss_struct *t = &per_cpu(init_tss, cpu); |
6776 |
++ struct tss_struct *t = init_tss + cpu; |
6777 |
+ struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu); |
6778 |
+ unsigned long v; |
6779 |
+ char *estacks = NULL; |
6780 |
+ struct task_struct *me; |
6781 |
+ int i; |
6782 |
++ struct desc_ptr cpu_gdt_descr = { .size = GDT_SIZE - 1, .address = (unsigned long)cpu_gdt_table[cpu]}; |
6783 |
+ |
6784 |
+ /* CPU 0 is initialised in head64.c */ |
6785 |
+ if (cpu != 0) { |
6786 |
+@@ -223,14 +222,12 @@ void __cpuinit cpu_init (void) |
6787 |
+ clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); |
6788 |
+ |
6789 |
+ /* |
6790 |
+- * Initialize the per-CPU GDT with the boot GDT, |
6791 |
+- * and set up the GDT descriptor: |
6792 |
++ * Initialize the per-CPU GDT with the boot GDT: |
6793 |
+ */ |
6794 |
+ if (cpu) |
6795 |
+ memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE); |
6796 |
+ |
6797 |
+- cpu_gdt_descr[cpu].size = GDT_SIZE; |
6798 |
+- load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]); |
6799 |
++ load_gdt(&cpu_gdt_descr); |
6800 |
+ load_idt((const struct desc_ptr *)&idt_descr); |
6801 |
+ |
6802 |
+ memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8); |
6803 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/signal_32.c linux-2.6.24.4/arch/x86/kernel/signal_32.c |
6804 |
+--- linux-2.6.24.4/arch/x86/kernel/signal_32.c 2008-03-24 14:49:18.000000000 -0400 |
6805 |
++++ linux-2.6.24.4/arch/x86/kernel/signal_32.c 2008-03-26 17:56:55.000000000 -0400 |
6806 |
+@@ -355,9 +355,9 @@ static int setup_frame(int sig, struct k |
6807 |
+ } |
6808 |
+ |
6809 |
+ if (current->binfmt->hasvdso) |
6810 |
+- restorer = (void *)VDSO_SYM(&__kernel_sigreturn); |
6811 |
++ restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn); |
6812 |
+ else |
6813 |
+- restorer = (void *)&frame->retcode; |
6814 |
++ restorer = (void __user *)&frame->retcode; |
6815 |
+ if (ka->sa.sa_flags & SA_RESTORER) |
6816 |
+ restorer = ka->sa.sa_restorer; |
6817 |
+ |
6818 |
+@@ -452,7 +452,7 @@ static int setup_rt_frame(int sig, struc |
6819 |
+ goto give_sigsegv; |
6820 |
+ |
6821 |
+ /* Set up to return from userspace. */ |
6822 |
+- restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn); |
6823 |
++ restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn); |
6824 |
+ if (ka->sa.sa_flags & SA_RESTORER) |
6825 |
+ restorer = ka->sa.sa_restorer; |
6826 |
+ err |= __put_user(restorer, &frame->pretcode); |
6827 |
+@@ -584,7 +584,7 @@ static void fastcall do_signal(struct pt |
6828 |
+ * before reaching here, so testing against kernel |
6829 |
+ * CS suffices. |
6830 |
+ */ |
6831 |
+- if (!user_mode(regs)) |
6832 |
++ if (!user_mode_novm(regs)) |
6833 |
+ return; |
6834 |
+ |
6835 |
+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
6836 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/signal_64.c linux-2.6.24.4/arch/x86/kernel/signal_64.c |
6837 |
+--- linux-2.6.24.4/arch/x86/kernel/signal_64.c 2008-03-24 14:49:18.000000000 -0400 |
6838 |
++++ linux-2.6.24.4/arch/x86/kernel/signal_64.c 2008-03-26 17:56:55.000000000 -0400 |
6839 |
+@@ -252,8 +252,8 @@ static int setup_rt_frame(int sig, struc |
6840 |
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me); |
6841 |
+ err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate); |
6842 |
+ if (sizeof(*set) == 16) { |
6843 |
+- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); |
6844 |
+- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); |
6845 |
++ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); |
6846 |
++ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); |
6847 |
+ } else |
6848 |
+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
6849 |
+ |
6850 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/smp_32.c linux-2.6.24.4/arch/x86/kernel/smp_32.c |
6851 |
+--- linux-2.6.24.4/arch/x86/kernel/smp_32.c 2008-03-24 14:49:18.000000000 -0400 |
6852 |
++++ linux-2.6.24.4/arch/x86/kernel/smp_32.c 2008-03-26 17:56:55.000000000 -0400 |
6853 |
+@@ -104,7 +104,7 @@ |
6854 |
+ * about nothing of note with C stepping upwards. |
6855 |
+ */ |
6856 |
+ |
6857 |
+-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, }; |
6858 |
++DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} }; |
6859 |
+ |
6860 |
+ /* |
6861 |
+ * the following functions deal with sending IPIs between CPUs. |
6862 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/smpboot_32.c linux-2.6.24.4/arch/x86/kernel/smpboot_32.c |
6863 |
+--- linux-2.6.24.4/arch/x86/kernel/smpboot_32.c 2008-03-24 14:49:18.000000000 -0400 |
6864 |
++++ linux-2.6.24.4/arch/x86/kernel/smpboot_32.c 2008-03-26 17:56:55.000000000 -0400 |
6865 |
+@@ -781,6 +781,10 @@ static int __cpuinit do_boot_cpu(int api |
6866 |
+ unsigned long start_eip; |
6867 |
+ unsigned short nmi_high = 0, nmi_low = 0; |
6868 |
+ |
6869 |
++#ifdef CONFIG_PAX_KERNEXEC |
6870 |
++ unsigned long cr0; |
6871 |
++#endif |
6872 |
++ |
6873 |
+ /* |
6874 |
+ * Save current MTRR state in case it was changed since early boot |
6875 |
+ * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync: |
6876 |
+@@ -797,7 +801,16 @@ static int __cpuinit do_boot_cpu(int api |
6877 |
+ |
6878 |
+ init_gdt(cpu); |
6879 |
+ per_cpu(current_task, cpu) = idle; |
6880 |
+- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
6881 |
++ |
6882 |
++#ifdef CONFIG_PAX_KERNEXEC |
6883 |
++ pax_open_kernel(cr0); |
6884 |
++#endif |
6885 |
++ |
6886 |
++ early_gdt_descr.address = get_cpu_gdt_table(cpu); |
6887 |
++ |
6888 |
++#ifdef CONFIG_PAX_KERNEXEC |
6889 |
++ pax_close_kernel(cr0); |
6890 |
++#endif |
6891 |
+ |
6892 |
+ idle->thread.eip = (unsigned long) start_secondary; |
6893 |
+ /* start_eip had better be page-aligned! */ |
6894 |
+@@ -1122,7 +1135,7 @@ static void __init smp_boot_cpus(unsigne |
6895 |
+ * construct cpu_sibling_map, so that we can tell sibling CPUs |
6896 |
+ * efficiently. |
6897 |
+ */ |
6898 |
+- for (cpu = 0; cpu < NR_CPUS; cpu++) { |
6899 |
++ for_each_possible_cpu(cpu) { |
6900 |
+ cpus_clear(per_cpu(cpu_sibling_map, cpu)); |
6901 |
+ cpus_clear(per_cpu(cpu_core_map, cpu)); |
6902 |
+ } |
6903 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/smpboot_64.c linux-2.6.24.4/arch/x86/kernel/smpboot_64.c |
6904 |
+--- linux-2.6.24.4/arch/x86/kernel/smpboot_64.c 2008-03-24 14:49:18.000000000 -0400 |
6905 |
++++ linux-2.6.24.4/arch/x86/kernel/smpboot_64.c 2008-03-26 17:56:55.000000000 -0400 |
6906 |
+@@ -549,13 +549,6 @@ static int __cpuinit do_boot_cpu(int cpu |
6907 |
+ .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), |
6908 |
+ }; |
6909 |
+ |
6910 |
+- /* allocate memory for gdts of secondary cpus. Hotplug is considered */ |
6911 |
+- if (!cpu_gdt_descr[cpu].address && |
6912 |
+- !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) { |
6913 |
+- printk(KERN_ERR "Failed to allocate GDT for CPU %d\n", cpu); |
6914 |
+- return -1; |
6915 |
+- } |
6916 |
+- |
6917 |
+ /* Allocate node local memory for AP pdas */ |
6918 |
+ if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) { |
6919 |
+ struct x8664_pda *newpda, *pda; |
6920 |
+@@ -614,7 +607,7 @@ do_rest: |
6921 |
+ start_rip = setup_trampoline(); |
6922 |
+ |
6923 |
+ init_rsp = c_idle.idle->thread.rsp; |
6924 |
+- per_cpu(init_tss,cpu).rsp0 = init_rsp; |
6925 |
++ init_tss[cpu].rsp0 = init_rsp; |
6926 |
+ initial_code = start_secondary; |
6927 |
+ clear_tsk_thread_flag(c_idle.idle, TIF_FORK); |
6928 |
+ |
6929 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/smpcommon_32.c linux-2.6.24.4/arch/x86/kernel/smpcommon_32.c |
6930 |
+--- linux-2.6.24.4/arch/x86/kernel/smpcommon_32.c 2008-03-24 14:49:18.000000000 -0400 |
6931 |
++++ linux-2.6.24.4/arch/x86/kernel/smpcommon_32.c 2008-03-26 17:56:55.000000000 -0400 |
6932 |
+@@ -3,6 +3,7 @@ |
6933 |
+ */ |
6934 |
+ #include <linux/module.h> |
6935 |
+ #include <asm/smp.h> |
6936 |
++#include <asm/sections.h> |
6937 |
+ |
6938 |
+ DEFINE_PER_CPU(unsigned long, this_cpu_off); |
6939 |
+ EXPORT_PER_CPU_SYMBOL(this_cpu_off); |
6940 |
+@@ -14,10 +15,29 @@ __cpuinit void init_gdt(int cpu) |
6941 |
+ { |
6942 |
+ struct desc_struct *gdt = get_cpu_gdt_table(cpu); |
6943 |
+ |
6944 |
+- pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a, |
6945 |
+- (u32 *)&gdt[GDT_ENTRY_PERCPU].b, |
6946 |
+- __per_cpu_offset[cpu], 0xFFFFF, |
6947 |
+- 0x80 | DESCTYPE_S | 0x2, 0x8); |
6948 |
++#ifdef CONFIG_PAX_KERNEXEC |
6949 |
++ unsigned long cr0; |
6950 |
++ |
6951 |
++ pax_open_kernel(cr0); |
6952 |
++#endif |
6953 |
++ |
6954 |
++ if (cpu) |
6955 |
++ memcpy(gdt, cpu_gdt_table, GDT_SIZE); |
6956 |
++ |
6957 |
++ if (PERCPU_ENOUGH_ROOM <= 64*1024*1024) |
6958 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a, |
6959 |
++ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b, |
6960 |
++ __per_cpu_offset[cpu], PERCPU_ENOUGH_ROOM-1, |
6961 |
++ 0x80 | DESCTYPE_S | 0x3, 0x4); |
6962 |
++ else |
6963 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a, |
6964 |
++ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b, |
6965 |
++ __per_cpu_offset[cpu], ((PERCPU_ENOUGH_ROOM-1) >> PAGE_SHIFT), |
6966 |
++ 0x80 | DESCTYPE_S | 0x3, 0xC); |
6967 |
++ |
6968 |
++#ifdef CONFIG_PAX_KERNEXEC |
6969 |
++ pax_close_kernel(cr0); |
6970 |
++#endif |
6971 |
+ |
6972 |
+ per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; |
6973 |
+ per_cpu(cpu_number, cpu) = cpu; |
6974 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/suspend_64.c linux-2.6.24.4/arch/x86/kernel/suspend_64.c |
6975 |
+--- linux-2.6.24.4/arch/x86/kernel/suspend_64.c 2008-03-24 14:49:18.000000000 -0400 |
6976 |
++++ linux-2.6.24.4/arch/x86/kernel/suspend_64.c 2008-03-26 17:56:55.000000000 -0400 |
6977 |
+@@ -116,12 +116,22 @@ void restore_processor_state(void) |
6978 |
+ void fix_processor_context(void) |
6979 |
+ { |
6980 |
+ int cpu = smp_processor_id(); |
6981 |
+- struct tss_struct *t = &per_cpu(init_tss, cpu); |
6982 |
++ struct tss_struct *t = init_tss + cpu; |
6983 |
++ |
6984 |
++#ifdef CONFIG_PAX_KERNEXEC |
6985 |
++ unsigned long cr0; |
6986 |
++ |
6987 |
++ pax_open_kernel(cr0); |
6988 |
++#endif |
6989 |
+ |
6990 |
+ 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. */ |
6991 |
+ |
6992 |
+ cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9; |
6993 |
+ |
6994 |
++#ifdef CONFIG_PAX_KERNEXEC |
6995 |
++ pax_close_kernel(cr0); |
6996 |
++#endif |
6997 |
++ |
6998 |
+ syscall_init(); /* This sets MSR_*STAR and related */ |
6999 |
+ load_TR_desc(); /* This does ltr */ |
7000 |
+ load_LDT(¤t->active_mm->context); /* This does lldt */ |
7001 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/syscall_table_32.S linux-2.6.24.4/arch/x86/kernel/syscall_table_32.S |
7002 |
+--- linux-2.6.24.4/arch/x86/kernel/syscall_table_32.S 2008-03-24 14:49:18.000000000 -0400 |
7003 |
++++ linux-2.6.24.4/arch/x86/kernel/syscall_table_32.S 2008-03-26 17:56:55.000000000 -0400 |
7004 |
+@@ -1,3 +1,4 @@ |
7005 |
++.section .rodata,"a",@progbits |
7006 |
+ ENTRY(sys_call_table) |
7007 |
+ .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ |
7008 |
+ .long sys_exit |
7009 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/sysenter_32.c linux-2.6.24.4/arch/x86/kernel/sysenter_32.c |
7010 |
+--- linux-2.6.24.4/arch/x86/kernel/sysenter_32.c 2008-03-24 14:49:18.000000000 -0400 |
7011 |
++++ linux-2.6.24.4/arch/x86/kernel/sysenter_32.c 2008-03-26 17:56:55.000000000 -0400 |
7012 |
+@@ -175,7 +175,7 @@ static __init void relocate_vdso(Elf32_E |
7013 |
+ void enable_sep_cpu(void) |
7014 |
+ { |
7015 |
+ int cpu = get_cpu(); |
7016 |
+- struct tss_struct *tss = &per_cpu(init_tss, cpu); |
7017 |
++ struct tss_struct *tss = init_tss + cpu; |
7018 |
+ |
7019 |
+ if (!boot_cpu_has(X86_FEATURE_SEP)) { |
7020 |
+ put_cpu(); |
7021 |
+@@ -198,7 +198,7 @@ static int __init gate_vma_init(void) |
7022 |
+ gate_vma.vm_start = FIXADDR_USER_START; |
7023 |
+ gate_vma.vm_end = FIXADDR_USER_END; |
7024 |
+ gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; |
7025 |
+- gate_vma.vm_page_prot = __P101; |
7026 |
++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags); |
7027 |
+ /* |
7028 |
+ * Make sure the vDSO gets into every core dump. |
7029 |
+ * Dumping its contents makes post-mortem fully interpretable later |
7030 |
+@@ -281,7 +281,7 @@ int arch_setup_additional_pages(struct l |
7031 |
+ if (compat) |
7032 |
+ addr = VDSO_HIGH_BASE; |
7033 |
+ else { |
7034 |
+- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); |
7035 |
++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE); |
7036 |
+ if (IS_ERR_VALUE(addr)) { |
7037 |
+ ret = addr; |
7038 |
+ goto up_fail; |
7039 |
+@@ -306,7 +306,7 @@ int arch_setup_additional_pages(struct l |
7040 |
+ goto up_fail; |
7041 |
+ } |
7042 |
+ |
7043 |
+- current->mm->context.vdso = (void *)addr; |
7044 |
++ current->mm->context.vdso = addr; |
7045 |
+ current_thread_info()->sysenter_return = |
7046 |
+ (void *)VDSO_SYM(&SYSENTER_RETURN); |
7047 |
+ |
7048 |
+@@ -318,8 +318,14 @@ int arch_setup_additional_pages(struct l |
7049 |
+ |
7050 |
+ const char *arch_vma_name(struct vm_area_struct *vma) |
7051 |
+ { |
7052 |
+- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) |
7053 |
++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso) |
7054 |
+ return "[vdso]"; |
7055 |
++ |
7056 |
++#ifdef CONFIG_PAX_SEGMEXEC |
7057 |
++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso) |
7058 |
++ return "[vdso]"; |
7059 |
++#endif |
7060 |
++ |
7061 |
+ return NULL; |
7062 |
+ } |
7063 |
+ |
7064 |
+@@ -328,7 +334,7 @@ struct vm_area_struct *get_gate_vma(stru |
7065 |
+ struct mm_struct *mm = tsk->mm; |
7066 |
+ |
7067 |
+ /* Check to see if this task was created in compat vdso mode */ |
7068 |
+- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE) |
7069 |
++ if (mm && mm->context.vdso == VDSO_HIGH_BASE) |
7070 |
+ return &gate_vma; |
7071 |
+ return NULL; |
7072 |
+ } |
7073 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/sys_i386_32.c linux-2.6.24.4/arch/x86/kernel/sys_i386_32.c |
7074 |
+--- linux-2.6.24.4/arch/x86/kernel/sys_i386_32.c 2008-03-24 14:49:18.000000000 -0400 |
7075 |
++++ linux-2.6.24.4/arch/x86/kernel/sys_i386_32.c 2008-03-26 17:56:55.000000000 -0400 |
7076 |
+@@ -39,6 +39,21 @@ asmlinkage int sys_pipe(unsigned long __ |
7077 |
+ return error; |
7078 |
+ } |
7079 |
+ |
7080 |
++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) |
7081 |
++{ |
7082 |
++ unsigned long task_size = TASK_SIZE; |
7083 |
++ |
7084 |
++#ifdef CONFIG_PAX_SEGMEXEC |
7085 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) |
7086 |
++ task_size = SEGMEXEC_TASK_SIZE; |
7087 |
++#endif |
7088 |
++ |
7089 |
++ if (len > task_size || addr > task_size - len) |
7090 |
++ return -EINVAL; |
7091 |
++ |
7092 |
++ return 0; |
7093 |
++} |
7094 |
++ |
7095 |
+ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, |
7096 |
+ unsigned long prot, unsigned long flags, |
7097 |
+ unsigned long fd, unsigned long pgoff) |
7098 |
+@@ -98,6 +113,205 @@ out: |
7099 |
+ return err; |
7100 |
+ } |
7101 |
+ |
7102 |
++unsigned long |
7103 |
++arch_get_unmapped_area(struct file *filp, unsigned long addr, |
7104 |
++ unsigned long len, unsigned long pgoff, unsigned long flags) |
7105 |
++{ |
7106 |
++ struct mm_struct *mm = current->mm; |
7107 |
++ struct vm_area_struct *vma; |
7108 |
++ unsigned long start_addr, task_size = TASK_SIZE; |
7109 |
++ |
7110 |
++#ifdef CONFIG_PAX_SEGMEXEC |
7111 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
7112 |
++ task_size = SEGMEXEC_TASK_SIZE; |
7113 |
++#endif |
7114 |
++ |
7115 |
++ if (len > task_size) |
7116 |
++ return -ENOMEM; |
7117 |
++ |
7118 |
++ if (flags & MAP_FIXED) |
7119 |
++ return addr; |
7120 |
++ |
7121 |
++#ifdef CONFIG_PAX_RANDMMAP |
7122 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
7123 |
++#endif |
7124 |
++ |
7125 |
++ if (addr) { |
7126 |
++ addr = PAGE_ALIGN(addr); |
7127 |
++ vma = find_vma(mm, addr); |
7128 |
++ if (task_size - len >= addr && |
7129 |
++ (!vma || addr + len <= vma->vm_start)) |
7130 |
++ return addr; |
7131 |
++ } |
7132 |
++ if (len > mm->cached_hole_size) { |
7133 |
++ start_addr = addr = mm->free_area_cache; |
7134 |
++ } else { |
7135 |
++ start_addr = addr = mm->mmap_base; |
7136 |
++ mm->cached_hole_size = 0; |
7137 |
++ } |
7138 |
++ |
7139 |
++#ifdef CONFIG_PAX_PAGEEXEC |
7140 |
++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) { |
7141 |
++ start_addr = 0x00110000UL; |
7142 |
++ |
7143 |
++#ifdef CONFIG_PAX_RANDMMAP |
7144 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
7145 |
++ start_addr += mm->delta_mmap & 0x03FFF000UL; |
7146 |
++#endif |
7147 |
++ |
7148 |
++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base) |
7149 |
++ start_addr = addr = mm->mmap_base; |
7150 |
++ else |
7151 |
++ addr = start_addr; |
7152 |
++ } |
7153 |
++#endif |
7154 |
++ |
7155 |
++full_search: |
7156 |
++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { |
7157 |
++ /* At this point: (!vma || addr < vma->vm_end). */ |
7158 |
++ if (task_size - len < addr) { |
7159 |
++ /* |
7160 |
++ * Start a new search - just in case we missed |
7161 |
++ * some holes. |
7162 |
++ */ |
7163 |
++ if (start_addr != mm->mmap_base) { |
7164 |
++ start_addr = addr = mm->mmap_base; |
7165 |
++ mm->cached_hole_size = 0; |
7166 |
++ goto full_search; |
7167 |
++ } |
7168 |
++ return -ENOMEM; |
7169 |
++ } |
7170 |
++ if (!vma || addr + len <= vma->vm_start) { |
7171 |
++ /* |
7172 |
++ * Remember the place where we stopped the search: |
7173 |
++ */ |
7174 |
++ mm->free_area_cache = addr + len; |
7175 |
++ return addr; |
7176 |
++ } |
7177 |
++ if (addr + mm->cached_hole_size < vma->vm_start) |
7178 |
++ mm->cached_hole_size = vma->vm_start - addr; |
7179 |
++ addr = vma->vm_end; |
7180 |
++ if (mm->start_brk <= addr && addr < mm->mmap_base) { |
7181 |
++ start_addr = addr = mm->mmap_base; |
7182 |
++ mm->cached_hole_size = 0; |
7183 |
++ goto full_search; |
7184 |
++ } |
7185 |
++ } |
7186 |
++} |
7187 |
++ |
7188 |
++unsigned long |
7189 |
++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, |
7190 |
++ const unsigned long len, const unsigned long pgoff, |
7191 |
++ const unsigned long flags) |
7192 |
++{ |
7193 |
++ struct vm_area_struct *vma; |
7194 |
++ struct mm_struct *mm = current->mm; |
7195 |
++ unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE; |
7196 |
++ |
7197 |
++#ifdef CONFIG_PAX_SEGMEXEC |
7198 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
7199 |
++ task_size = SEGMEXEC_TASK_SIZE; |
7200 |
++#endif |
7201 |
++ |
7202 |
++ /* requested length too big for entire address space */ |
7203 |
++ if (len > task_size) |
7204 |
++ return -ENOMEM; |
7205 |
++ |
7206 |
++ if (flags & MAP_FIXED) |
7207 |
++ return addr; |
7208 |
++ |
7209 |
++#ifdef CONFIG_PAX_PAGEEXEC |
7210 |
++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE)) |
7211 |
++ goto bottomup; |
7212 |
++#endif |
7213 |
++ |
7214 |
++#ifdef CONFIG_PAX_RANDMMAP |
7215 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
7216 |
++#endif |
7217 |
++ |
7218 |
++ /* requesting a specific address */ |
7219 |
++ if (addr) { |
7220 |
++ addr = PAGE_ALIGN(addr); |
7221 |
++ vma = find_vma(mm, addr); |
7222 |
++ if (task_size - len >= addr && |
7223 |
++ (!vma || addr + len <= vma->vm_start)) |
7224 |
++ return addr; |
7225 |
++ } |
7226 |
++ |
7227 |
++ /* check if free_area_cache is useful for us */ |
7228 |
++ if (len <= mm->cached_hole_size) { |
7229 |
++ mm->cached_hole_size = 0; |
7230 |
++ mm->free_area_cache = mm->mmap_base; |
7231 |
++ } |
7232 |
++ |
7233 |
++ /* either no address requested or can't fit in requested address hole */ |
7234 |
++ addr = mm->free_area_cache; |
7235 |
++ |
7236 |
++ /* make sure it can fit in the remaining address space */ |
7237 |
++ if (addr > len) { |
7238 |
++ vma = find_vma(mm, addr-len); |
7239 |
++ if (!vma || addr <= vma->vm_start) |
7240 |
++ /* remember the address as a hint for next time */ |
7241 |
++ return (mm->free_area_cache = addr-len); |
7242 |
++ } |
7243 |
++ |
7244 |
++ if (mm->mmap_base < len) |
7245 |
++ goto bottomup; |
7246 |
++ |
7247 |
++ addr = mm->mmap_base-len; |
7248 |
++ |
7249 |
++ do { |
7250 |
++ /* |
7251 |
++ * Lookup failure means no vma is above this address, |
7252 |
++ * else if new region fits below vma->vm_start, |
7253 |
++ * return with success: |
7254 |
++ */ |
7255 |
++ vma = find_vma(mm, addr); |
7256 |
++ if (!vma || addr+len <= vma->vm_start) |
7257 |
++ /* remember the address as a hint for next time */ |
7258 |
++ return (mm->free_area_cache = addr); |
7259 |
++ |
7260 |
++ /* remember the largest hole we saw so far */ |
7261 |
++ if (addr + mm->cached_hole_size < vma->vm_start) |
7262 |
++ mm->cached_hole_size = vma->vm_start - addr; |
7263 |
++ |
7264 |
++ /* try just below the current vma->vm_start */ |
7265 |
++ addr = vma->vm_start-len; |
7266 |
++ } while (len < vma->vm_start); |
7267 |
++ |
7268 |
++bottomup: |
7269 |
++ /* |
7270 |
++ * A failed mmap() very likely causes application failure, |
7271 |
++ * so fall back to the bottom-up function here. This scenario |
7272 |
++ * can happen with large stack limits and large mmap() |
7273 |
++ * allocations. |
7274 |
++ */ |
7275 |
++ |
7276 |
++#ifdef CONFIG_PAX_SEGMEXEC |
7277 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
7278 |
++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE; |
7279 |
++ else |
7280 |
++#endif |
7281 |
++ |
7282 |
++ mm->mmap_base = TASK_UNMAPPED_BASE; |
7283 |
++ |
7284 |
++#ifdef CONFIG_PAX_RANDMMAP |
7285 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
7286 |
++ mm->mmap_base += mm->delta_mmap; |
7287 |
++#endif |
7288 |
++ |
7289 |
++ mm->free_area_cache = mm->mmap_base; |
7290 |
++ mm->cached_hole_size = ~0UL; |
7291 |
++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); |
7292 |
++ /* |
7293 |
++ * Restore the topdown base: |
7294 |
++ */ |
7295 |
++ mm->mmap_base = base; |
7296 |
++ mm->free_area_cache = base; |
7297 |
++ mm->cached_hole_size = ~0UL; |
7298 |
++ |
7299 |
++ return addr; |
7300 |
++} |
7301 |
+ |
7302 |
+ struct sel_arg_struct { |
7303 |
+ unsigned long n; |
7304 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/sys_x86_64.c linux-2.6.24.4/arch/x86/kernel/sys_x86_64.c |
7305 |
+--- linux-2.6.24.4/arch/x86/kernel/sys_x86_64.c 2008-03-24 14:49:18.000000000 -0400 |
7306 |
++++ linux-2.6.24.4/arch/x86/kernel/sys_x86_64.c 2008-03-26 17:56:55.000000000 -0400 |
7307 |
+@@ -61,8 +61,8 @@ out: |
7308 |
+ return error; |
7309 |
+ } |
7310 |
+ |
7311 |
+-static void find_start_end(unsigned long flags, unsigned long *begin, |
7312 |
+- unsigned long *end) |
7313 |
++static void find_start_end(struct mm_struct *mm, unsigned long flags, |
7314 |
++ unsigned long *begin, unsigned long *end) |
7315 |
+ { |
7316 |
+ if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) { |
7317 |
+ /* This is usually used needed to map code in small |
7318 |
+@@ -75,7 +75,7 @@ static void find_start_end(unsigned long |
7319 |
+ *begin = 0x40000000; |
7320 |
+ *end = 0x80000000; |
7321 |
+ } else { |
7322 |
+- *begin = TASK_UNMAPPED_BASE; |
7323 |
++ *begin = mm->mmap_base; |
7324 |
+ *end = TASK_SIZE; |
7325 |
+ } |
7326 |
+ } |
7327 |
+@@ -92,11 +92,15 @@ arch_get_unmapped_area(struct file *filp |
7328 |
+ if (flags & MAP_FIXED) |
7329 |
+ return addr; |
7330 |
+ |
7331 |
+- find_start_end(flags, &begin, &end); |
7332 |
++ find_start_end(mm, flags, &begin, &end); |
7333 |
+ |
7334 |
+ if (len > end) |
7335 |
+ return -ENOMEM; |
7336 |
+ |
7337 |
++#ifdef CONFIG_PAX_RANDMMAP |
7338 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
7339 |
++#endif |
7340 |
++ |
7341 |
+ if (addr) { |
7342 |
+ addr = PAGE_ALIGN(addr); |
7343 |
+ vma = find_vma(mm, addr); |
7344 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/time_32.c linux-2.6.24.4/arch/x86/kernel/time_32.c |
7345 |
+--- linux-2.6.24.4/arch/x86/kernel/time_32.c 2008-03-24 14:49:18.000000000 -0400 |
7346 |
++++ linux-2.6.24.4/arch/x86/kernel/time_32.c 2008-03-26 17:56:55.000000000 -0400 |
7347 |
+@@ -130,20 +130,30 @@ unsigned long profile_pc(struct pt_regs |
7348 |
+ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) && |
7349 |
+ in_lock_functions(pc)) { |
7350 |
+ #ifdef CONFIG_FRAME_POINTER |
7351 |
+- return *(unsigned long *)(regs->ebp + 4); |
7352 |
++ return ktla_ktva(*(unsigned long *)(regs->ebp + 4)); |
7353 |
+ #else |
7354 |
+ unsigned long *sp = (unsigned long *)®s->esp; |
7355 |
+ |
7356 |
+ /* Return address is either directly at stack pointer |
7357 |
+ or above a saved eflags. Eflags has bits 22-31 zero, |
7358 |
+ kernel addresses don't. */ |
7359 |
++ |
7360 |
++#ifdef CONFIG_PAX_KERNEXEC |
7361 |
++ return ktla_ktva(sp[0]); |
7362 |
++#else |
7363 |
+ if (sp[0] >> 22) |
7364 |
+ return sp[0]; |
7365 |
+ if (sp[1] >> 22) |
7366 |
+ return sp[1]; |
7367 |
+ #endif |
7368 |
++ |
7369 |
++#endif |
7370 |
+ } |
7371 |
+ #endif |
7372 |
++ |
7373 |
++ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs)) |
7374 |
++ pc = ktla_ktva(pc); |
7375 |
++ |
7376 |
+ return pc; |
7377 |
+ } |
7378 |
+ EXPORT_SYMBOL(profile_pc); |
7379 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/traps_32.c linux-2.6.24.4/arch/x86/kernel/traps_32.c |
7380 |
+--- linux-2.6.24.4/arch/x86/kernel/traps_32.c 2008-03-24 14:49:18.000000000 -0400 |
7381 |
++++ linux-2.6.24.4/arch/x86/kernel/traps_32.c 2008-03-26 17:56:55.000000000 -0400 |
7382 |
+@@ -29,6 +29,7 @@ |
7383 |
+ #include <linux/uaccess.h> |
7384 |
+ #include <linux/nmi.h> |
7385 |
+ #include <linux/bug.h> |
7386 |
++#include <linux/binfmts.h> |
7387 |
+ |
7388 |
+ #ifdef CONFIG_EISA |
7389 |
+ #include <linux/ioport.h> |
7390 |
+@@ -71,12 +72,7 @@ asmlinkage int system_call(void); |
7391 |
+ /* Do we ignore FPU interrupts ? */ |
7392 |
+ char ignore_fpu_irq = 0; |
7393 |
+ |
7394 |
+-/* |
7395 |
+- * The IDT has to be page-aligned to simplify the Pentium |
7396 |
+- * F0 0F bug workaround.. We have a special link segment |
7397 |
+- * for this. |
7398 |
+- */ |
7399 |
+-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, }; |
7400 |
++extern struct desc_struct idt_table[256]; |
7401 |
+ |
7402 |
+ asmlinkage void divide_error(void); |
7403 |
+ asmlinkage void debug(void); |
7404 |
+@@ -306,22 +302,23 @@ void show_registers(struct pt_regs *regs |
7405 |
+ * When in-kernel, we also print out the stack and code at the |
7406 |
+ * time of the fault.. |
7407 |
+ */ |
7408 |
+- if (!user_mode_vm(regs)) { |
7409 |
++ if (!user_mode(regs)) { |
7410 |
+ u8 *eip; |
7411 |
+ unsigned int code_prologue = code_bytes * 43 / 64; |
7412 |
+ unsigned int code_len = code_bytes; |
7413 |
+ unsigned char c; |
7414 |
++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->xcs) >> 3]); |
7415 |
+ |
7416 |
+ printk("\n" KERN_EMERG "Stack: "); |
7417 |
+ show_stack_log_lvl(NULL, regs, ®s->esp, KERN_EMERG); |
7418 |
+ |
7419 |
+ printk(KERN_EMERG "Code: "); |
7420 |
+ |
7421 |
+- eip = (u8 *)regs->eip - code_prologue; |
7422 |
++ eip = (u8 *)regs->eip - code_prologue + cs_base; |
7423 |
+ if (eip < (u8 *)PAGE_OFFSET || |
7424 |
+ probe_kernel_address(eip, c)) { |
7425 |
+ /* try starting at EIP */ |
7426 |
+- eip = (u8 *)regs->eip; |
7427 |
++ eip = (u8 *)regs->eip + cs_base; |
7428 |
+ code_len = code_len - code_prologue + 1; |
7429 |
+ } |
7430 |
+ for (i = 0; i < code_len; i++, eip++) { |
7431 |
+@@ -330,7 +327,7 @@ void show_registers(struct pt_regs *regs |
7432 |
+ printk(" Bad EIP value."); |
7433 |
+ break; |
7434 |
+ } |
7435 |
+- if (eip == (u8 *)regs->eip) |
7436 |
++ if (eip == (u8 *)regs->eip + cs_base) |
7437 |
+ printk("<%02x> ", c); |
7438 |
+ else |
7439 |
+ printk("%02x ", c); |
7440 |
+@@ -343,6 +340,7 @@ int is_valid_bugaddr(unsigned long eip) |
7441 |
+ { |
7442 |
+ unsigned short ud2; |
7443 |
+ |
7444 |
++ eip = ktla_ktva(eip); |
7445 |
+ if (eip < PAGE_OFFSET) |
7446 |
+ return 0; |
7447 |
+ if (probe_kernel_address((unsigned short *)eip, ud2)) |
7448 |
+@@ -444,7 +442,7 @@ void die(const char * str, struct pt_reg |
7449 |
+ |
7450 |
+ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) |
7451 |
+ { |
7452 |
+- if (!user_mode_vm(regs)) |
7453 |
++ if (!user_mode(regs)) |
7454 |
+ die(str, regs, err); |
7455 |
+ } |
7456 |
+ |
7457 |
+@@ -460,7 +458,7 @@ static void __kprobes do_trap(int trapnr |
7458 |
+ goto trap_signal; |
7459 |
+ } |
7460 |
+ |
7461 |
+- if (!user_mode(regs)) |
7462 |
++ if (!user_mode_novm(regs)) |
7463 |
+ goto kernel_trap; |
7464 |
+ |
7465 |
+ trap_signal: { |
7466 |
+@@ -566,7 +564,7 @@ fastcall void __kprobes do_general_prote |
7467 |
+ long error_code) |
7468 |
+ { |
7469 |
+ int cpu = get_cpu(); |
7470 |
+- struct tss_struct *tss = &per_cpu(init_tss, cpu); |
7471 |
++ struct tss_struct *tss = &init_tss[cpu]; |
7472 |
+ struct thread_struct *thread = ¤t->thread; |
7473 |
+ |
7474 |
+ /* |
7475 |
+@@ -599,9 +597,25 @@ fastcall void __kprobes do_general_prote |
7476 |
+ if (regs->eflags & VM_MASK) |
7477 |
+ goto gp_in_vm86; |
7478 |
+ |
7479 |
+- if (!user_mode(regs)) |
7480 |
++ if (!user_mode_novm(regs)) |
7481 |
+ goto gp_in_kernel; |
7482 |
+ |
7483 |
++#ifdef CONFIG_PAX_PAGEEXEC |
7484 |
++ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) { |
7485 |
++ struct mm_struct *mm = current->mm; |
7486 |
++ unsigned long limit; |
7487 |
++ |
7488 |
++ down_write(&mm->mmap_sem); |
7489 |
++ limit = mm->context.user_cs_limit; |
7490 |
++ if (limit < TASK_SIZE) { |
7491 |
++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC); |
7492 |
++ up_write(&mm->mmap_sem); |
7493 |
++ return; |
7494 |
++ } |
7495 |
++ up_write(&mm->mmap_sem); |
7496 |
++ } |
7497 |
++#endif |
7498 |
++ |
7499 |
+ current->thread.error_code = error_code; |
7500 |
+ current->thread.trap_no = 13; |
7501 |
+ if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) && |
7502 |
+@@ -626,6 +640,13 @@ gp_in_kernel: |
7503 |
+ if (notify_die(DIE_GPF, "general protection fault", regs, |
7504 |
+ error_code, 13, SIGSEGV) == NOTIFY_STOP) |
7505 |
+ return; |
7506 |
++ |
7507 |
++#ifdef CONFIG_PAX_KERNEXEC |
7508 |
++ if ((regs->xcs & 0xFFFF) == __KERNEL_CS) |
7509 |
++ die("PAX: suspicious general protection fault", regs, error_code); |
7510 |
++ else |
7511 |
++#endif |
7512 |
++ |
7513 |
+ die("general protection fault", regs, error_code); |
7514 |
+ } |
7515 |
+ } |
7516 |
+@@ -715,7 +736,7 @@ void __kprobes die_nmi(struct pt_regs *r |
7517 |
+ /* If we are in kernel we are probably nested up pretty bad |
7518 |
+ * and might aswell get out now while we still can. |
7519 |
+ */ |
7520 |
+- if (!user_mode_vm(regs)) { |
7521 |
++ if (!user_mode(regs)) { |
7522 |
+ current->thread.trap_no = 2; |
7523 |
+ crash_kexec(regs); |
7524 |
+ } |
7525 |
+@@ -866,7 +887,7 @@ fastcall void __kprobes do_debug(struct |
7526 |
+ * check for kernel mode by just checking the CPL |
7527 |
+ * of CS. |
7528 |
+ */ |
7529 |
+- if (!user_mode(regs)) |
7530 |
++ if (!user_mode_novm(regs)) |
7531 |
+ goto clear_TF_reenable; |
7532 |
+ } |
7533 |
+ |
7534 |
+@@ -1044,18 +1065,14 @@ fastcall void do_spurious_interrupt_bug( |
7535 |
+ fastcall unsigned long patch_espfix_desc(unsigned long uesp, |
7536 |
+ unsigned long kesp) |
7537 |
+ { |
7538 |
+- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt; |
7539 |
+ unsigned long base = (kesp - uesp) & -THREAD_SIZE; |
7540 |
+ unsigned long new_kesp = kesp - base; |
7541 |
+ unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; |
7542 |
+- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS]; |
7543 |
++ __u32 a, b; |
7544 |
++ |
7545 |
+ /* Set up base for espfix segment */ |
7546 |
+- desc &= 0x00f0ff0000000000ULL; |
7547 |
+- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) | |
7548 |
+- ((((__u64)base) << 32) & 0xff00000000000000ULL) | |
7549 |
+- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) | |
7550 |
+- (lim_pages & 0xffff); |
7551 |
+- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc; |
7552 |
++ pack_descriptor(&a, &b, base, lim_pages, 0x93, 0xC); |
7553 |
++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, a, b); |
7554 |
+ return new_kesp; |
7555 |
+ } |
7556 |
+ |
7557 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/tsc_32.c linux-2.6.24.4/arch/x86/kernel/tsc_32.c |
7558 |
+--- linux-2.6.24.4/arch/x86/kernel/tsc_32.c 2008-03-24 14:49:18.000000000 -0400 |
7559 |
++++ linux-2.6.24.4/arch/x86/kernel/tsc_32.c 2008-03-26 17:56:55.000000000 -0400 |
7560 |
+@@ -322,7 +322,7 @@ static struct dmi_system_id __initdata b |
7561 |
+ DMI_MATCH(DMI_BOARD_NAME, "2635FA0"), |
7562 |
+ }, |
7563 |
+ }, |
7564 |
+- {} |
7565 |
++ { NULL, NULL, {{0, NULL}}, NULL} |
7566 |
+ }; |
7567 |
+ |
7568 |
+ /* |
7569 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/vm86_32.c linux-2.6.24.4/arch/x86/kernel/vm86_32.c |
7570 |
+--- linux-2.6.24.4/arch/x86/kernel/vm86_32.c 2008-03-24 14:49:18.000000000 -0400 |
7571 |
++++ linux-2.6.24.4/arch/x86/kernel/vm86_32.c 2008-03-26 17:56:55.000000000 -0400 |
7572 |
+@@ -146,7 +146,7 @@ struct pt_regs * fastcall save_v86_state |
7573 |
+ do_exit(SIGSEGV); |
7574 |
+ } |
7575 |
+ |
7576 |
+- tss = &per_cpu(init_tss, get_cpu()); |
7577 |
++ tss = init_tss + get_cpu(); |
7578 |
+ current->thread.esp0 = current->thread.saved_esp0; |
7579 |
+ current->thread.sysenter_cs = __KERNEL_CS; |
7580 |
+ load_esp0(tss, ¤t->thread); |
7581 |
+@@ -322,7 +322,7 @@ static void do_sys_vm86(struct kernel_vm |
7582 |
+ tsk->thread.saved_fs = info->regs32->xfs; |
7583 |
+ savesegment(gs, tsk->thread.saved_gs); |
7584 |
+ |
7585 |
+- tss = &per_cpu(init_tss, get_cpu()); |
7586 |
++ tss = init_tss + get_cpu(); |
7587 |
+ tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; |
7588 |
+ if (cpu_has_sep) |
7589 |
+ tsk->thread.sysenter_cs = 0; |
7590 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/vmi_32.c linux-2.6.24.4/arch/x86/kernel/vmi_32.c |
7591 |
+--- linux-2.6.24.4/arch/x86/kernel/vmi_32.c 2008-03-24 14:49:18.000000000 -0400 |
7592 |
++++ linux-2.6.24.4/arch/x86/kernel/vmi_32.c 2008-03-26 17:56:55.000000000 -0400 |
7593 |
+@@ -98,18 +98,43 @@ static unsigned patch_internal(int call, |
7594 |
+ { |
7595 |
+ u64 reloc; |
7596 |
+ struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc; |
7597 |
++ |
7598 |
++#ifdef CONFIG_PAX_KERNEXEC |
7599 |
++ unsigned long cr0; |
7600 |
++#endif |
7601 |
++ |
7602 |
+ reloc = call_vrom_long_func(vmi_rom, get_reloc, call); |
7603 |
+ switch(rel->type) { |
7604 |
+ case VMI_RELOCATION_CALL_REL: |
7605 |
+ BUG_ON(len < 5); |
7606 |
++ |
7607 |
++#ifdef CONFIG_PAX_KERNEXEC |
7608 |
++ pax_open_kernel(cr0); |
7609 |
++#endif |
7610 |
++ |
7611 |
+ *(char *)insnbuf = MNEM_CALL; |
7612 |
+ patch_offset(insnbuf, eip, (unsigned long)rel->eip); |
7613 |
++ |
7614 |
++#ifdef CONFIG_PAX_KERNEXEC |
7615 |
++ pax_close_kernel(cr0); |
7616 |
++#endif |
7617 |
++ |
7618 |
+ return 5; |
7619 |
+ |
7620 |
+ case VMI_RELOCATION_JUMP_REL: |
7621 |
+ BUG_ON(len < 5); |
7622 |
++ |
7623 |
++#ifdef CONFIG_PAX_KERNEXEC |
7624 |
++ pax_open_kernel(cr0); |
7625 |
++#endif |
7626 |
++ |
7627 |
+ *(char *)insnbuf = MNEM_JMP; |
7628 |
+ patch_offset(insnbuf, eip, (unsigned long)rel->eip); |
7629 |
++ |
7630 |
++#ifdef CONFIG_PAX_KERNEXEC |
7631 |
++ pax_close_kernel(cr0); |
7632 |
++#endif |
7633 |
++ |
7634 |
+ return 5; |
7635 |
+ |
7636 |
+ case VMI_RELOCATION_NOP: |
7637 |
+@@ -492,14 +517,14 @@ static void vmi_set_pud(pud_t *pudp, pud |
7638 |
+ |
7639 |
+ static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
7640 |
+ { |
7641 |
+- const pte_t pte = { 0 }; |
7642 |
++ const pte_t pte = __pte(0ULL); |
7643 |
+ vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); |
7644 |
+ vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); |
7645 |
+ } |
7646 |
+ |
7647 |
+ static void vmi_pmd_clear(pmd_t *pmd) |
7648 |
+ { |
7649 |
+- const pte_t pte = { 0 }; |
7650 |
++ const pte_t pte = __pte(0ULL); |
7651 |
+ vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD); |
7652 |
+ vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD); |
7653 |
+ } |
7654 |
+@@ -528,8 +553,8 @@ vmi_startup_ipi_hook(int phys_apicid, un |
7655 |
+ ap.ss = __KERNEL_DS; |
7656 |
+ ap.esp = (unsigned long) start_esp; |
7657 |
+ |
7658 |
+- ap.ds = __USER_DS; |
7659 |
+- ap.es = __USER_DS; |
7660 |
++ ap.ds = __KERNEL_DS; |
7661 |
++ ap.es = __KERNEL_DS; |
7662 |
+ ap.fs = __KERNEL_PERCPU; |
7663 |
+ ap.gs = 0; |
7664 |
+ |
7665 |
+@@ -724,12 +749,20 @@ static inline int __init activate_vmi(vo |
7666 |
+ u64 reloc; |
7667 |
+ const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc; |
7668 |
+ |
7669 |
++#ifdef CONFIG_PAX_KERNEXEC |
7670 |
++ unsigned long cr0; |
7671 |
++#endif |
7672 |
++ |
7673 |
+ if (call_vrom_func(vmi_rom, vmi_init) != 0) { |
7674 |
+ printk(KERN_ERR "VMI ROM failed to initialize!"); |
7675 |
+ return 0; |
7676 |
+ } |
7677 |
+ savesegment(cs, kernel_cs); |
7678 |
+ |
7679 |
++#ifdef CONFIG_PAX_KERNEXEC |
7680 |
++ pax_open_kernel(cr0); |
7681 |
++#endif |
7682 |
++ |
7683 |
+ pv_info.paravirt_enabled = 1; |
7684 |
+ pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK; |
7685 |
+ pv_info.name = "vmi"; |
7686 |
+@@ -917,6 +950,10 @@ static inline int __init activate_vmi(vo |
7687 |
+ |
7688 |
+ para_fill(pv_irq_ops.safe_halt, Halt); |
7689 |
+ |
7690 |
++#ifdef CONFIG_PAX_KERNEXEC |
7691 |
++ pax_close_kernel(cr0); |
7692 |
++#endif |
7693 |
++ |
7694 |
+ /* |
7695 |
+ * Alternative instruction rewriting doesn't happen soon enough |
7696 |
+ * to convert VMI_IRET to a call instead of a jump; so we have |
7697 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.24.4/arch/x86/kernel/vmlinux_32.lds.S |
7698 |
+--- linux-2.6.24.4/arch/x86/kernel/vmlinux_32.lds.S 2008-03-24 14:49:18.000000000 -0400 |
7699 |
++++ linux-2.6.24.4/arch/x86/kernel/vmlinux_32.lds.S 2008-03-26 17:56:55.000000000 -0400 |
7700 |
+@@ -21,6 +21,20 @@ |
7701 |
+ #include <asm/page.h> |
7702 |
+ #include <asm/cache.h> |
7703 |
+ #include <asm/boot.h> |
7704 |
++#include <asm/segment.h> |
7705 |
++ |
7706 |
++#ifdef CONFIG_X86_PAE |
7707 |
++#define PMD_SHIFT 21 |
7708 |
++#else |
7709 |
++#define PMD_SHIFT 22 |
7710 |
++#endif |
7711 |
++#define PMD_SIZE (1 << PMD_SHIFT) |
7712 |
++ |
7713 |
++#ifdef CONFIG_PAX_KERNEXEC |
7714 |
++#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1))) |
7715 |
++#else |
7716 |
++#define __KERNEL_TEXT_OFFSET 0 |
7717 |
++#endif |
7718 |
+ |
7719 |
+ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") |
7720 |
+ OUTPUT_ARCH(i386) |
7721 |
+@@ -28,22 +42,125 @@ ENTRY(phys_startup_32) |
7722 |
+ jiffies = jiffies_64; |
7723 |
+ |
7724 |
+ PHDRS { |
7725 |
+- text PT_LOAD FLAGS(5); /* R_E */ |
7726 |
+- data PT_LOAD FLAGS(7); /* RWE */ |
7727 |
+- note PT_NOTE FLAGS(0); /* ___ */ |
7728 |
++ initdata PT_LOAD FLAGS(6); /* RW_ */ |
7729 |
++ percpu PT_LOAD FLAGS(6); /* RW_ */ |
7730 |
++ inittext PT_LOAD FLAGS(5); /* R_E */ |
7731 |
++ text PT_LOAD FLAGS(5); /* R_E */ |
7732 |
++ rodata PT_LOAD FLAGS(4); /* R__ */ |
7733 |
++ data PT_LOAD FLAGS(6); /* RW_ */ |
7734 |
++ note PT_NOTE FLAGS(0); /* ___ */ |
7735 |
+ } |
7736 |
+ SECTIONS |
7737 |
+ { |
7738 |
+- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR; |
7739 |
+- phys_startup_32 = startup_32 - LOAD_OFFSET; |
7740 |
++ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR; |
7741 |
++ |
7742 |
++ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) { |
7743 |
++ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET; |
7744 |
++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET; |
7745 |
++ *(.text.startup) |
7746 |
++ } :initdata |
7747 |
++ |
7748 |
++ /* might get freed after init */ |
7749 |
++ . = ALIGN(4096); |
7750 |
++ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { |
7751 |
++ __smp_locks = .; |
7752 |
++ *(.smp_locks) |
7753 |
++ __smp_locks_end = .; |
7754 |
++ } |
7755 |
++ /* will be freed after init |
7756 |
++ * Following ALIGN() is required to make sure no other data falls on the |
7757 |
++ * same page where __smp_alt_end is pointing as that page might be freed |
7758 |
++ * after boot. Always make sure that ALIGN() directive is present after |
7759 |
++ * the section which contains __smp_alt_end. |
7760 |
++ */ |
7761 |
++ . = ALIGN(4096); |
7762 |
++ |
7763 |
++ /* will be freed after init */ |
7764 |
++ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { |
7765 |
++ __init_begin = .; |
7766 |
++ *(.init.data) |
7767 |
++ } |
7768 |
++ . = ALIGN(16); |
7769 |
++ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { |
7770 |
++ __setup_start = .; |
7771 |
++ *(.init.setup) |
7772 |
++ __setup_end = .; |
7773 |
++ } |
7774 |
++ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { |
7775 |
++ __initcall_start = .; |
7776 |
++ INITCALLS |
7777 |
++ __initcall_end = .; |
7778 |
++ } |
7779 |
++ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { |
7780 |
++ __con_initcall_start = .; |
7781 |
++ *(.con_initcall.init) |
7782 |
++ __con_initcall_end = .; |
7783 |
++ } |
7784 |
++ SECURITY_INIT |
7785 |
++ . = ALIGN(4); |
7786 |
++ .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { |
7787 |
++ __alt_instructions = .; |
7788 |
++ *(.altinstructions) |
7789 |
++ __alt_instructions_end = .; |
7790 |
++ } |
7791 |
++ .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { |
7792 |
++ *(.altinstr_replacement) |
7793 |
++ } |
7794 |
++ . = ALIGN(4); |
7795 |
++ .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { |
7796 |
++ __parainstructions = .; |
7797 |
++ *(.parainstructions) |
7798 |
++ __parainstructions_end = .; |
7799 |
++ } |
7800 |
++ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } |
7801 |
++#if defined(CONFIG_BLK_DEV_INITRD) |
7802 |
++ . = ALIGN(4096); |
7803 |
++ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { |
7804 |
++ __initramfs_start = .; |
7805 |
++ *(.init.ramfs) |
7806 |
++ __initramfs_end = .; |
7807 |
++ } |
7808 |
++#endif |
7809 |
++ . = ALIGN(4096); |
7810 |
++ per_cpu_start = .; |
7811 |
++ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) { |
7812 |
++ __per_cpu_start = . + per_cpu_start; |
7813 |
++ LONG(0) |
7814 |
++ *(.data.percpu) |
7815 |
++ *(.data.percpu.shared_aligned) |
7816 |
++ __per_cpu_end = . + per_cpu_start; |
7817 |
++ } :percpu |
7818 |
++ . += per_cpu_start; |
7819 |
++ |
7820 |
++ /* read-only */ |
7821 |
++ |
7822 |
++ . = ALIGN(4096); /* Init code and data */ |
7823 |
++ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { |
7824 |
++ _sinittext = .; |
7825 |
++ *(.init.text) |
7826 |
++ _einittext = .; |
7827 |
++ } :inittext |
7828 |
++ |
7829 |
++ /* .exit.text is discard at runtime, not link time, to deal with references |
7830 |
++ from .altinstructions and .eh_frame */ |
7831 |
++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) } |
7832 |
+ |
7833 |
+- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) { |
7834 |
+- _text = .; /* Text and read-only data */ |
7835 |
++ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { |
7836 |
++ BYTE(0) |
7837 |
++ . = ALIGN(2*PMD_SIZE) - 1; |
7838 |
++ } |
7839 |
++ |
7840 |
++ /* freed after init ends here */ |
7841 |
++ |
7842 |
++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { |
7843 |
++ __init_end = . + __KERNEL_TEXT_OFFSET; |
7844 |
++ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET; |
7845 |
++ _text = .; /* Text and read-only data */ |
7846 |
+ *(.text.head) |
7847 |
+ } :text = 0x9090 |
7848 |
+ |
7849 |
+ /* read-only */ |
7850 |
+- .text : AT(ADDR(.text) - LOAD_OFFSET) { |
7851 |
++ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { |
7852 |
+ TEXT_TEXT |
7853 |
+ SCHED_TEXT |
7854 |
+ LOCK_TEXT |
7855 |
+@@ -53,16 +170,17 @@ SECTIONS |
7856 |
+ _etext = .; /* End of text section */ |
7857 |
+ } :text = 0x9090 |
7858 |
+ |
7859 |
+- . = ALIGN(16); /* Exception table */ |
7860 |
++ . += __KERNEL_TEXT_OFFSET; |
7861 |
++ . = ALIGN(4096); /* Exception table */ |
7862 |
+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { |
7863 |
+ __start___ex_table = .; |
7864 |
+ *(__ex_table) |
7865 |
+ __stop___ex_table = .; |
7866 |
+- } |
7867 |
++ } :rodata |
7868 |
+ |
7869 |
+- NOTES :text :note |
7870 |
++ NOTES :rodata :note |
7871 |
+ |
7872 |
+- BUG_TABLE :text |
7873 |
++ BUG_TABLE :rodata |
7874 |
+ |
7875 |
+ . = ALIGN(4); |
7876 |
+ .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { |
7877 |
+@@ -71,11 +189,38 @@ SECTIONS |
7878 |
+ __tracedata_end = .; |
7879 |
+ } |
7880 |
+ |
7881 |
+- RODATA |
7882 |
++ RO_DATA(4096) |
7883 |
++ |
7884 |
++ . = ALIGN(4096); |
7885 |
++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) { |
7886 |
++ *(.idt) |
7887 |
++ . = ALIGN(4096); |
7888 |
++ *(.empty_zero_page) |
7889 |
++ *(.swapper_pm_dir) |
7890 |
++ *(.swapper_pg_dir) |
7891 |
++ } |
7892 |
++ |
7893 |
++#ifdef CONFIG_PAX_KERNEXEC |
7894 |
++ |
7895 |
++#ifdef CONFIG_MODULES |
7896 |
++ . = ALIGN(4096); |
7897 |
++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) { |
7898 |
++ MODULES_VADDR = .; |
7899 |
++ BYTE(0) |
7900 |
++ . += (6 * 1024 * 1024); |
7901 |
++ . = ALIGN( PMD_SIZE) - 1; |
7902 |
++ MODULES_END = .; |
7903 |
++ } |
7904 |
++#else |
7905 |
++ . = ALIGN(PMD_SIZE) - 1; |
7906 |
++#endif |
7907 |
++ |
7908 |
++#endif |
7909 |
+ |
7910 |
+ /* writeable */ |
7911 |
+ . = ALIGN(4096); |
7912 |
+ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ |
7913 |
++ _data = .; |
7914 |
+ DATA_DATA |
7915 |
+ CONSTRUCTORS |
7916 |
+ } :data |
7917 |
+@@ -91,7 +236,6 @@ SECTIONS |
7918 |
+ . = ALIGN(4096); |
7919 |
+ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { |
7920 |
+ *(.data.page_aligned) |
7921 |
+- *(.data.idt) |
7922 |
+ } |
7923 |
+ |
7924 |
+ . = ALIGN(32); |
7925 |
+@@ -111,86 +255,7 @@ SECTIONS |
7926 |
+ *(.data.init_task) |
7927 |
+ } |
7928 |
+ |
7929 |
+- /* might get freed after init */ |
7930 |
+- . = ALIGN(4096); |
7931 |
+- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { |
7932 |
+- __smp_locks = .; |
7933 |
+- *(.smp_locks) |
7934 |
+- __smp_locks_end = .; |
7935 |
+- } |
7936 |
+- /* will be freed after init |
7937 |
+- * Following ALIGN() is required to make sure no other data falls on the |
7938 |
+- * same page where __smp_alt_end is pointing as that page might be freed |
7939 |
+- * after boot. Always make sure that ALIGN() directive is present after |
7940 |
+- * the section which contains __smp_alt_end. |
7941 |
+- */ |
7942 |
+- . = ALIGN(4096); |
7943 |
+- |
7944 |
+- /* will be freed after init */ |
7945 |
+- . = ALIGN(4096); /* Init code and data */ |
7946 |
+- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { |
7947 |
+- __init_begin = .; |
7948 |
+- _sinittext = .; |
7949 |
+- *(.init.text) |
7950 |
+- _einittext = .; |
7951 |
+- } |
7952 |
+- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } |
7953 |
+- . = ALIGN(16); |
7954 |
+- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { |
7955 |
+- __setup_start = .; |
7956 |
+- *(.init.setup) |
7957 |
+- __setup_end = .; |
7958 |
+- } |
7959 |
+- .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { |
7960 |
+- __initcall_start = .; |
7961 |
+- INITCALLS |
7962 |
+- __initcall_end = .; |
7963 |
+- } |
7964 |
+- .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { |
7965 |
+- __con_initcall_start = .; |
7966 |
+- *(.con_initcall.init) |
7967 |
+- __con_initcall_end = .; |
7968 |
+- } |
7969 |
+- SECURITY_INIT |
7970 |
+- . = ALIGN(4); |
7971 |
+- .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { |
7972 |
+- __alt_instructions = .; |
7973 |
+- *(.altinstructions) |
7974 |
+- __alt_instructions_end = .; |
7975 |
+- } |
7976 |
+- .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { |
7977 |
+- *(.altinstr_replacement) |
7978 |
+- } |
7979 |
+- . = ALIGN(4); |
7980 |
+- .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { |
7981 |
+- __parainstructions = .; |
7982 |
+- *(.parainstructions) |
7983 |
+- __parainstructions_end = .; |
7984 |
+- } |
7985 |
+- /* .exit.text is discard at runtime, not link time, to deal with references |
7986 |
+- from .altinstructions and .eh_frame */ |
7987 |
+- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } |
7988 |
+- .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } |
7989 |
+-#if defined(CONFIG_BLK_DEV_INITRD) |
7990 |
+- . = ALIGN(4096); |
7991 |
+- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { |
7992 |
+- __initramfs_start = .; |
7993 |
+- *(.init.ramfs) |
7994 |
+- __initramfs_end = .; |
7995 |
+- } |
7996 |
+-#endif |
7997 |
+- . = ALIGN(4096); |
7998 |
+- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { |
7999 |
+- __per_cpu_start = .; |
8000 |
+- *(.data.percpu) |
8001 |
+- *(.data.percpu.shared_aligned) |
8002 |
+- __per_cpu_end = .; |
8003 |
+- } |
8004 |
+- . = ALIGN(4096); |
8005 |
+- /* freed after init ends here */ |
8006 |
+- |
8007 |
+ .bss : AT(ADDR(.bss) - LOAD_OFFSET) { |
8008 |
+- __init_end = .; |
8009 |
+ __bss_start = .; /* BSS */ |
8010 |
+ *(.bss.page_aligned) |
8011 |
+ *(.bss) |
8012 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.24.4/arch/x86/kernel/vmlinux_64.lds.S |
8013 |
+--- linux-2.6.24.4/arch/x86/kernel/vmlinux_64.lds.S 2008-03-24 14:49:18.000000000 -0400 |
8014 |
++++ linux-2.6.24.4/arch/x86/kernel/vmlinux_64.lds.S 2008-03-26 17:56:55.000000000 -0400 |
8015 |
+@@ -16,8 +16,8 @@ jiffies_64 = jiffies; |
8016 |
+ _proxy_pda = 1; |
8017 |
+ PHDRS { |
8018 |
+ text PT_LOAD FLAGS(5); /* R_E */ |
8019 |
+- data PT_LOAD FLAGS(7); /* RWE */ |
8020 |
+- user PT_LOAD FLAGS(7); /* RWE */ |
8021 |
++ data PT_LOAD FLAGS(6); /* RW_ */ |
8022 |
++ user PT_LOAD FLAGS(7); /* RWX */ |
8023 |
+ data.init PT_LOAD FLAGS(7); /* RWE */ |
8024 |
+ note PT_NOTE FLAGS(4); /* R__ */ |
8025 |
+ } |
8026 |
+@@ -52,7 +52,7 @@ SECTIONS |
8027 |
+ |
8028 |
+ BUG_TABLE :text |
8029 |
+ |
8030 |
+- RODATA |
8031 |
++ RO_DATA(4096) |
8032 |
+ |
8033 |
+ . = ALIGN(4); |
8034 |
+ .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { |
8035 |
+@@ -61,15 +61,18 @@ SECTIONS |
8036 |
+ __tracedata_end = .; |
8037 |
+ } |
8038 |
+ |
8039 |
++#ifdef CONFIG_PAX_KERNEXEC |
8040 |
++ . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */ |
8041 |
++#else |
8042 |
+ . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ |
8043 |
++#endif |
8044 |
+ /* Data */ |
8045 |
++ _data = .; |
8046 |
+ .data : AT(ADDR(.data) - LOAD_OFFSET) { |
8047 |
+ DATA_DATA |
8048 |
+ CONSTRUCTORS |
8049 |
+ } :data |
8050 |
+ |
8051 |
+- _edata = .; /* End of data section */ |
8052 |
+- |
8053 |
+ . = ALIGN(PAGE_SIZE); |
8054 |
+ . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); |
8055 |
+ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { |
8056 |
+@@ -80,9 +83,27 @@ SECTIONS |
8057 |
+ *(.data.read_mostly) |
8058 |
+ } |
8059 |
+ |
8060 |
++ . = ALIGN(8192); /* init_task */ |
8061 |
++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { |
8062 |
++ *(.data.init_task) |
8063 |
++ } |
8064 |
++ |
8065 |
++ . = ALIGN(4096); |
8066 |
++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { |
8067 |
++ *(.data.page_aligned) |
8068 |
++ } |
8069 |
++ |
8070 |
++ . = ALIGN(4096); |
8071 |
++ __nosave_begin = .; |
8072 |
++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } |
8073 |
++ . = ALIGN(4096); |
8074 |
++ __nosave_end = .; |
8075 |
++ |
8076 |
++ _edata = .; /* End of data section */ |
8077 |
++ |
8078 |
+ #define VSYSCALL_ADDR (-10*1024*1024) |
8079 |
+-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095)) |
8080 |
+-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095)) |
8081 |
++#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095)) |
8082 |
++#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095)) |
8083 |
+ |
8084 |
+ #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR) |
8085 |
+ #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) |
8086 |
+@@ -130,23 +151,13 @@ SECTIONS |
8087 |
+ #undef VVIRT_OFFSET |
8088 |
+ #undef VVIRT |
8089 |
+ |
8090 |
+- . = ALIGN(8192); /* init_task */ |
8091 |
+- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { |
8092 |
+- *(.data.init_task) |
8093 |
+- }:data.init |
8094 |
+- |
8095 |
+- . = ALIGN(4096); |
8096 |
+- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { |
8097 |
+- *(.data.page_aligned) |
8098 |
+- } |
8099 |
+- |
8100 |
+ /* might get freed after init */ |
8101 |
+ . = ALIGN(4096); |
8102 |
+ __smp_alt_begin = .; |
8103 |
+ __smp_locks = .; |
8104 |
+ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { |
8105 |
+ *(.smp_locks) |
8106 |
+- } |
8107 |
++ } :data.init |
8108 |
+ __smp_locks_end = .; |
8109 |
+ . = ALIGN(4096); |
8110 |
+ __smp_alt_end = .; |
8111 |
+@@ -208,12 +219,6 @@ SECTIONS |
8112 |
+ . = ALIGN(4096); |
8113 |
+ __init_end = .; |
8114 |
+ |
8115 |
+- . = ALIGN(4096); |
8116 |
+- __nosave_begin = .; |
8117 |
+- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } |
8118 |
+- . = ALIGN(4096); |
8119 |
+- __nosave_end = .; |
8120 |
+- |
8121 |
+ __bss_start = .; /* BSS */ |
8122 |
+ .bss : AT(ADDR(.bss) - LOAD_OFFSET) { |
8123 |
+ *(.bss.page_aligned) |
8124 |
+@@ -221,6 +226,7 @@ SECTIONS |
8125 |
+ } |
8126 |
+ __bss_stop = .; |
8127 |
+ |
8128 |
++ . = ALIGN(2*1024*1024); |
8129 |
+ _end = . ; |
8130 |
+ |
8131 |
+ /* Sections to be discarded */ |
8132 |
+diff -urNp linux-2.6.24.4/arch/x86/kernel/vsyscall_64.c linux-2.6.24.4/arch/x86/kernel/vsyscall_64.c |
8133 |
+--- linux-2.6.24.4/arch/x86/kernel/vsyscall_64.c 2008-03-24 14:49:18.000000000 -0400 |
8134 |
++++ linux-2.6.24.4/arch/x86/kernel/vsyscall_64.c 2008-03-26 17:56:55.000000000 -0400 |
8135 |
+@@ -271,13 +271,13 @@ static ctl_table kernel_table2[] = { |
8136 |
+ .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int), |
8137 |
+ .mode = 0644, |
8138 |
+ .proc_handler = vsyscall_sysctl_change }, |
8139 |
+- {} |
8140 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
8141 |
+ }; |
8142 |
+ |
8143 |
+ static ctl_table kernel_root_table2[] = { |
8144 |
+ { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555, |
8145 |
+ .child = kernel_table2 }, |
8146 |
+- {} |
8147 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
8148 |
+ }; |
8149 |
+ |
8150 |
+ #endif |
8151 |
+@@ -288,6 +288,11 @@ static void __cpuinit vsyscall_set_cpu(i |
8152 |
+ { |
8153 |
+ unsigned long *d; |
8154 |
+ unsigned long node = 0; |
8155 |
++ |
8156 |
++#ifdef CONFIG_PAX_KERNEXEC |
8157 |
++ unsigned long cr0; |
8158 |
++#endif |
8159 |
++ |
8160 |
+ #ifdef CONFIG_NUMA |
8161 |
+ node = cpu_to_node(cpu); |
8162 |
+ #endif |
8163 |
+@@ -298,10 +303,20 @@ static void __cpuinit vsyscall_set_cpu(i |
8164 |
+ in user space in vgetcpu. |
8165 |
+ 12 bits for the CPU and 8 bits for the node. */ |
8166 |
+ d = (unsigned long *)(cpu_gdt(cpu) + GDT_ENTRY_PER_CPU); |
8167 |
++ |
8168 |
++#ifdef CONFIG_PAX_KERNEXEC |
8169 |
++ pax_open_kernel(cr0); |
8170 |
++#endif |
8171 |
++ |
8172 |
+ *d = 0x0f40000000000ULL; |
8173 |
+ *d |= cpu; |
8174 |
+ *d |= (node & 0xf) << 12; |
8175 |
+ *d |= (node >> 4) << 48; |
8176 |
++ |
8177 |
++#ifdef CONFIG_PAX_KERNEXEC |
8178 |
++ pax_close_kernel(cr0); |
8179 |
++#endif |
8180 |
++ |
8181 |
+ } |
8182 |
+ |
8183 |
+ static void __cpuinit cpu_vsyscall_init(void *arg) |
8184 |
+diff -urNp linux-2.6.24.4/arch/x86/lib/checksum_32.S linux-2.6.24.4/arch/x86/lib/checksum_32.S |
8185 |
+--- linux-2.6.24.4/arch/x86/lib/checksum_32.S 2008-03-24 14:49:18.000000000 -0400 |
8186 |
++++ linux-2.6.24.4/arch/x86/lib/checksum_32.S 2008-03-26 17:56:55.000000000 -0400 |
8187 |
+@@ -28,7 +28,8 @@ |
8188 |
+ #include <linux/linkage.h> |
8189 |
+ #include <asm/dwarf2.h> |
8190 |
+ #include <asm/errno.h> |
8191 |
+- |
8192 |
++#include <asm/segment.h> |
8193 |
++ |
8194 |
+ /* |
8195 |
+ * computes a partial checksum, e.g. for TCP/UDP fragments |
8196 |
+ */ |
8197 |
+@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic ( |
8198 |
+ |
8199 |
+ #define ARGBASE 16 |
8200 |
+ #define FP 12 |
8201 |
+- |
8202 |
+-ENTRY(csum_partial_copy_generic) |
8203 |
++ |
8204 |
++ENTRY(csum_partial_copy_generic_to_user) |
8205 |
+ CFI_STARTPROC |
8206 |
++ pushl $(__USER_DS) |
8207 |
++ CFI_ADJUST_CFA_OFFSET 4 |
8208 |
++ popl %es |
8209 |
++ CFI_ADJUST_CFA_OFFSET -4 |
8210 |
++ jmp csum_partial_copy_generic |
8211 |
++ |
8212 |
++ENTRY(csum_partial_copy_generic_from_user) |
8213 |
++ pushl $(__USER_DS) |
8214 |
++ CFI_ADJUST_CFA_OFFSET 4 |
8215 |
++ popl %ds |
8216 |
++ CFI_ADJUST_CFA_OFFSET -4 |
8217 |
++ |
8218 |
++ENTRY(csum_partial_copy_generic) |
8219 |
+ subl $4,%esp |
8220 |
+ CFI_ADJUST_CFA_OFFSET 4 |
8221 |
+ pushl %edi |
8222 |
+@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic) |
8223 |
+ jmp 4f |
8224 |
+ SRC(1: movw (%esi), %bx ) |
8225 |
+ addl $2, %esi |
8226 |
+-DST( movw %bx, (%edi) ) |
8227 |
++DST( movw %bx, %es:(%edi) ) |
8228 |
+ addl $2, %edi |
8229 |
+ addw %bx, %ax |
8230 |
+ adcl $0, %eax |
8231 |
+@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) ) |
8232 |
+ SRC(1: movl (%esi), %ebx ) |
8233 |
+ SRC( movl 4(%esi), %edx ) |
8234 |
+ adcl %ebx, %eax |
8235 |
+-DST( movl %ebx, (%edi) ) |
8236 |
++DST( movl %ebx, %es:(%edi) ) |
8237 |
+ adcl %edx, %eax |
8238 |
+-DST( movl %edx, 4(%edi) ) |
8239 |
++DST( movl %edx, %es:4(%edi) ) |
8240 |
+ |
8241 |
+ SRC( movl 8(%esi), %ebx ) |
8242 |
+ SRC( movl 12(%esi), %edx ) |
8243 |
+ adcl %ebx, %eax |
8244 |
+-DST( movl %ebx, 8(%edi) ) |
8245 |
++DST( movl %ebx, %es:8(%edi) ) |
8246 |
+ adcl %edx, %eax |
8247 |
+-DST( movl %edx, 12(%edi) ) |
8248 |
++DST( movl %edx, %es:12(%edi) ) |
8249 |
+ |
8250 |
+ SRC( movl 16(%esi), %ebx ) |
8251 |
+ SRC( movl 20(%esi), %edx ) |
8252 |
+ adcl %ebx, %eax |
8253 |
+-DST( movl %ebx, 16(%edi) ) |
8254 |
++DST( movl %ebx, %es:16(%edi) ) |
8255 |
+ adcl %edx, %eax |
8256 |
+-DST( movl %edx, 20(%edi) ) |
8257 |
++DST( movl %edx, %es:20(%edi) ) |
8258 |
+ |
8259 |
+ SRC( movl 24(%esi), %ebx ) |
8260 |
+ SRC( movl 28(%esi), %edx ) |
8261 |
+ adcl %ebx, %eax |
8262 |
+-DST( movl %ebx, 24(%edi) ) |
8263 |
++DST( movl %ebx, %es:24(%edi) ) |
8264 |
+ adcl %edx, %eax |
8265 |
+-DST( movl %edx, 28(%edi) ) |
8266 |
++DST( movl %edx, %es:28(%edi) ) |
8267 |
+ |
8268 |
+ lea 32(%esi), %esi |
8269 |
+ lea 32(%edi), %edi |
8270 |
+@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) ) |
8271 |
+ shrl $2, %edx # This clears CF |
8272 |
+ SRC(3: movl (%esi), %ebx ) |
8273 |
+ adcl %ebx, %eax |
8274 |
+-DST( movl %ebx, (%edi) ) |
8275 |
++DST( movl %ebx, %es:(%edi) ) |
8276 |
+ lea 4(%esi), %esi |
8277 |
+ lea 4(%edi), %edi |
8278 |
+ dec %edx |
8279 |
+@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) ) |
8280 |
+ jb 5f |
8281 |
+ SRC( movw (%esi), %cx ) |
8282 |
+ leal 2(%esi), %esi |
8283 |
+-DST( movw %cx, (%edi) ) |
8284 |
++DST( movw %cx, %es:(%edi) ) |
8285 |
+ leal 2(%edi), %edi |
8286 |
+ je 6f |
8287 |
+ shll $16,%ecx |
8288 |
+ SRC(5: movb (%esi), %cl ) |
8289 |
+-DST( movb %cl, (%edi) ) |
8290 |
++DST( movb %cl, %es:(%edi) ) |
8291 |
+ 6: addl %ecx, %eax |
8292 |
+ adcl $0, %eax |
8293 |
+ 7: |
8294 |
+@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) ) |
8295 |
+ |
8296 |
+ 6001: |
8297 |
+ movl ARGBASE+20(%esp), %ebx # src_err_ptr |
8298 |
+- movl $-EFAULT, (%ebx) |
8299 |
++ movl $-EFAULT, %ss:(%ebx) |
8300 |
+ |
8301 |
+ # zero the complete destination - computing the rest |
8302 |
+ # is too much work |
8303 |
+@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) ) |
8304 |
+ |
8305 |
+ 6002: |
8306 |
+ movl ARGBASE+24(%esp), %ebx # dst_err_ptr |
8307 |
+- movl $-EFAULT,(%ebx) |
8308 |
++ movl $-EFAULT,%ss:(%ebx) |
8309 |
+ jmp 5000b |
8310 |
+ |
8311 |
+ .previous |
8312 |
+ |
8313 |
++ pushl %ss |
8314 |
++ CFI_ADJUST_CFA_OFFSET 4 |
8315 |
++ popl %ds |
8316 |
++ CFI_ADJUST_CFA_OFFSET -4 |
8317 |
++ pushl %ss |
8318 |
++ CFI_ADJUST_CFA_OFFSET 4 |
8319 |
++ popl %es |
8320 |
++ CFI_ADJUST_CFA_OFFSET -4 |
8321 |
+ popl %ebx |
8322 |
+ CFI_ADJUST_CFA_OFFSET -4 |
8323 |
+ CFI_RESTORE ebx |
8324 |
+@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) ) |
8325 |
+ CFI_ADJUST_CFA_OFFSET -4 |
8326 |
+ ret |
8327 |
+ CFI_ENDPROC |
8328 |
+-ENDPROC(csum_partial_copy_generic) |
8329 |
++ENDPROC(csum_partial_copy_generic_to_user) |
8330 |
+ |
8331 |
+ #else |
8332 |
+ |
8333 |
+ /* Version for PentiumII/PPro */ |
8334 |
+ |
8335 |
+ #define ROUND1(x) \ |
8336 |
++ nop; nop; nop; \ |
8337 |
+ SRC(movl x(%esi), %ebx ) ; \ |
8338 |
+ addl %ebx, %eax ; \ |
8339 |
+- DST(movl %ebx, x(%edi) ) ; |
8340 |
++ DST(movl %ebx, %es:x(%edi)) ; |
8341 |
+ |
8342 |
+ #define ROUND(x) \ |
8343 |
++ nop; nop; nop; \ |
8344 |
+ SRC(movl x(%esi), %ebx ) ; \ |
8345 |
+ adcl %ebx, %eax ; \ |
8346 |
+- DST(movl %ebx, x(%edi) ) ; |
8347 |
++ DST(movl %ebx, %es:x(%edi)) ; |
8348 |
+ |
8349 |
+ #define ARGBASE 12 |
8350 |
+- |
8351 |
+-ENTRY(csum_partial_copy_generic) |
8352 |
++ |
8353 |
++ENTRY(csum_partial_copy_generic_to_user) |
8354 |
+ CFI_STARTPROC |
8355 |
++ pushl $(__USER_DS) |
8356 |
++ CFI_ADJUST_CFA_OFFSET 4 |
8357 |
++ popl %es |
8358 |
++ CFI_ADJUST_CFA_OFFSET -4 |
8359 |
++ jmp csum_partial_copy_generic |
8360 |
++ |
8361 |
++ENTRY(csum_partial_copy_generic_from_user) |
8362 |
++ pushl $(__USER_DS) |
8363 |
++ CFI_ADJUST_CFA_OFFSET 4 |
8364 |
++ popl %ds |
8365 |
++ CFI_ADJUST_CFA_OFFSET -4 |
8366 |
++ |
8367 |
++ENTRY(csum_partial_copy_generic) |
8368 |
+ pushl %ebx |
8369 |
+ CFI_ADJUST_CFA_OFFSET 4 |
8370 |
+ CFI_REL_OFFSET ebx, 0 |
8371 |
+@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic) |
8372 |
+ subl %ebx, %edi |
8373 |
+ lea -1(%esi),%edx |
8374 |
+ andl $-32,%edx |
8375 |
+- lea 3f(%ebx,%ebx), %ebx |
8376 |
++ lea 3f(%ebx,%ebx,2), %ebx |
8377 |
+ testl %esi, %esi |
8378 |
+ jmp *%ebx |
8379 |
+ 1: addl $64,%esi |
8380 |
+@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic) |
8381 |
+ jb 5f |
8382 |
+ SRC( movw (%esi), %dx ) |
8383 |
+ leal 2(%esi), %esi |
8384 |
+-DST( movw %dx, (%edi) ) |
8385 |
++DST( movw %dx, %es:(%edi) ) |
8386 |
+ leal 2(%edi), %edi |
8387 |
+ je 6f |
8388 |
+ shll $16,%edx |
8389 |
+ 5: |
8390 |
+ SRC( movb (%esi), %dl ) |
8391 |
+-DST( movb %dl, (%edi) ) |
8392 |
++DST( movb %dl, %es:(%edi) ) |
8393 |
+ 6: addl %edx, %eax |
8394 |
+ adcl $0, %eax |
8395 |
+ 7: |
8396 |
+ .section .fixup, "ax" |
8397 |
+ 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr |
8398 |
+- movl $-EFAULT, (%ebx) |
8399 |
++ movl $-EFAULT, %ss:(%ebx) |
8400 |
+ # zero the complete destination (computing the rest is too much work) |
8401 |
+ movl ARGBASE+8(%esp),%edi # dst |
8402 |
+ movl ARGBASE+12(%esp),%ecx # len |
8403 |
+@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) ) |
8404 |
+ rep; stosb |
8405 |
+ jmp 7b |
8406 |
+ 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr |
8407 |
+- movl $-EFAULT, (%ebx) |
8408 |
++ movl $-EFAULT, %ss:(%ebx) |
8409 |
+ jmp 7b |
8410 |
+ .previous |
8411 |
+ |
8412 |
++ pushl %ss |
8413 |
++ CFI_ADJUST_CFA_OFFSET 4 |
8414 |
++ popl %ds |
8415 |
++ CFI_ADJUST_CFA_OFFSET -4 |
8416 |
++ pushl %ss |
8417 |
++ CFI_ADJUST_CFA_OFFSET 4 |
8418 |
++ popl %es |
8419 |
++ CFI_ADJUST_CFA_OFFSET -4 |
8420 |
+ popl %esi |
8421 |
+ CFI_ADJUST_CFA_OFFSET -4 |
8422 |
+ CFI_RESTORE esi |
8423 |
+@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) ) |
8424 |
+ CFI_RESTORE ebx |
8425 |
+ ret |
8426 |
+ CFI_ENDPROC |
8427 |
+-ENDPROC(csum_partial_copy_generic) |
8428 |
++ENDPROC(csum_partial_copy_generic_to_user) |
8429 |
+ |
8430 |
+ #undef ROUND |
8431 |
+ #undef ROUND1 |
8432 |
+diff -urNp linux-2.6.24.4/arch/x86/lib/clear_page_64.S linux-2.6.24.4/arch/x86/lib/clear_page_64.S |
8433 |
+--- linux-2.6.24.4/arch/x86/lib/clear_page_64.S 2008-03-24 14:49:18.000000000 -0400 |
8434 |
++++ linux-2.6.24.4/arch/x86/lib/clear_page_64.S 2008-03-26 17:56:55.000000000 -0400 |
8435 |
+@@ -44,7 +44,7 @@ ENDPROC(clear_page) |
8436 |
+ |
8437 |
+ #include <asm/cpufeature.h> |
8438 |
+ |
8439 |
+- .section .altinstr_replacement,"ax" |
8440 |
++ .section .altinstr_replacement,"a" |
8441 |
+ 1: .byte 0xeb /* jmp <disp8> */ |
8442 |
+ .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */ |
8443 |
+ 2: |
8444 |
+diff -urNp linux-2.6.24.4/arch/x86/lib/copy_page_64.S linux-2.6.24.4/arch/x86/lib/copy_page_64.S |
8445 |
+--- linux-2.6.24.4/arch/x86/lib/copy_page_64.S 2008-03-24 14:49:18.000000000 -0400 |
8446 |
++++ linux-2.6.24.4/arch/x86/lib/copy_page_64.S 2008-03-26 17:56:55.000000000 -0400 |
8447 |
+@@ -104,7 +104,7 @@ ENDPROC(copy_page) |
8448 |
+ |
8449 |
+ #include <asm/cpufeature.h> |
8450 |
+ |
8451 |
+- .section .altinstr_replacement,"ax" |
8452 |
++ .section .altinstr_replacement,"a" |
8453 |
+ 1: .byte 0xeb /* jmp <disp8> */ |
8454 |
+ .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */ |
8455 |
+ 2: |
8456 |
+diff -urNp linux-2.6.24.4/arch/x86/lib/copy_user_64.S linux-2.6.24.4/arch/x86/lib/copy_user_64.S |
8457 |
+--- linux-2.6.24.4/arch/x86/lib/copy_user_64.S 2008-03-24 14:49:18.000000000 -0400 |
8458 |
++++ linux-2.6.24.4/arch/x86/lib/copy_user_64.S 2008-03-26 17:56:55.000000000 -0400 |
8459 |
+@@ -19,7 +19,7 @@ |
8460 |
+ .byte 0xe9 /* 32bit jump */ |
8461 |
+ .long \orig-1f /* by default jump to orig */ |
8462 |
+ 1: |
8463 |
+- .section .altinstr_replacement,"ax" |
8464 |
++ .section .altinstr_replacement,"a" |
8465 |
+ 2: .byte 0xe9 /* near jump with 32bit immediate */ |
8466 |
+ .long \alt-1b /* offset */ /* or alternatively to alt */ |
8467 |
+ .previous |
8468 |
+diff -urNp linux-2.6.24.4/arch/x86/lib/getuser_32.S linux-2.6.24.4/arch/x86/lib/getuser_32.S |
8469 |
+--- linux-2.6.24.4/arch/x86/lib/getuser_32.S 2008-03-24 14:49:18.000000000 -0400 |
8470 |
++++ linux-2.6.24.4/arch/x86/lib/getuser_32.S 2008-03-26 17:56:55.000000000 -0400 |
8471 |
+@@ -11,7 +11,7 @@ |
8472 |
+ #include <linux/linkage.h> |
8473 |
+ #include <asm/dwarf2.h> |
8474 |
+ #include <asm/thread_info.h> |
8475 |
+- |
8476 |
++#include <asm/segment.h> |
8477 |
+ |
8478 |
+ /* |
8479 |
+ * __get_user_X |
8480 |
+@@ -31,7 +31,11 @@ ENTRY(__get_user_1) |
8481 |
+ GET_THREAD_INFO(%edx) |
8482 |
+ cmpl TI_addr_limit(%edx),%eax |
8483 |
+ jae bad_get_user |
8484 |
++ pushl $(__USER_DS) |
8485 |
++ popl %ds |
8486 |
+ 1: movzbl (%eax),%edx |
8487 |
++ pushl %ss |
8488 |
++ pop %ds |
8489 |
+ xorl %eax,%eax |
8490 |
+ ret |
8491 |
+ CFI_ENDPROC |
8492 |
+@@ -44,7 +48,11 @@ ENTRY(__get_user_2) |
8493 |
+ GET_THREAD_INFO(%edx) |
8494 |
+ cmpl TI_addr_limit(%edx),%eax |
8495 |
+ jae bad_get_user |
8496 |
++ pushl $(__USER_DS) |
8497 |
++ popl %ds |
8498 |
+ 2: movzwl -1(%eax),%edx |
8499 |
++ pushl %ss |
8500 |
++ pop %ds |
8501 |
+ xorl %eax,%eax |
8502 |
+ ret |
8503 |
+ CFI_ENDPROC |
8504 |
+@@ -57,7 +65,11 @@ ENTRY(__get_user_4) |
8505 |
+ GET_THREAD_INFO(%edx) |
8506 |
+ cmpl TI_addr_limit(%edx),%eax |
8507 |
+ jae bad_get_user |
8508 |
++ pushl $(__USER_DS) |
8509 |
++ popl %ds |
8510 |
+ 3: movl -3(%eax),%edx |
8511 |
++ pushl %ss |
8512 |
++ pop %ds |
8513 |
+ xorl %eax,%eax |
8514 |
+ ret |
8515 |
+ CFI_ENDPROC |
8516 |
+@@ -65,6 +77,8 @@ ENDPROC(__get_user_4) |
8517 |
+ |
8518 |
+ bad_get_user: |
8519 |
+ CFI_STARTPROC |
8520 |
++ pushl %ss |
8521 |
++ pop %ds |
8522 |
+ xorl %edx,%edx |
8523 |
+ movl $-14,%eax |
8524 |
+ ret |
8525 |
+diff -urNp linux-2.6.24.4/arch/x86/lib/memcpy_64.S linux-2.6.24.4/arch/x86/lib/memcpy_64.S |
8526 |
+--- linux-2.6.24.4/arch/x86/lib/memcpy_64.S 2008-03-24 14:49:18.000000000 -0400 |
8527 |
++++ linux-2.6.24.4/arch/x86/lib/memcpy_64.S 2008-03-26 17:56:55.000000000 -0400 |
8528 |
+@@ -114,7 +114,7 @@ ENDPROC(__memcpy) |
8529 |
+ /* Some CPUs run faster using the string copy instructions. |
8530 |
+ It is also a lot simpler. Use this when possible */ |
8531 |
+ |
8532 |
+- .section .altinstr_replacement,"ax" |
8533 |
++ .section .altinstr_replacement,"a" |
8534 |
+ 1: .byte 0xeb /* jmp <disp8> */ |
8535 |
+ .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */ |
8536 |
+ 2: |
8537 |
+diff -urNp linux-2.6.24.4/arch/x86/lib/memset_64.S linux-2.6.24.4/arch/x86/lib/memset_64.S |
8538 |
+--- linux-2.6.24.4/arch/x86/lib/memset_64.S 2008-03-24 14:49:18.000000000 -0400 |
8539 |
++++ linux-2.6.24.4/arch/x86/lib/memset_64.S 2008-03-26 17:56:55.000000000 -0400 |
8540 |
+@@ -118,7 +118,7 @@ ENDPROC(__memset) |
8541 |
+ |
8542 |
+ #include <asm/cpufeature.h> |
8543 |
+ |
8544 |
+- .section .altinstr_replacement,"ax" |
8545 |
++ .section .altinstr_replacement,"a" |
8546 |
+ 1: .byte 0xeb /* jmp <disp8> */ |
8547 |
+ .byte (memset_c - memset) - (2f - 1b) /* offset */ |
8548 |
+ 2: |
8549 |
+diff -urNp linux-2.6.24.4/arch/x86/lib/mmx_32.c linux-2.6.24.4/arch/x86/lib/mmx_32.c |
8550 |
+--- linux-2.6.24.4/arch/x86/lib/mmx_32.c 2008-03-24 14:49:18.000000000 -0400 |
8551 |
++++ linux-2.6.24.4/arch/x86/lib/mmx_32.c 2008-03-26 17:56:55.000000000 -0400 |
8552 |
+@@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void * |
8553 |
+ { |
8554 |
+ void *p; |
8555 |
+ int i; |
8556 |
++ unsigned long cr0; |
8557 |
+ |
8558 |
+ if (unlikely(in_interrupt())) |
8559 |
+ return __memcpy(to, from, len); |
8560 |
+@@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void * |
8561 |
+ kernel_fpu_begin(); |
8562 |
+ |
8563 |
+ __asm__ __volatile__ ( |
8564 |
+- "1: prefetch (%0)\n" /* This set is 28 bytes */ |
8565 |
+- " prefetch 64(%0)\n" |
8566 |
+- " prefetch 128(%0)\n" |
8567 |
+- " prefetch 192(%0)\n" |
8568 |
+- " prefetch 256(%0)\n" |
8569 |
++ "1: prefetch (%1)\n" /* This set is 28 bytes */ |
8570 |
++ " prefetch 64(%1)\n" |
8571 |
++ " prefetch 128(%1)\n" |
8572 |
++ " prefetch 192(%1)\n" |
8573 |
++ " prefetch 256(%1)\n" |
8574 |
+ "2: \n" |
8575 |
+ ".section .fixup, \"ax\"\n" |
8576 |
+- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
8577 |
++ "3: \n" |
8578 |
++ |
8579 |
++#ifdef CONFIG_PAX_KERNEXEC |
8580 |
++ " movl %%cr0, %0\n" |
8581 |
++ " movl %0, %%eax\n" |
8582 |
++ " andl $0xFFFEFFFF, %%eax\n" |
8583 |
++ " movl %%eax, %%cr0\n" |
8584 |
++#endif |
8585 |
++ |
8586 |
++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
8587 |
++ |
8588 |
++#ifdef CONFIG_PAX_KERNEXEC |
8589 |
++ " movl %0, %%cr0\n" |
8590 |
++#endif |
8591 |
++ |
8592 |
+ " jmp 2b\n" |
8593 |
+ ".previous\n" |
8594 |
+ ".section __ex_table,\"a\"\n" |
8595 |
+ " .align 4\n" |
8596 |
+ " .long 1b, 3b\n" |
8597 |
+ ".previous" |
8598 |
+- : : "r" (from) ); |
8599 |
++ : "=&r" (cr0) : "r" (from) : "ax"); |
8600 |
+ |
8601 |
+ |
8602 |
+ for(; i>5; i--) |
8603 |
+ { |
8604 |
+ __asm__ __volatile__ ( |
8605 |
+- "1: prefetch 320(%0)\n" |
8606 |
+- "2: movq (%0), %%mm0\n" |
8607 |
+- " movq 8(%0), %%mm1\n" |
8608 |
+- " movq 16(%0), %%mm2\n" |
8609 |
+- " movq 24(%0), %%mm3\n" |
8610 |
+- " movq %%mm0, (%1)\n" |
8611 |
+- " movq %%mm1, 8(%1)\n" |
8612 |
+- " movq %%mm2, 16(%1)\n" |
8613 |
+- " movq %%mm3, 24(%1)\n" |
8614 |
+- " movq 32(%0), %%mm0\n" |
8615 |
+- " movq 40(%0), %%mm1\n" |
8616 |
+- " movq 48(%0), %%mm2\n" |
8617 |
+- " movq 56(%0), %%mm3\n" |
8618 |
+- " movq %%mm0, 32(%1)\n" |
8619 |
+- " movq %%mm1, 40(%1)\n" |
8620 |
+- " movq %%mm2, 48(%1)\n" |
8621 |
+- " movq %%mm3, 56(%1)\n" |
8622 |
++ "1: prefetch 320(%1)\n" |
8623 |
++ "2: movq (%1), %%mm0\n" |
8624 |
++ " movq 8(%1), %%mm1\n" |
8625 |
++ " movq 16(%1), %%mm2\n" |
8626 |
++ " movq 24(%1), %%mm3\n" |
8627 |
++ " movq %%mm0, (%2)\n" |
8628 |
++ " movq %%mm1, 8(%2)\n" |
8629 |
++ " movq %%mm2, 16(%2)\n" |
8630 |
++ " movq %%mm3, 24(%2)\n" |
8631 |
++ " movq 32(%1), %%mm0\n" |
8632 |
++ " movq 40(%1), %%mm1\n" |
8633 |
++ " movq 48(%1), %%mm2\n" |
8634 |
++ " movq 56(%1), %%mm3\n" |
8635 |
++ " movq %%mm0, 32(%2)\n" |
8636 |
++ " movq %%mm1, 40(%2)\n" |
8637 |
++ " movq %%mm2, 48(%2)\n" |
8638 |
++ " movq %%mm3, 56(%2)\n" |
8639 |
+ ".section .fixup, \"ax\"\n" |
8640 |
+- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
8641 |
++ "3:\n" |
8642 |
++ |
8643 |
++#ifdef CONFIG_PAX_KERNEXEC |
8644 |
++ " movl %%cr0, %0\n" |
8645 |
++ " movl %0, %%eax\n" |
8646 |
++ " andl $0xFFFEFFFF, %%eax\n" |
8647 |
++ " movl %%eax, %%cr0\n" |
8648 |
++#endif |
8649 |
++ |
8650 |
++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
8651 |
++ |
8652 |
++#ifdef CONFIG_PAX_KERNEXEC |
8653 |
++ " movl %0, %%cr0\n" |
8654 |
++#endif |
8655 |
++ |
8656 |
+ " jmp 2b\n" |
8657 |
+ ".previous\n" |
8658 |
+ ".section __ex_table,\"a\"\n" |
8659 |
+ " .align 4\n" |
8660 |
+ " .long 1b, 3b\n" |
8661 |
+ ".previous" |
8662 |
+- : : "r" (from), "r" (to) : "memory"); |
8663 |
++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); |
8664 |
+ from+=64; |
8665 |
+ to+=64; |
8666 |
+ } |
8667 |
+@@ -164,6 +193,7 @@ static void fast_clear_page(void *page) |
8668 |
+ static void fast_copy_page(void *to, void *from) |
8669 |
+ { |
8670 |
+ int i; |
8671 |
++ unsigned long cr0; |
8672 |
+ |
8673 |
+ kernel_fpu_begin(); |
8674 |
+ |
8675 |
+@@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi |
8676 |
+ * but that is for later. -AV |
8677 |
+ */ |
8678 |
+ __asm__ __volatile__ ( |
8679 |
+- "1: prefetch (%0)\n" |
8680 |
+- " prefetch 64(%0)\n" |
8681 |
+- " prefetch 128(%0)\n" |
8682 |
+- " prefetch 192(%0)\n" |
8683 |
+- " prefetch 256(%0)\n" |
8684 |
++ "1: prefetch (%1)\n" |
8685 |
++ " prefetch 64(%1)\n" |
8686 |
++ " prefetch 128(%1)\n" |
8687 |
++ " prefetch 192(%1)\n" |
8688 |
++ " prefetch 256(%1)\n" |
8689 |
+ "2: \n" |
8690 |
+ ".section .fixup, \"ax\"\n" |
8691 |
+- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
8692 |
++ "3: \n" |
8693 |
++ |
8694 |
++#ifdef CONFIG_PAX_KERNEXEC |
8695 |
++ " movl %%cr0, %0\n" |
8696 |
++ " movl %0, %%eax\n" |
8697 |
++ " andl $0xFFFEFFFF, %%eax\n" |
8698 |
++ " movl %%eax, %%cr0\n" |
8699 |
++#endif |
8700 |
++ |
8701 |
++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
8702 |
++ |
8703 |
++#ifdef CONFIG_PAX_KERNEXEC |
8704 |
++ " movl %0, %%cr0\n" |
8705 |
++#endif |
8706 |
++ |
8707 |
+ " jmp 2b\n" |
8708 |
+ ".previous\n" |
8709 |
+ ".section __ex_table,\"a\"\n" |
8710 |
+ " .align 4\n" |
8711 |
+ " .long 1b, 3b\n" |
8712 |
+ ".previous" |
8713 |
+- : : "r" (from) ); |
8714 |
++ : "=&r" (cr0) : "r" (from) : "ax"); |
8715 |
+ |
8716 |
+ for(i=0; i<(4096-320)/64; i++) |
8717 |
+ { |
8718 |
+ __asm__ __volatile__ ( |
8719 |
+- "1: prefetch 320(%0)\n" |
8720 |
+- "2: movq (%0), %%mm0\n" |
8721 |
+- " movntq %%mm0, (%1)\n" |
8722 |
+- " movq 8(%0), %%mm1\n" |
8723 |
+- " movntq %%mm1, 8(%1)\n" |
8724 |
+- " movq 16(%0), %%mm2\n" |
8725 |
+- " movntq %%mm2, 16(%1)\n" |
8726 |
+- " movq 24(%0), %%mm3\n" |
8727 |
+- " movntq %%mm3, 24(%1)\n" |
8728 |
+- " movq 32(%0), %%mm4\n" |
8729 |
+- " movntq %%mm4, 32(%1)\n" |
8730 |
+- " movq 40(%0), %%mm5\n" |
8731 |
+- " movntq %%mm5, 40(%1)\n" |
8732 |
+- " movq 48(%0), %%mm6\n" |
8733 |
+- " movntq %%mm6, 48(%1)\n" |
8734 |
+- " movq 56(%0), %%mm7\n" |
8735 |
+- " movntq %%mm7, 56(%1)\n" |
8736 |
++ "1: prefetch 320(%1)\n" |
8737 |
++ "2: movq (%1), %%mm0\n" |
8738 |
++ " movntq %%mm0, (%2)\n" |
8739 |
++ " movq 8(%1), %%mm1\n" |
8740 |
++ " movntq %%mm1, 8(%2)\n" |
8741 |
++ " movq 16(%1), %%mm2\n" |
8742 |
++ " movntq %%mm2, 16(%2)\n" |
8743 |
++ " movq 24(%1), %%mm3\n" |
8744 |
++ " movntq %%mm3, 24(%2)\n" |
8745 |
++ " movq 32(%1), %%mm4\n" |
8746 |
++ " movntq %%mm4, 32(%2)\n" |
8747 |
++ " movq 40(%1), %%mm5\n" |
8748 |
++ " movntq %%mm5, 40(%2)\n" |
8749 |
++ " movq 48(%1), %%mm6\n" |
8750 |
++ " movntq %%mm6, 48(%2)\n" |
8751 |
++ " movq 56(%1), %%mm7\n" |
8752 |
++ " movntq %%mm7, 56(%2)\n" |
8753 |
+ ".section .fixup, \"ax\"\n" |
8754 |
+- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
8755 |
++ "3:\n" |
8756 |
++ |
8757 |
++#ifdef CONFIG_PAX_KERNEXEC |
8758 |
++ " movl %%cr0, %0\n" |
8759 |
++ " movl %0, %%eax\n" |
8760 |
++ " andl $0xFFFEFFFF, %%eax\n" |
8761 |
++ " movl %%eax, %%cr0\n" |
8762 |
++#endif |
8763 |
++ |
8764 |
++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
8765 |
++ |
8766 |
++#ifdef CONFIG_PAX_KERNEXEC |
8767 |
++ " movl %0, %%cr0\n" |
8768 |
++#endif |
8769 |
++ |
8770 |
+ " jmp 2b\n" |
8771 |
+ ".previous\n" |
8772 |
+ ".section __ex_table,\"a\"\n" |
8773 |
+ " .align 4\n" |
8774 |
+ " .long 1b, 3b\n" |
8775 |
+ ".previous" |
8776 |
+- : : "r" (from), "r" (to) : "memory"); |
8777 |
++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); |
8778 |
+ from+=64; |
8779 |
+ to+=64; |
8780 |
+ } |
8781 |
+@@ -296,56 +354,84 @@ static void fast_clear_page(void *page) |
8782 |
+ static void fast_copy_page(void *to, void *from) |
8783 |
+ { |
8784 |
+ int i; |
8785 |
+- |
8786 |
+- |
8787 |
++ unsigned long cr0; |
8788 |
++ |
8789 |
+ kernel_fpu_begin(); |
8790 |
+ |
8791 |
+ __asm__ __volatile__ ( |
8792 |
+- "1: prefetch (%0)\n" |
8793 |
+- " prefetch 64(%0)\n" |
8794 |
+- " prefetch 128(%0)\n" |
8795 |
+- " prefetch 192(%0)\n" |
8796 |
+- " prefetch 256(%0)\n" |
8797 |
++ "1: prefetch (%1)\n" |
8798 |
++ " prefetch 64(%1)\n" |
8799 |
++ " prefetch 128(%1)\n" |
8800 |
++ " prefetch 192(%1)\n" |
8801 |
++ " prefetch 256(%1)\n" |
8802 |
+ "2: \n" |
8803 |
+ ".section .fixup, \"ax\"\n" |
8804 |
+- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
8805 |
++ "3: \n" |
8806 |
++ |
8807 |
++#ifdef CONFIG_PAX_KERNEXEC |
8808 |
++ " movl %%cr0, %0\n" |
8809 |
++ " movl %0, %%eax\n" |
8810 |
++ " andl $0xFFFEFFFF, %%eax\n" |
8811 |
++ " movl %%eax, %%cr0\n" |
8812 |
++#endif |
8813 |
++ |
8814 |
++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
8815 |
++ |
8816 |
++#ifdef CONFIG_PAX_KERNEXEC |
8817 |
++ " movl %0, %%cr0\n" |
8818 |
++#endif |
8819 |
++ |
8820 |
+ " jmp 2b\n" |
8821 |
+ ".previous\n" |
8822 |
+ ".section __ex_table,\"a\"\n" |
8823 |
+ " .align 4\n" |
8824 |
+ " .long 1b, 3b\n" |
8825 |
+ ".previous" |
8826 |
+- : : "r" (from) ); |
8827 |
++ : "=&r" (cr0) : "r" (from) : "ax"); |
8828 |
+ |
8829 |
+ for(i=0; i<4096/64; i++) |
8830 |
+ { |
8831 |
+ __asm__ __volatile__ ( |
8832 |
+- "1: prefetch 320(%0)\n" |
8833 |
+- "2: movq (%0), %%mm0\n" |
8834 |
+- " movq 8(%0), %%mm1\n" |
8835 |
+- " movq 16(%0), %%mm2\n" |
8836 |
+- " movq 24(%0), %%mm3\n" |
8837 |
+- " movq %%mm0, (%1)\n" |
8838 |
+- " movq %%mm1, 8(%1)\n" |
8839 |
+- " movq %%mm2, 16(%1)\n" |
8840 |
+- " movq %%mm3, 24(%1)\n" |
8841 |
+- " movq 32(%0), %%mm0\n" |
8842 |
+- " movq 40(%0), %%mm1\n" |
8843 |
+- " movq 48(%0), %%mm2\n" |
8844 |
+- " movq 56(%0), %%mm3\n" |
8845 |
+- " movq %%mm0, 32(%1)\n" |
8846 |
+- " movq %%mm1, 40(%1)\n" |
8847 |
+- " movq %%mm2, 48(%1)\n" |
8848 |
+- " movq %%mm3, 56(%1)\n" |
8849 |
++ "1: prefetch 320(%1)\n" |
8850 |
++ "2: movq (%1), %%mm0\n" |
8851 |
++ " movq 8(%1), %%mm1\n" |
8852 |
++ " movq 16(%1), %%mm2\n" |
8853 |
++ " movq 24(%1), %%mm3\n" |
8854 |
++ " movq %%mm0, (%2)\n" |
8855 |
++ " movq %%mm1, 8(%2)\n" |
8856 |
++ " movq %%mm2, 16(%2)\n" |
8857 |
++ " movq %%mm3, 24(%2)\n" |
8858 |
++ " movq 32(%1), %%mm0\n" |
8859 |
++ " movq 40(%1), %%mm1\n" |
8860 |
++ " movq 48(%1), %%mm2\n" |
8861 |
++ " movq 56(%1), %%mm3\n" |
8862 |
++ " movq %%mm0, 32(%2)\n" |
8863 |
++ " movq %%mm1, 40(%2)\n" |
8864 |
++ " movq %%mm2, 48(%2)\n" |
8865 |
++ " movq %%mm3, 56(%2)\n" |
8866 |
+ ".section .fixup, \"ax\"\n" |
8867 |
+- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
8868 |
++ "3:\n" |
8869 |
++ |
8870 |
++#ifdef CONFIG_PAX_KERNEXEC |
8871 |
++ " movl %%cr0, %0\n" |
8872 |
++ " movl %0, %%eax\n" |
8873 |
++ " andl $0xFFFEFFFF, %%eax\n" |
8874 |
++ " movl %%eax, %%cr0\n" |
8875 |
++#endif |
8876 |
++ |
8877 |
++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
8878 |
++ |
8879 |
++#ifdef CONFIG_PAX_KERNEXEC |
8880 |
++ " movl %0, %%cr0\n" |
8881 |
++#endif |
8882 |
++ |
8883 |
+ " jmp 2b\n" |
8884 |
+ ".previous\n" |
8885 |
+ ".section __ex_table,\"a\"\n" |
8886 |
+ " .align 4\n" |
8887 |
+ " .long 1b, 3b\n" |
8888 |
+ ".previous" |
8889 |
+- : : "r" (from), "r" (to) : "memory"); |
8890 |
++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); |
8891 |
+ from+=64; |
8892 |
+ to+=64; |
8893 |
+ } |
8894 |
+diff -urNp linux-2.6.24.4/arch/x86/lib/putuser_32.S linux-2.6.24.4/arch/x86/lib/putuser_32.S |
8895 |
+--- linux-2.6.24.4/arch/x86/lib/putuser_32.S 2008-03-24 14:49:18.000000000 -0400 |
8896 |
++++ linux-2.6.24.4/arch/x86/lib/putuser_32.S 2008-03-26 17:56:55.000000000 -0400 |
8897 |
+@@ -11,7 +11,7 @@ |
8898 |
+ #include <linux/linkage.h> |
8899 |
+ #include <asm/dwarf2.h> |
8900 |
+ #include <asm/thread_info.h> |
8901 |
+- |
8902 |
++#include <asm/segment.h> |
8903 |
+ |
8904 |
+ /* |
8905 |
+ * __put_user_X |
8906 |
+@@ -41,7 +41,11 @@ ENTRY(__put_user_1) |
8907 |
+ ENTER |
8908 |
+ cmpl TI_addr_limit(%ebx),%ecx |
8909 |
+ jae bad_put_user |
8910 |
++ pushl $(__USER_DS) |
8911 |
++ popl %ds |
8912 |
+ 1: movb %al,(%ecx) |
8913 |
++ pushl %ss |
8914 |
++ popl %ds |
8915 |
+ xorl %eax,%eax |
8916 |
+ EXIT |
8917 |
+ ENDPROC(__put_user_1) |
8918 |
+@@ -52,7 +56,11 @@ ENTRY(__put_user_2) |
8919 |
+ subl $1,%ebx |
8920 |
+ cmpl %ebx,%ecx |
8921 |
+ jae bad_put_user |
8922 |
++ pushl $(__USER_DS) |
8923 |
++ popl %ds |
8924 |
+ 2: movw %ax,(%ecx) |
8925 |
++ pushl %ss |
8926 |
++ popl %ds |
8927 |
+ xorl %eax,%eax |
8928 |
+ EXIT |
8929 |
+ ENDPROC(__put_user_2) |
8930 |
+@@ -63,7 +71,11 @@ ENTRY(__put_user_4) |
8931 |
+ subl $3,%ebx |
8932 |
+ cmpl %ebx,%ecx |
8933 |
+ jae bad_put_user |
8934 |
++ pushl $(__USER_DS) |
8935 |
++ popl %ds |
8936 |
+ 3: movl %eax,(%ecx) |
8937 |
++ pushl %ss |
8938 |
++ popl %ds |
8939 |
+ xorl %eax,%eax |
8940 |
+ EXIT |
8941 |
+ ENDPROC(__put_user_4) |
8942 |
+@@ -74,8 +86,12 @@ ENTRY(__put_user_8) |
8943 |
+ subl $7,%ebx |
8944 |
+ cmpl %ebx,%ecx |
8945 |
+ jae bad_put_user |
8946 |
++ pushl $(__USER_DS) |
8947 |
++ popl %ds |
8948 |
+ 4: movl %eax,(%ecx) |
8949 |
+ 5: movl %edx,4(%ecx) |
8950 |
++ pushl %ss |
8951 |
++ popl %ds |
8952 |
+ xorl %eax,%eax |
8953 |
+ EXIT |
8954 |
+ ENDPROC(__put_user_8) |
8955 |
+@@ -85,6 +101,10 @@ bad_put_user: |
8956 |
+ CFI_DEF_CFA esp, 2*4 |
8957 |
+ CFI_OFFSET eip, -1*4 |
8958 |
+ CFI_OFFSET ebx, -2*4 |
8959 |
++ pushl %ss |
8960 |
++ CFI_ADJUST_CFA_OFFSET 4 |
8961 |
++ popl %ds |
8962 |
++ CFI_ADJUST_CFA_OFFSET -4 |
8963 |
+ movl $-14,%eax |
8964 |
+ EXIT |
8965 |
+ END(bad_put_user) |
8966 |
+diff -urNp linux-2.6.24.4/arch/x86/lib/usercopy_32.c linux-2.6.24.4/arch/x86/lib/usercopy_32.c |
8967 |
+--- linux-2.6.24.4/arch/x86/lib/usercopy_32.c 2008-03-24 14:49:18.000000000 -0400 |
8968 |
++++ linux-2.6.24.4/arch/x86/lib/usercopy_32.c 2008-03-26 17:56:55.000000000 -0400 |
8969 |
+@@ -29,34 +29,41 @@ static inline int __movsl_is_ok(unsigned |
8970 |
+ * Copy a null terminated string from userspace. |
8971 |
+ */ |
8972 |
+ |
8973 |
+-#define __do_strncpy_from_user(dst,src,count,res) \ |
8974 |
+-do { \ |
8975 |
+- int __d0, __d1, __d2; \ |
8976 |
+- might_sleep(); \ |
8977 |
+- __asm__ __volatile__( \ |
8978 |
+- " testl %1,%1\n" \ |
8979 |
+- " jz 2f\n" \ |
8980 |
+- "0: lodsb\n" \ |
8981 |
+- " stosb\n" \ |
8982 |
+- " testb %%al,%%al\n" \ |
8983 |
+- " jz 1f\n" \ |
8984 |
+- " decl %1\n" \ |
8985 |
+- " jnz 0b\n" \ |
8986 |
+- "1: subl %1,%0\n" \ |
8987 |
+- "2:\n" \ |
8988 |
+- ".section .fixup,\"ax\"\n" \ |
8989 |
+- "3: movl %5,%0\n" \ |
8990 |
+- " jmp 2b\n" \ |
8991 |
+- ".previous\n" \ |
8992 |
+- ".section __ex_table,\"a\"\n" \ |
8993 |
+- " .align 4\n" \ |
8994 |
+- " .long 0b,3b\n" \ |
8995 |
+- ".previous" \ |
8996 |
+- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \ |
8997 |
+- "=&D" (__d2) \ |
8998 |
+- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ |
8999 |
+- : "memory"); \ |
9000 |
+-} while (0) |
9001 |
++static long __do_strncpy_from_user(char *dst, const char __user *src, long count) |
9002 |
++{ |
9003 |
++ int __d0, __d1, __d2; |
9004 |
++ long res = -EFAULT; |
9005 |
++ |
9006 |
++ might_sleep(); |
9007 |
++ __asm__ __volatile__( |
9008 |
++ " movw %w10,%%ds\n" |
9009 |
++ " testl %1,%1\n" |
9010 |
++ " jz 2f\n" |
9011 |
++ "0: lodsb\n" |
9012 |
++ " stosb\n" |
9013 |
++ " testb %%al,%%al\n" |
9014 |
++ " jz 1f\n" |
9015 |
++ " decl %1\n" |
9016 |
++ " jnz 0b\n" |
9017 |
++ "1: subl %1,%0\n" |
9018 |
++ "2:\n" |
9019 |
++ " pushl %%ss\n" |
9020 |
++ " popl %%ds\n" |
9021 |
++ ".section .fixup,\"ax\"\n" |
9022 |
++ "3: movl %5,%0\n" |
9023 |
++ " jmp 2b\n" |
9024 |
++ ".previous\n" |
9025 |
++ ".section __ex_table,\"a\"\n" |
9026 |
++ " .align 4\n" |
9027 |
++ " .long 0b,3b\n" |
9028 |
++ ".previous" |
9029 |
++ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), |
9030 |
++ "=&D" (__d2) |
9031 |
++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst), |
9032 |
++ "r"(__USER_DS) |
9033 |
++ : "memory"); |
9034 |
++ return res; |
9035 |
++} |
9036 |
+ |
9037 |
+ /** |
9038 |
+ * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking. |
9039 |
+@@ -81,9 +88,7 @@ do { \ |
9040 |
+ long |
9041 |
+ __strncpy_from_user(char *dst, const char __user *src, long count) |
9042 |
+ { |
9043 |
+- long res; |
9044 |
+- __do_strncpy_from_user(dst, src, count, res); |
9045 |
+- return res; |
9046 |
++ return __do_strncpy_from_user(dst, src, count); |
9047 |
+ } |
9048 |
+ EXPORT_SYMBOL(__strncpy_from_user); |
9049 |
+ |
9050 |
+@@ -110,7 +115,7 @@ strncpy_from_user(char *dst, const char |
9051 |
+ { |
9052 |
+ long res = -EFAULT; |
9053 |
+ if (access_ok(VERIFY_READ, src, 1)) |
9054 |
+- __do_strncpy_from_user(dst, src, count, res); |
9055 |
++ res = __do_strncpy_from_user(dst, src, count); |
9056 |
+ return res; |
9057 |
+ } |
9058 |
+ EXPORT_SYMBOL(strncpy_from_user); |
9059 |
+@@ -119,27 +124,33 @@ EXPORT_SYMBOL(strncpy_from_user); |
9060 |
+ * Zero Userspace |
9061 |
+ */ |
9062 |
+ |
9063 |
+-#define __do_clear_user(addr,size) \ |
9064 |
+-do { \ |
9065 |
+- int __d0; \ |
9066 |
+- might_sleep(); \ |
9067 |
+- __asm__ __volatile__( \ |
9068 |
+- "0: rep; stosl\n" \ |
9069 |
+- " movl %2,%0\n" \ |
9070 |
+- "1: rep; stosb\n" \ |
9071 |
+- "2:\n" \ |
9072 |
+- ".section .fixup,\"ax\"\n" \ |
9073 |
+- "3: lea 0(%2,%0,4),%0\n" \ |
9074 |
+- " jmp 2b\n" \ |
9075 |
+- ".previous\n" \ |
9076 |
+- ".section __ex_table,\"a\"\n" \ |
9077 |
+- " .align 4\n" \ |
9078 |
+- " .long 0b,3b\n" \ |
9079 |
+- " .long 1b,2b\n" \ |
9080 |
+- ".previous" \ |
9081 |
+- : "=&c"(size), "=&D" (__d0) \ |
9082 |
+- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \ |
9083 |
+-} while (0) |
9084 |
++static unsigned long __do_clear_user(void __user *addr, unsigned long size) |
9085 |
++{ |
9086 |
++ int __d0; |
9087 |
++ |
9088 |
++ might_sleep(); |
9089 |
++ __asm__ __volatile__( |
9090 |
++ " movw %w6,%%es\n" |
9091 |
++ "0: rep; stosl\n" |
9092 |
++ " movl %2,%0\n" |
9093 |
++ "1: rep; stosb\n" |
9094 |
++ "2:\n" |
9095 |
++ " pushl %%ss\n" |
9096 |
++ " popl %%es\n" |
9097 |
++ ".section .fixup,\"ax\"\n" |
9098 |
++ "3: lea 0(%2,%0,4),%0\n" |
9099 |
++ " jmp 2b\n" |
9100 |
++ ".previous\n" |
9101 |
++ ".section __ex_table,\"a\"\n" |
9102 |
++ " .align 4\n" |
9103 |
++ " .long 0b,3b\n" |
9104 |
++ " .long 1b,2b\n" |
9105 |
++ ".previous" |
9106 |
++ : "=&c"(size), "=&D" (__d0) |
9107 |
++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0), |
9108 |
++ "r"(__USER_DS)); |
9109 |
++ return size; |
9110 |
++} |
9111 |
+ |
9112 |
+ /** |
9113 |
+ * clear_user: - Zero a block of memory in user space. |
9114 |
+@@ -156,7 +167,7 @@ clear_user(void __user *to, unsigned lon |
9115 |
+ { |
9116 |
+ might_sleep(); |
9117 |
+ if (access_ok(VERIFY_WRITE, to, n)) |
9118 |
+- __do_clear_user(to, n); |
9119 |
++ n = __do_clear_user(to, n); |
9120 |
+ return n; |
9121 |
+ } |
9122 |
+ EXPORT_SYMBOL(clear_user); |
9123 |
+@@ -175,8 +186,7 @@ EXPORT_SYMBOL(clear_user); |
9124 |
+ unsigned long |
9125 |
+ __clear_user(void __user *to, unsigned long n) |
9126 |
+ { |
9127 |
+- __do_clear_user(to, n); |
9128 |
+- return n; |
9129 |
++ return __do_clear_user(to, n); |
9130 |
+ } |
9131 |
+ EXPORT_SYMBOL(__clear_user); |
9132 |
+ |
9133 |
+@@ -199,14 +209,17 @@ long strnlen_user(const char __user *s, |
9134 |
+ might_sleep(); |
9135 |
+ |
9136 |
+ __asm__ __volatile__( |
9137 |
++ " movw %w8,%%es\n" |
9138 |
+ " testl %0, %0\n" |
9139 |
+ " jz 3f\n" |
9140 |
+- " andl %0,%%ecx\n" |
9141 |
++ " movl %0,%%ecx\n" |
9142 |
+ "0: repne; scasb\n" |
9143 |
+ " setne %%al\n" |
9144 |
+ " subl %%ecx,%0\n" |
9145 |
+ " addl %0,%%eax\n" |
9146 |
+ "1:\n" |
9147 |
++ " pushl %%ss\n" |
9148 |
++ " popl %%es\n" |
9149 |
+ ".section .fixup,\"ax\"\n" |
9150 |
+ "2: xorl %%eax,%%eax\n" |
9151 |
+ " jmp 1b\n" |
9152 |
+@@ -218,7 +231,7 @@ long strnlen_user(const char __user *s, |
9153 |
+ " .long 0b,2b\n" |
9154 |
+ ".previous" |
9155 |
+ :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp) |
9156 |
+- :"0" (n), "1" (s), "2" (0), "3" (mask) |
9157 |
++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS) |
9158 |
+ :"cc"); |
9159 |
+ return res & mask; |
9160 |
+ } |
9161 |
+@@ -226,10 +239,121 @@ EXPORT_SYMBOL(strnlen_user); |
9162 |
+ |
9163 |
+ #ifdef CONFIG_X86_INTEL_USERCOPY |
9164 |
+ static unsigned long |
9165 |
+-__copy_user_intel(void __user *to, const void *from, unsigned long size) |
9166 |
++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size) |
9167 |
++{ |
9168 |
++ int d0, d1; |
9169 |
++ __asm__ __volatile__( |
9170 |
++ " movw %w6, %%es\n" |
9171 |
++ " .align 2,0x90\n" |
9172 |
++ "1: movl 32(%4), %%eax\n" |
9173 |
++ " cmpl $67, %0\n" |
9174 |
++ " jbe 3f\n" |
9175 |
++ "2: movl 64(%4), %%eax\n" |
9176 |
++ " .align 2,0x90\n" |
9177 |
++ "3: movl 0(%4), %%eax\n" |
9178 |
++ "4: movl 4(%4), %%edx\n" |
9179 |
++ "5: movl %%eax, %%es:0(%3)\n" |
9180 |
++ "6: movl %%edx, %%es:4(%3)\n" |
9181 |
++ "7: movl 8(%4), %%eax\n" |
9182 |
++ "8: movl 12(%4),%%edx\n" |
9183 |
++ "9: movl %%eax, %%es:8(%3)\n" |
9184 |
++ "10: movl %%edx, %%es:12(%3)\n" |
9185 |
++ "11: movl 16(%4), %%eax\n" |
9186 |
++ "12: movl 20(%4), %%edx\n" |
9187 |
++ "13: movl %%eax, %%es:16(%3)\n" |
9188 |
++ "14: movl %%edx, %%es:20(%3)\n" |
9189 |
++ "15: movl 24(%4), %%eax\n" |
9190 |
++ "16: movl 28(%4), %%edx\n" |
9191 |
++ "17: movl %%eax, %%es:24(%3)\n" |
9192 |
++ "18: movl %%edx, %%es:28(%3)\n" |
9193 |
++ "19: movl 32(%4), %%eax\n" |
9194 |
++ "20: movl 36(%4), %%edx\n" |
9195 |
++ "21: movl %%eax, %%es:32(%3)\n" |
9196 |
++ "22: movl %%edx, %%es:36(%3)\n" |
9197 |
++ "23: movl 40(%4), %%eax\n" |
9198 |
++ "24: movl 44(%4), %%edx\n" |
9199 |
++ "25: movl %%eax, %%es:40(%3)\n" |
9200 |
++ "26: movl %%edx, %%es:44(%3)\n" |
9201 |
++ "27: movl 48(%4), %%eax\n" |
9202 |
++ "28: movl 52(%4), %%edx\n" |
9203 |
++ "29: movl %%eax, %%es:48(%3)\n" |
9204 |
++ "30: movl %%edx, %%es:52(%3)\n" |
9205 |
++ "31: movl 56(%4), %%eax\n" |
9206 |
++ "32: movl 60(%4), %%edx\n" |
9207 |
++ "33: movl %%eax, %%es:56(%3)\n" |
9208 |
++ "34: movl %%edx, %%es:60(%3)\n" |
9209 |
++ " addl $-64, %0\n" |
9210 |
++ " addl $64, %4\n" |
9211 |
++ " addl $64, %3\n" |
9212 |
++ " cmpl $63, %0\n" |
9213 |
++ " ja 1b\n" |
9214 |
++ "35: movl %0, %%eax\n" |
9215 |
++ " shrl $2, %0\n" |
9216 |
++ " andl $3, %%eax\n" |
9217 |
++ " cld\n" |
9218 |
++ "99: rep; movsl\n" |
9219 |
++ "36: movl %%eax, %0\n" |
9220 |
++ "37: rep; movsb\n" |
9221 |
++ "100:\n" |
9222 |
++ " pushl %%ss\n" |
9223 |
++ " popl %%es\n" |
9224 |
++ ".section .fixup,\"ax\"\n" |
9225 |
++ "101: lea 0(%%eax,%0,4),%0\n" |
9226 |
++ " jmp 100b\n" |
9227 |
++ ".previous\n" |
9228 |
++ ".section __ex_table,\"a\"\n" |
9229 |
++ " .align 4\n" |
9230 |
++ " .long 1b,100b\n" |
9231 |
++ " .long 2b,100b\n" |
9232 |
++ " .long 3b,100b\n" |
9233 |
++ " .long 4b,100b\n" |
9234 |
++ " .long 5b,100b\n" |
9235 |
++ " .long 6b,100b\n" |
9236 |
++ " .long 7b,100b\n" |
9237 |
++ " .long 8b,100b\n" |
9238 |
++ " .long 9b,100b\n" |
9239 |
++ " .long 10b,100b\n" |
9240 |
++ " .long 11b,100b\n" |
9241 |
++ " .long 12b,100b\n" |
9242 |
++ " .long 13b,100b\n" |
9243 |
++ " .long 14b,100b\n" |
9244 |
++ " .long 15b,100b\n" |
9245 |
++ " .long 16b,100b\n" |
9246 |
++ " .long 17b,100b\n" |
9247 |
++ " .long 18b,100b\n" |
9248 |
++ " .long 19b,100b\n" |
9249 |
++ " .long 20b,100b\n" |
9250 |
++ " .long 21b,100b\n" |
9251 |
++ " .long 22b,100b\n" |
9252 |
++ " .long 23b,100b\n" |
9253 |
++ " .long 24b,100b\n" |
9254 |
++ " .long 25b,100b\n" |
9255 |
++ " .long 26b,100b\n" |
9256 |
++ " .long 27b,100b\n" |
9257 |
++ " .long 28b,100b\n" |
9258 |
++ " .long 29b,100b\n" |
9259 |
++ " .long 30b,100b\n" |
9260 |
++ " .long 31b,100b\n" |
9261 |
++ " .long 32b,100b\n" |
9262 |
++ " .long 33b,100b\n" |
9263 |
++ " .long 34b,100b\n" |
9264 |
++ " .long 35b,100b\n" |
9265 |
++ " .long 36b,100b\n" |
9266 |
++ " .long 37b,100b\n" |
9267 |
++ " .long 99b,101b\n" |
9268 |
++ ".previous" |
9269 |
++ : "=&c"(size), "=&D" (d0), "=&S" (d1) |
9270 |
++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) |
9271 |
++ : "eax", "edx", "memory"); |
9272 |
++ return size; |
9273 |
++} |
9274 |
++ |
9275 |
++static unsigned long |
9276 |
++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size) |
9277 |
+ { |
9278 |
+ int d0, d1; |
9279 |
+ __asm__ __volatile__( |
9280 |
++ " movw %w6, %%ds\n" |
9281 |
+ " .align 2,0x90\n" |
9282 |
+ "1: movl 32(%4), %%eax\n" |
9283 |
+ " cmpl $67, %0\n" |
9284 |
+@@ -238,36 +362,36 @@ __copy_user_intel(void __user *to, const |
9285 |
+ " .align 2,0x90\n" |
9286 |
+ "3: movl 0(%4), %%eax\n" |
9287 |
+ "4: movl 4(%4), %%edx\n" |
9288 |
+- "5: movl %%eax, 0(%3)\n" |
9289 |
+- "6: movl %%edx, 4(%3)\n" |
9290 |
++ "5: movl %%eax, %%es:0(%3)\n" |
9291 |
++ "6: movl %%edx, %%es:4(%3)\n" |
9292 |
+ "7: movl 8(%4), %%eax\n" |
9293 |
+ "8: movl 12(%4),%%edx\n" |
9294 |
+- "9: movl %%eax, 8(%3)\n" |
9295 |
+- "10: movl %%edx, 12(%3)\n" |
9296 |
++ "9: movl %%eax, %%es:8(%3)\n" |
9297 |
++ "10: movl %%edx, %%es:12(%3)\n" |
9298 |
+ "11: movl 16(%4), %%eax\n" |
9299 |
+ "12: movl 20(%4), %%edx\n" |
9300 |
+- "13: movl %%eax, 16(%3)\n" |
9301 |
+- "14: movl %%edx, 20(%3)\n" |
9302 |
++ "13: movl %%eax, %%es:16(%3)\n" |
9303 |
++ "14: movl %%edx, %%es:20(%3)\n" |
9304 |
+ "15: movl 24(%4), %%eax\n" |
9305 |
+ "16: movl 28(%4), %%edx\n" |
9306 |
+- "17: movl %%eax, 24(%3)\n" |
9307 |
+- "18: movl %%edx, 28(%3)\n" |
9308 |
++ "17: movl %%eax, %%es:24(%3)\n" |
9309 |
++ "18: movl %%edx, %%es:28(%3)\n" |
9310 |
+ "19: movl 32(%4), %%eax\n" |
9311 |
+ "20: movl 36(%4), %%edx\n" |
9312 |
+- "21: movl %%eax, 32(%3)\n" |
9313 |
+- "22: movl %%edx, 36(%3)\n" |
9314 |
++ "21: movl %%eax, %%es:32(%3)\n" |
9315 |
++ "22: movl %%edx, %%es:36(%3)\n" |
9316 |
+ "23: movl 40(%4), %%eax\n" |
9317 |
+ "24: movl 44(%4), %%edx\n" |
9318 |
+- "25: movl %%eax, 40(%3)\n" |
9319 |
+- "26: movl %%edx, 44(%3)\n" |
9320 |
++ "25: movl %%eax, %%es:40(%3)\n" |
9321 |
++ "26: movl %%edx, %%es:44(%3)\n" |
9322 |
+ "27: movl 48(%4), %%eax\n" |
9323 |
+ "28: movl 52(%4), %%edx\n" |
9324 |
+- "29: movl %%eax, 48(%3)\n" |
9325 |
+- "30: movl %%edx, 52(%3)\n" |
9326 |
++ "29: movl %%eax, %%es:48(%3)\n" |
9327 |
++ "30: movl %%edx, %%es:52(%3)\n" |
9328 |
+ "31: movl 56(%4), %%eax\n" |
9329 |
+ "32: movl 60(%4), %%edx\n" |
9330 |
+- "33: movl %%eax, 56(%3)\n" |
9331 |
+- "34: movl %%edx, 60(%3)\n" |
9332 |
++ "33: movl %%eax, %%es:56(%3)\n" |
9333 |
++ "34: movl %%edx, %%es:60(%3)\n" |
9334 |
+ " addl $-64, %0\n" |
9335 |
+ " addl $64, %4\n" |
9336 |
+ " addl $64, %3\n" |
9337 |
+@@ -281,6 +405,8 @@ __copy_user_intel(void __user *to, const |
9338 |
+ "36: movl %%eax, %0\n" |
9339 |
+ "37: rep; movsb\n" |
9340 |
+ "100:\n" |
9341 |
++ " pushl %%ss\n" |
9342 |
++ " popl %%ds\n" |
9343 |
+ ".section .fixup,\"ax\"\n" |
9344 |
+ "101: lea 0(%%eax,%0,4),%0\n" |
9345 |
+ " jmp 100b\n" |
9346 |
+@@ -327,7 +453,7 @@ __copy_user_intel(void __user *to, const |
9347 |
+ " .long 99b,101b\n" |
9348 |
+ ".previous" |
9349 |
+ : "=&c"(size), "=&D" (d0), "=&S" (d1) |
9350 |
+- : "1"(to), "2"(from), "0"(size) |
9351 |
++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) |
9352 |
+ : "eax", "edx", "memory"); |
9353 |
+ return size; |
9354 |
+ } |
9355 |
+@@ -337,6 +463,7 @@ __copy_user_zeroing_intel(void *to, cons |
9356 |
+ { |
9357 |
+ int d0, d1; |
9358 |
+ __asm__ __volatile__( |
9359 |
++ " movw %w6, %%ds\n" |
9360 |
+ " .align 2,0x90\n" |
9361 |
+ "0: movl 32(%4), %%eax\n" |
9362 |
+ " cmpl $67, %0\n" |
9363 |
+@@ -345,36 +472,36 @@ __copy_user_zeroing_intel(void *to, cons |
9364 |
+ " .align 2,0x90\n" |
9365 |
+ "2: movl 0(%4), %%eax\n" |
9366 |
+ "21: movl 4(%4), %%edx\n" |
9367 |
+- " movl %%eax, 0(%3)\n" |
9368 |
+- " movl %%edx, 4(%3)\n" |
9369 |
++ " movl %%eax, %%es:0(%3)\n" |
9370 |
++ " movl %%edx, %%es:4(%3)\n" |
9371 |
+ "3: movl 8(%4), %%eax\n" |
9372 |
+ "31: movl 12(%4),%%edx\n" |
9373 |
+- " movl %%eax, 8(%3)\n" |
9374 |
+- " movl %%edx, 12(%3)\n" |
9375 |
++ " movl %%eax, %%es:8(%3)\n" |
9376 |
++ " movl %%edx, %%es:12(%3)\n" |
9377 |
+ "4: movl 16(%4), %%eax\n" |
9378 |
+ "41: movl 20(%4), %%edx\n" |
9379 |
+- " movl %%eax, 16(%3)\n" |
9380 |
+- " movl %%edx, 20(%3)\n" |
9381 |
++ " movl %%eax, %%es:16(%3)\n" |
9382 |
++ " movl %%edx, %%es:20(%3)\n" |
9383 |
+ "10: movl 24(%4), %%eax\n" |
9384 |
+ "51: movl 28(%4), %%edx\n" |
9385 |
+- " movl %%eax, 24(%3)\n" |
9386 |
+- " movl %%edx, 28(%3)\n" |
9387 |
++ " movl %%eax, %%es:24(%3)\n" |
9388 |
++ " movl %%edx, %%es:28(%3)\n" |
9389 |
+ "11: movl 32(%4), %%eax\n" |
9390 |
+ "61: movl 36(%4), %%edx\n" |
9391 |
+- " movl %%eax, 32(%3)\n" |
9392 |
+- " movl %%edx, 36(%3)\n" |
9393 |
++ " movl %%eax, %%es:32(%3)\n" |
9394 |
++ " movl %%edx, %%es:36(%3)\n" |
9395 |
+ "12: movl 40(%4), %%eax\n" |
9396 |
+ "71: movl 44(%4), %%edx\n" |
9397 |
+- " movl %%eax, 40(%3)\n" |
9398 |
+- " movl %%edx, 44(%3)\n" |
9399 |
++ " movl %%eax, %%es:40(%3)\n" |
9400 |
++ " movl %%edx, %%es:44(%3)\n" |
9401 |
+ "13: movl 48(%4), %%eax\n" |
9402 |
+ "81: movl 52(%4), %%edx\n" |
9403 |
+- " movl %%eax, 48(%3)\n" |
9404 |
+- " movl %%edx, 52(%3)\n" |
9405 |
++ " movl %%eax, %%es:48(%3)\n" |
9406 |
++ " movl %%edx, %%es:52(%3)\n" |
9407 |
+ "14: movl 56(%4), %%eax\n" |
9408 |
+ "91: movl 60(%4), %%edx\n" |
9409 |
+- " movl %%eax, 56(%3)\n" |
9410 |
+- " movl %%edx, 60(%3)\n" |
9411 |
++ " movl %%eax, %%es:56(%3)\n" |
9412 |
++ " movl %%edx, %%es:60(%3)\n" |
9413 |
+ " addl $-64, %0\n" |
9414 |
+ " addl $64, %4\n" |
9415 |
+ " addl $64, %3\n" |
9416 |
+@@ -388,6 +515,8 @@ __copy_user_zeroing_intel(void *to, cons |
9417 |
+ " movl %%eax,%0\n" |
9418 |
+ "7: rep; movsb\n" |
9419 |
+ "8:\n" |
9420 |
++ " pushl %%ss\n" |
9421 |
++ " popl %%ds\n" |
9422 |
+ ".section .fixup,\"ax\"\n" |
9423 |
+ "9: lea 0(%%eax,%0,4),%0\n" |
9424 |
+ "16: pushl %0\n" |
9425 |
+@@ -422,7 +551,7 @@ __copy_user_zeroing_intel(void *to, cons |
9426 |
+ " .long 7b,16b\n" |
9427 |
+ ".previous" |
9428 |
+ : "=&c"(size), "=&D" (d0), "=&S" (d1) |
9429 |
+- : "1"(to), "2"(from), "0"(size) |
9430 |
++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) |
9431 |
+ : "eax", "edx", "memory"); |
9432 |
+ return size; |
9433 |
+ } |
9434 |
+@@ -438,6 +567,7 @@ static unsigned long __copy_user_zeroing |
9435 |
+ int d0, d1; |
9436 |
+ |
9437 |
+ __asm__ __volatile__( |
9438 |
++ " movw %w6, %%ds\n" |
9439 |
+ " .align 2,0x90\n" |
9440 |
+ "0: movl 32(%4), %%eax\n" |
9441 |
+ " cmpl $67, %0\n" |
9442 |
+@@ -446,36 +576,36 @@ static unsigned long __copy_user_zeroing |
9443 |
+ " .align 2,0x90\n" |
9444 |
+ "2: movl 0(%4), %%eax\n" |
9445 |
+ "21: movl 4(%4), %%edx\n" |
9446 |
+- " movnti %%eax, 0(%3)\n" |
9447 |
+- " movnti %%edx, 4(%3)\n" |
9448 |
++ " movnti %%eax, %%es:0(%3)\n" |
9449 |
++ " movnti %%edx, %%es:4(%3)\n" |
9450 |
+ "3: movl 8(%4), %%eax\n" |
9451 |
+ "31: movl 12(%4),%%edx\n" |
9452 |
+- " movnti %%eax, 8(%3)\n" |
9453 |
+- " movnti %%edx, 12(%3)\n" |
9454 |
++ " movnti %%eax, %%es:8(%3)\n" |
9455 |
++ " movnti %%edx, %%es:12(%3)\n" |
9456 |
+ "4: movl 16(%4), %%eax\n" |
9457 |
+ "41: movl 20(%4), %%edx\n" |
9458 |
+- " movnti %%eax, 16(%3)\n" |
9459 |
+- " movnti %%edx, 20(%3)\n" |
9460 |
++ " movnti %%eax, %%es:16(%3)\n" |
9461 |
++ " movnti %%edx, %%es:20(%3)\n" |
9462 |
+ "10: movl 24(%4), %%eax\n" |
9463 |
+ "51: movl 28(%4), %%edx\n" |
9464 |
+- " movnti %%eax, 24(%3)\n" |
9465 |
+- " movnti %%edx, 28(%3)\n" |
9466 |
++ " movnti %%eax, %%es:24(%3)\n" |
9467 |
++ " movnti %%edx, %%es:28(%3)\n" |
9468 |
+ "11: movl 32(%4), %%eax\n" |
9469 |
+ "61: movl 36(%4), %%edx\n" |
9470 |
+- " movnti %%eax, 32(%3)\n" |
9471 |
+- " movnti %%edx, 36(%3)\n" |
9472 |
++ " movnti %%eax, %%es:32(%3)\n" |
9473 |
++ " movnti %%edx, %%es:36(%3)\n" |
9474 |
+ "12: movl 40(%4), %%eax\n" |
9475 |
+ "71: movl 44(%4), %%edx\n" |
9476 |
+- " movnti %%eax, 40(%3)\n" |
9477 |
+- " movnti %%edx, 44(%3)\n" |
9478 |
++ " movnti %%eax, %%es:40(%3)\n" |
9479 |
++ " movnti %%edx, %%es:44(%3)\n" |
9480 |
+ "13: movl 48(%4), %%eax\n" |
9481 |
+ "81: movl 52(%4), %%edx\n" |
9482 |
+- " movnti %%eax, 48(%3)\n" |
9483 |
+- " movnti %%edx, 52(%3)\n" |
9484 |
++ " movnti %%eax, %%es:48(%3)\n" |
9485 |
++ " movnti %%edx, %%es:52(%3)\n" |
9486 |
+ "14: movl 56(%4), %%eax\n" |
9487 |
+ "91: movl 60(%4), %%edx\n" |
9488 |
+- " movnti %%eax, 56(%3)\n" |
9489 |
+- " movnti %%edx, 60(%3)\n" |
9490 |
++ " movnti %%eax, %%es:56(%3)\n" |
9491 |
++ " movnti %%edx, %%es:60(%3)\n" |
9492 |
+ " addl $-64, %0\n" |
9493 |
+ " addl $64, %4\n" |
9494 |
+ " addl $64, %3\n" |
9495 |
+@@ -490,6 +620,8 @@ static unsigned long __copy_user_zeroing |
9496 |
+ " movl %%eax,%0\n" |
9497 |
+ "7: rep; movsb\n" |
9498 |
+ "8:\n" |
9499 |
++ " pushl %%ss\n" |
9500 |
++ " popl %%ds\n" |
9501 |
+ ".section .fixup,\"ax\"\n" |
9502 |
+ "9: lea 0(%%eax,%0,4),%0\n" |
9503 |
+ "16: pushl %0\n" |
9504 |
+@@ -524,7 +656,7 @@ static unsigned long __copy_user_zeroing |
9505 |
+ " .long 7b,16b\n" |
9506 |
+ ".previous" |
9507 |
+ : "=&c"(size), "=&D" (d0), "=&S" (d1) |
9508 |
+- : "1"(to), "2"(from), "0"(size) |
9509 |
++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) |
9510 |
+ : "eax", "edx", "memory"); |
9511 |
+ return size; |
9512 |
+ } |
9513 |
+@@ -535,6 +667,7 @@ static unsigned long __copy_user_intel_n |
9514 |
+ int d0, d1; |
9515 |
+ |
9516 |
+ __asm__ __volatile__( |
9517 |
++ " movw %w6, %%ds\n" |
9518 |
+ " .align 2,0x90\n" |
9519 |
+ "0: movl 32(%4), %%eax\n" |
9520 |
+ " cmpl $67, %0\n" |
9521 |
+@@ -543,36 +676,36 @@ static unsigned long __copy_user_intel_n |
9522 |
+ " .align 2,0x90\n" |
9523 |
+ "2: movl 0(%4), %%eax\n" |
9524 |
+ "21: movl 4(%4), %%edx\n" |
9525 |
+- " movnti %%eax, 0(%3)\n" |
9526 |
+- " movnti %%edx, 4(%3)\n" |
9527 |
++ " movnti %%eax, %%es:0(%3)\n" |
9528 |
++ " movnti %%edx, %%es:4(%3)\n" |
9529 |
+ "3: movl 8(%4), %%eax\n" |
9530 |
+ "31: movl 12(%4),%%edx\n" |
9531 |
+- " movnti %%eax, 8(%3)\n" |
9532 |
+- " movnti %%edx, 12(%3)\n" |
9533 |
++ " movnti %%eax, %%es:8(%3)\n" |
9534 |
++ " movnti %%edx, %%es:12(%3)\n" |
9535 |
+ "4: movl 16(%4), %%eax\n" |
9536 |
+ "41: movl 20(%4), %%edx\n" |
9537 |
+- " movnti %%eax, 16(%3)\n" |
9538 |
+- " movnti %%edx, 20(%3)\n" |
9539 |
++ " movnti %%eax, %%es:16(%3)\n" |
9540 |
++ " movnti %%edx, %%es:20(%3)\n" |
9541 |
+ "10: movl 24(%4), %%eax\n" |
9542 |
+ "51: movl 28(%4), %%edx\n" |
9543 |
+- " movnti %%eax, 24(%3)\n" |
9544 |
+- " movnti %%edx, 28(%3)\n" |
9545 |
++ " movnti %%eax, %%es:24(%3)\n" |
9546 |
++ " movnti %%edx, %%es:28(%3)\n" |
9547 |
+ "11: movl 32(%4), %%eax\n" |
9548 |
+ "61: movl 36(%4), %%edx\n" |
9549 |
+- " movnti %%eax, 32(%3)\n" |
9550 |
+- " movnti %%edx, 36(%3)\n" |
9551 |
++ " movnti %%eax, %%es:32(%3)\n" |
9552 |
++ " movnti %%edx, %%es:36(%3)\n" |
9553 |
+ "12: movl 40(%4), %%eax\n" |
9554 |
+ "71: movl 44(%4), %%edx\n" |
9555 |
+- " movnti %%eax, 40(%3)\n" |
9556 |
+- " movnti %%edx, 44(%3)\n" |
9557 |
++ " movnti %%eax, %%es:40(%3)\n" |
9558 |
++ " movnti %%edx, %%es:44(%3)\n" |
9559 |
+ "13: movl 48(%4), %%eax\n" |
9560 |
+ "81: movl 52(%4), %%edx\n" |
9561 |
+- " movnti %%eax, 48(%3)\n" |
9562 |
+- " movnti %%edx, 52(%3)\n" |
9563 |
++ " movnti %%eax, %%es:48(%3)\n" |
9564 |
++ " movnti %%edx, %%es:52(%3)\n" |
9565 |
+ "14: movl 56(%4), %%eax\n" |
9566 |
+ "91: movl 60(%4), %%edx\n" |
9567 |
+- " movnti %%eax, 56(%3)\n" |
9568 |
+- " movnti %%edx, 60(%3)\n" |
9569 |
++ " movnti %%eax, %%es:56(%3)\n" |
9570 |
++ " movnti %%edx, %%es:60(%3)\n" |
9571 |
+ " addl $-64, %0\n" |
9572 |
+ " addl $64, %4\n" |
9573 |
+ " addl $64, %3\n" |
9574 |
+@@ -587,6 +720,8 @@ static unsigned long __copy_user_intel_n |
9575 |
+ " movl %%eax,%0\n" |
9576 |
+ "7: rep; movsb\n" |
9577 |
+ "8:\n" |
9578 |
++ " pushl %%ss\n" |
9579 |
++ " popl %%ds\n" |
9580 |
+ ".section .fixup,\"ax\"\n" |
9581 |
+ "9: lea 0(%%eax,%0,4),%0\n" |
9582 |
+ "16: jmp 8b\n" |
9583 |
+@@ -615,7 +750,7 @@ static unsigned long __copy_user_intel_n |
9584 |
+ " .long 7b,16b\n" |
9585 |
+ ".previous" |
9586 |
+ : "=&c"(size), "=&D" (d0), "=&S" (d1) |
9587 |
+- : "1"(to), "2"(from), "0"(size) |
9588 |
++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) |
9589 |
+ : "eax", "edx", "memory"); |
9590 |
+ return size; |
9591 |
+ } |
9592 |
+@@ -628,90 +763,146 @@ static unsigned long __copy_user_intel_n |
9593 |
+ */ |
9594 |
+ unsigned long __copy_user_zeroing_intel(void *to, const void __user *from, |
9595 |
+ unsigned long size); |
9596 |
+-unsigned long __copy_user_intel(void __user *to, const void *from, |
9597 |
++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from, |
9598 |
++ unsigned long size); |
9599 |
++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from, |
9600 |
+ unsigned long size); |
9601 |
+ unsigned long __copy_user_zeroing_intel_nocache(void *to, |
9602 |
+ const void __user *from, unsigned long size); |
9603 |
+ #endif /* CONFIG_X86_INTEL_USERCOPY */ |
9604 |
+ |
9605 |
+ /* Generic arbitrary sized copy. */ |
9606 |
+-#define __copy_user(to,from,size) \ |
9607 |
+-do { \ |
9608 |
+- int __d0, __d1, __d2; \ |
9609 |
+- __asm__ __volatile__( \ |
9610 |
+- " cmp $7,%0\n" \ |
9611 |
+- " jbe 1f\n" \ |
9612 |
+- " movl %1,%0\n" \ |
9613 |
+- " negl %0\n" \ |
9614 |
+- " andl $7,%0\n" \ |
9615 |
+- " subl %0,%3\n" \ |
9616 |
+- "4: rep; movsb\n" \ |
9617 |
+- " movl %3,%0\n" \ |
9618 |
+- " shrl $2,%0\n" \ |
9619 |
+- " andl $3,%3\n" \ |
9620 |
+- " .align 2,0x90\n" \ |
9621 |
+- "0: rep; movsl\n" \ |
9622 |
+- " movl %3,%0\n" \ |
9623 |
+- "1: rep; movsb\n" \ |
9624 |
+- "2:\n" \ |
9625 |
+- ".section .fixup,\"ax\"\n" \ |
9626 |
+- "5: addl %3,%0\n" \ |
9627 |
+- " jmp 2b\n" \ |
9628 |
+- "3: lea 0(%3,%0,4),%0\n" \ |
9629 |
+- " jmp 2b\n" \ |
9630 |
+- ".previous\n" \ |
9631 |
+- ".section __ex_table,\"a\"\n" \ |
9632 |
+- " .align 4\n" \ |
9633 |
+- " .long 4b,5b\n" \ |
9634 |
+- " .long 0b,3b\n" \ |
9635 |
+- " .long 1b,2b\n" \ |
9636 |
+- ".previous" \ |
9637 |
+- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ |
9638 |
+- : "3"(size), "0"(size), "1"(to), "2"(from) \ |
9639 |
+- : "memory"); \ |
9640 |
+-} while (0) |
9641 |
+- |
9642 |
+-#define __copy_user_zeroing(to,from,size) \ |
9643 |
+-do { \ |
9644 |
+- int __d0, __d1, __d2; \ |
9645 |
+- __asm__ __volatile__( \ |
9646 |
+- " cmp $7,%0\n" \ |
9647 |
+- " jbe 1f\n" \ |
9648 |
+- " movl %1,%0\n" \ |
9649 |
+- " negl %0\n" \ |
9650 |
+- " andl $7,%0\n" \ |
9651 |
+- " subl %0,%3\n" \ |
9652 |
+- "4: rep; movsb\n" \ |
9653 |
+- " movl %3,%0\n" \ |
9654 |
+- " shrl $2,%0\n" \ |
9655 |
+- " andl $3,%3\n" \ |
9656 |
+- " .align 2,0x90\n" \ |
9657 |
+- "0: rep; movsl\n" \ |
9658 |
+- " movl %3,%0\n" \ |
9659 |
+- "1: rep; movsb\n" \ |
9660 |
+- "2:\n" \ |
9661 |
+- ".section .fixup,\"ax\"\n" \ |
9662 |
+- "5: addl %3,%0\n" \ |
9663 |
+- " jmp 6f\n" \ |
9664 |
+- "3: lea 0(%3,%0,4),%0\n" \ |
9665 |
+- "6: pushl %0\n" \ |
9666 |
+- " pushl %%eax\n" \ |
9667 |
+- " xorl %%eax,%%eax\n" \ |
9668 |
+- " rep; stosb\n" \ |
9669 |
+- " popl %%eax\n" \ |
9670 |
+- " popl %0\n" \ |
9671 |
+- " jmp 2b\n" \ |
9672 |
+- ".previous\n" \ |
9673 |
+- ".section __ex_table,\"a\"\n" \ |
9674 |
+- " .align 4\n" \ |
9675 |
+- " .long 4b,5b\n" \ |
9676 |
+- " .long 0b,3b\n" \ |
9677 |
+- " .long 1b,6b\n" \ |
9678 |
+- ".previous" \ |
9679 |
+- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ |
9680 |
+- : "3"(size), "0"(size), "1"(to), "2"(from) \ |
9681 |
+- : "memory"); \ |
9682 |
+-} while (0) |
9683 |
++static unsigned long |
9684 |
++__generic_copy_to_user(void __user *to, const void *from, unsigned long size) |
9685 |
++{ |
9686 |
++ int __d0, __d1, __d2; |
9687 |
++ |
9688 |
++ __asm__ __volatile__( |
9689 |
++ " movw %w8,%%es\n" |
9690 |
++ " cmp $7,%0\n" |
9691 |
++ " jbe 1f\n" |
9692 |
++ " movl %1,%0\n" |
9693 |
++ " negl %0\n" |
9694 |
++ " andl $7,%0\n" |
9695 |
++ " subl %0,%3\n" |
9696 |
++ "4: rep; movsb\n" |
9697 |
++ " movl %3,%0\n" |
9698 |
++ " shrl $2,%0\n" |
9699 |
++ " andl $3,%3\n" |
9700 |
++ " .align 2,0x90\n" |
9701 |
++ "0: rep; movsl\n" |
9702 |
++ " movl %3,%0\n" |
9703 |
++ "1: rep; movsb\n" |
9704 |
++ "2:\n" |
9705 |
++ " pushl %%ss\n" |
9706 |
++ " popl %%es\n" |
9707 |
++ ".section .fixup,\"ax\"\n" |
9708 |
++ "5: addl %3,%0\n" |
9709 |
++ " jmp 2b\n" |
9710 |
++ "3: lea 0(%3,%0,4),%0\n" |
9711 |
++ " jmp 2b\n" |
9712 |
++ ".previous\n" |
9713 |
++ ".section __ex_table,\"a\"\n" |
9714 |
++ " .align 4\n" |
9715 |
++ " .long 4b,5b\n" |
9716 |
++ " .long 0b,3b\n" |
9717 |
++ " .long 1b,2b\n" |
9718 |
++ ".previous" |
9719 |
++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) |
9720 |
++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS) |
9721 |
++ : "memory"); |
9722 |
++ return size; |
9723 |
++} |
9724 |
++ |
9725 |
++static unsigned long |
9726 |
++__generic_copy_from_user(void *to, const void __user *from, unsigned long size) |
9727 |
++{ |
9728 |
++ int __d0, __d1, __d2; |
9729 |
++ |
9730 |
++ __asm__ __volatile__( |
9731 |
++ " movw %w8,%%ds\n" |
9732 |
++ " cmp $7,%0\n" |
9733 |
++ " jbe 1f\n" |
9734 |
++ " movl %1,%0\n" |
9735 |
++ " negl %0\n" |
9736 |
++ " andl $7,%0\n" |
9737 |
++ " subl %0,%3\n" |
9738 |
++ "4: rep; movsb\n" |
9739 |
++ " movl %3,%0\n" |
9740 |
++ " shrl $2,%0\n" |
9741 |
++ " andl $3,%3\n" |
9742 |
++ " .align 2,0x90\n" |
9743 |
++ "0: rep; movsl\n" |
9744 |
++ " movl %3,%0\n" |
9745 |
++ "1: rep; movsb\n" |
9746 |
++ "2:\n" |
9747 |
++ " pushl %%ss\n" |
9748 |
++ " popl %%ds\n" |
9749 |
++ ".section .fixup,\"ax\"\n" |
9750 |
++ "5: addl %3,%0\n" |
9751 |
++ " jmp 2b\n" |
9752 |
++ "3: lea 0(%3,%0,4),%0\n" |
9753 |
++ " jmp 2b\n" |
9754 |
++ ".previous\n" |
9755 |
++ ".section __ex_table,\"a\"\n" |
9756 |
++ " .align 4\n" |
9757 |
++ " .long 4b,5b\n" |
9758 |
++ " .long 0b,3b\n" |
9759 |
++ " .long 1b,2b\n" |
9760 |
++ ".previous" |
9761 |
++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) |
9762 |
++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS) |
9763 |
++ : "memory"); |
9764 |
++ return size; |
9765 |
++} |
9766 |
++ |
9767 |
++static unsigned long |
9768 |
++__copy_user_zeroing(void *to, const void __user *from, unsigned long size) |
9769 |
++{ |
9770 |
++ int __d0, __d1, __d2; |
9771 |
++ |
9772 |
++ __asm__ __volatile__( |
9773 |
++ " movw %w8,%%ds\n" |
9774 |
++ " cmp $7,%0\n" |
9775 |
++ " jbe 1f\n" |
9776 |
++ " movl %1,%0\n" |
9777 |
++ " negl %0\n" |
9778 |
++ " andl $7,%0\n" |
9779 |
++ " subl %0,%3\n" |
9780 |
++ "4: rep; movsb\n" |
9781 |
++ " movl %3,%0\n" |
9782 |
++ " shrl $2,%0\n" |
9783 |
++ " andl $3,%3\n" |
9784 |
++ " .align 2,0x90\n" |
9785 |
++ "0: rep; movsl\n" |
9786 |
++ " movl %3,%0\n" |
9787 |
++ "1: rep; movsb\n" |
9788 |
++ "2:\n" |
9789 |
++ " pushl %%ss\n" |
9790 |
++ " popl %%ds\n" |
9791 |
++ ".section .fixup,\"ax\"\n" |
9792 |
++ "5: addl %3,%0\n" |
9793 |
++ " jmp 6f\n" |
9794 |
++ "3: lea 0(%3,%0,4),%0\n" |
9795 |
++ "6: pushl %0\n" |
9796 |
++ " pushl %%eax\n" |
9797 |
++ " xorl %%eax,%%eax\n" |
9798 |
++ " rep; stosb\n" |
9799 |
++ " popl %%eax\n" |
9800 |
++ " popl %0\n" |
9801 |
++ " jmp 2b\n" |
9802 |
++ ".previous\n" |
9803 |
++ ".section __ex_table,\"a\"\n" |
9804 |
++ " .align 4\n" |
9805 |
++ " .long 4b,5b\n" |
9806 |
++ " .long 0b,3b\n" |
9807 |
++ " .long 1b,6b\n" |
9808 |
++ ".previous" |
9809 |
++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) |
9810 |
++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS) |
9811 |
++ : "memory"); |
9812 |
++ return size; |
9813 |
++} |
9814 |
+ |
9815 |
+ unsigned long __copy_to_user_ll(void __user *to, const void *from, |
9816 |
+ unsigned long n) |
9817 |
+@@ -774,9 +965,9 @@ survive: |
9818 |
+ } |
9819 |
+ #endif |
9820 |
+ if (movsl_is_ok(to, from, n)) |
9821 |
+- __copy_user(to, from, n); |
9822 |
++ n = __generic_copy_to_user(to, from, n); |
9823 |
+ else |
9824 |
+- n = __copy_user_intel(to, from, n); |
9825 |
++ n = __generic_copy_to_user_intel(to, from, n); |
9826 |
+ return n; |
9827 |
+ } |
9828 |
+ EXPORT_SYMBOL(__copy_to_user_ll); |
9829 |
+@@ -785,7 +976,7 @@ unsigned long __copy_from_user_ll(void * |
9830 |
+ unsigned long n) |
9831 |
+ { |
9832 |
+ if (movsl_is_ok(to, from, n)) |
9833 |
+- __copy_user_zeroing(to, from, n); |
9834 |
++ n = __copy_user_zeroing(to, from, n); |
9835 |
+ else |
9836 |
+ n = __copy_user_zeroing_intel(to, from, n); |
9837 |
+ return n; |
9838 |
+@@ -796,9 +987,9 @@ unsigned long __copy_from_user_ll_nozero |
9839 |
+ unsigned long n) |
9840 |
+ { |
9841 |
+ if (movsl_is_ok(to, from, n)) |
9842 |
+- __copy_user(to, from, n); |
9843 |
++ n = __generic_copy_from_user(to, from, n); |
9844 |
+ else |
9845 |
+- n = __copy_user_intel((void __user *)to, |
9846 |
++ n = __generic_copy_from_user_intel((void __user *)to, |
9847 |
+ (const void *)from, n); |
9848 |
+ return n; |
9849 |
+ } |
9850 |
+@@ -809,9 +1000,9 @@ unsigned long __copy_from_user_ll_nocach |
9851 |
+ { |
9852 |
+ #ifdef CONFIG_X86_INTEL_USERCOPY |
9853 |
+ if ( n > 64 && cpu_has_xmm2) |
9854 |
+- n = __copy_user_zeroing_intel_nocache(to, from, n); |
9855 |
++ n = __copy_user_zeroing_intel_nocache(to, from, n); |
9856 |
+ else |
9857 |
+- __copy_user_zeroing(to, from, n); |
9858 |
++ n = __copy_user_zeroing(to, from, n); |
9859 |
+ #else |
9860 |
+ __copy_user_zeroing(to, from, n); |
9861 |
+ #endif |
9862 |
+@@ -823,11 +1014,11 @@ unsigned long __copy_from_user_ll_nocach |
9863 |
+ { |
9864 |
+ #ifdef CONFIG_X86_INTEL_USERCOPY |
9865 |
+ if ( n > 64 && cpu_has_xmm2) |
9866 |
+- n = __copy_user_intel_nocache(to, from, n); |
9867 |
++ n = __copy_user_intel_nocache(to, from, n); |
9868 |
+ else |
9869 |
+- __copy_user(to, from, n); |
9870 |
++ n = __generic_copy_from_user(to, from, n); |
9871 |
+ #else |
9872 |
+- __copy_user(to, from, n); |
9873 |
++ n = __generic_copy_from_user(to, from, n); |
9874 |
+ #endif |
9875 |
+ return n; |
9876 |
+ } |
9877 |
+@@ -880,3 +1071,30 @@ copy_from_user(void *to, const void __us |
9878 |
+ return n; |
9879 |
+ } |
9880 |
+ EXPORT_SYMBOL(copy_from_user); |
9881 |
++ |
9882 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
9883 |
++void __set_fs(mm_segment_t x, int cpu) |
9884 |
++{ |
9885 |
++ unsigned long limit = x.seg; |
9886 |
++ __u32 a, b; |
9887 |
++ |
9888 |
++ current_thread_info()->addr_limit = x; |
9889 |
++ if (likely(limit)) |
9890 |
++ limit = (limit - 1UL) >> PAGE_SHIFT; |
9891 |
++ pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC); |
9892 |
++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b); |
9893 |
++} |
9894 |
++ |
9895 |
++void set_fs(mm_segment_t x) |
9896 |
++{ |
9897 |
++ __set_fs(x, get_cpu()); |
9898 |
++ put_cpu_no_resched(); |
9899 |
++} |
9900 |
++#else |
9901 |
++void set_fs(mm_segment_t x) |
9902 |
++{ |
9903 |
++ current_thread_info()->addr_limit = x; |
9904 |
++} |
9905 |
++#endif |
9906 |
++ |
9907 |
++EXPORT_SYMBOL(set_fs); |
9908 |
+diff -urNp linux-2.6.24.4/arch/x86/mach-voyager/voyager_basic.c linux-2.6.24.4/arch/x86/mach-voyager/voyager_basic.c |
9909 |
+--- linux-2.6.24.4/arch/x86/mach-voyager/voyager_basic.c 2008-03-24 14:49:18.000000000 -0400 |
9910 |
++++ linux-2.6.24.4/arch/x86/mach-voyager/voyager_basic.c 2008-03-26 17:56:55.000000000 -0400 |
9911 |
+@@ -130,7 +130,7 @@ voyager_memory_detect(int region, __u32 |
9912 |
+ __u8 cmos[4]; |
9913 |
+ ClickMap_t *map; |
9914 |
+ unsigned long map_addr; |
9915 |
+- unsigned long old; |
9916 |
++ pte_t old; |
9917 |
+ |
9918 |
+ if(region >= CLICK_ENTRIES) { |
9919 |
+ printk("Voyager: Illegal ClickMap region %d\n", region); |
9920 |
+@@ -144,7 +144,7 @@ voyager_memory_detect(int region, __u32 |
9921 |
+ |
9922 |
+ /* steal page 0 for this */ |
9923 |
+ old = pg0[0]; |
9924 |
+- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT); |
9925 |
++ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT); |
9926 |
+ local_flush_tlb(); |
9927 |
+ /* now clear everything out but page 0 */ |
9928 |
+ map = (ClickMap_t *)(map_addr & (~PAGE_MASK)); |
9929 |
+diff -urNp linux-2.6.24.4/arch/x86/mach-voyager/voyager_smp.c linux-2.6.24.4/arch/x86/mach-voyager/voyager_smp.c |
9930 |
+--- linux-2.6.24.4/arch/x86/mach-voyager/voyager_smp.c 2008-03-24 14:49:18.000000000 -0400 |
9931 |
++++ linux-2.6.24.4/arch/x86/mach-voyager/voyager_smp.c 2008-03-26 17:56:55.000000000 -0400 |
9932 |
+@@ -554,6 +554,10 @@ do_boot_cpu(__u8 cpu) |
9933 |
+ __u32 *hijack_vector; |
9934 |
+ __u32 start_phys_address = setup_trampoline(); |
9935 |
+ |
9936 |
++#ifdef CONFIG_PAX_KERNEXEC |
9937 |
++ unsigned long cr0; |
9938 |
++#endif |
9939 |
++ |
9940 |
+ /* There's a clever trick to this: The linux trampoline is |
9941 |
+ * compiled to begin at absolute location zero, so make the |
9942 |
+ * address zero but have the data segment selector compensate |
9943 |
+@@ -573,7 +577,17 @@ do_boot_cpu(__u8 cpu) |
9944 |
+ |
9945 |
+ init_gdt(cpu); |
9946 |
+ per_cpu(current_task, cpu) = idle; |
9947 |
+- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
9948 |
++ |
9949 |
++#ifdef CONFIG_PAX_KERNEXEC |
9950 |
++ pax_open_kernel(cr0); |
9951 |
++#endif |
9952 |
++ |
9953 |
++ early_gdt_descr.address = get_cpu_gdt_table(cpu); |
9954 |
++ |
9955 |
++#ifdef CONFIG_PAX_KERNEXEC |
9956 |
++ pax_close_kernel(cr0); |
9957 |
++#endif |
9958 |
++ |
9959 |
+ irq_ctx_init(cpu); |
9960 |
+ |
9961 |
+ /* Note: Don't modify initial ss override */ |
9962 |
+@@ -1277,7 +1291,7 @@ smp_local_timer_interrupt(void) |
9963 |
+ per_cpu(prof_counter, cpu); |
9964 |
+ } |
9965 |
+ |
9966 |
+- update_process_times(user_mode_vm(get_irq_regs())); |
9967 |
++ update_process_times(user_mode(get_irq_regs())); |
9968 |
+ } |
9969 |
+ |
9970 |
+ if( ((1<<cpu) & voyager_extended_vic_processors) == 0) |
9971 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/boot_ioremap_32.c linux-2.6.24.4/arch/x86/mm/boot_ioremap_32.c |
9972 |
+--- linux-2.6.24.4/arch/x86/mm/boot_ioremap_32.c 2008-03-24 14:49:18.000000000 -0400 |
9973 |
++++ linux-2.6.24.4/arch/x86/mm/boot_ioremap_32.c 2008-03-26 17:56:55.000000000 -0400 |
9974 |
+@@ -7,57 +7,37 @@ |
9975 |
+ * Written by Dave Hansen <haveblue@××××××.com> |
9976 |
+ */ |
9977 |
+ |
9978 |
+- |
9979 |
+-/* |
9980 |
+- * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE |
9981 |
+- * keeps that from happening. If anyone has a better way, I'm listening. |
9982 |
+- * |
9983 |
+- * boot_pte_t is defined only if this all works correctly |
9984 |
+- */ |
9985 |
+- |
9986 |
+-#undef CONFIG_X86_PAE |
9987 |
+ #undef CONFIG_PARAVIRT |
9988 |
+ #include <asm/page.h> |
9989 |
+ #include <asm/pgtable.h> |
9990 |
+ #include <asm/tlbflush.h> |
9991 |
+ #include <linux/init.h> |
9992 |
+ #include <linux/stddef.h> |
9993 |
+- |
9994 |
+-/* |
9995 |
+- * I'm cheating here. It is known that the two boot PTE pages are |
9996 |
+- * allocated next to each other. I'm pretending that they're just |
9997 |
+- * one big array. |
9998 |
+- */ |
9999 |
+- |
10000 |
+-#define BOOT_PTE_PTRS (PTRS_PER_PTE*2) |
10001 |
+- |
10002 |
+-static unsigned long boot_pte_index(unsigned long vaddr) |
10003 |
+-{ |
10004 |
+- return __pa(vaddr) >> PAGE_SHIFT; |
10005 |
+-} |
10006 |
+- |
10007 |
+-static inline boot_pte_t* boot_vaddr_to_pte(void *address) |
10008 |
+-{ |
10009 |
+- boot_pte_t* boot_pg = (boot_pte_t*)pg0; |
10010 |
+- return &boot_pg[boot_pte_index((unsigned long)address)]; |
10011 |
+-} |
10012 |
++#include <linux/sched.h> |
10013 |
+ |
10014 |
+ /* |
10015 |
+ * This is only for a caller who is clever enough to page-align |
10016 |
+ * phys_addr and virtual_source, and who also has a preference |
10017 |
+ * about which virtual address from which to steal ptes |
10018 |
+ */ |
10019 |
+-static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, |
10020 |
+- void* virtual_source) |
10021 |
++static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, |
10022 |
++ char* virtual_source) |
10023 |
+ { |
10024 |
+- boot_pte_t* pte; |
10025 |
+- int i; |
10026 |
+- char *vaddr = virtual_source; |
10027 |
++ pgd_t *pgd; |
10028 |
++ pud_t *pud; |
10029 |
++ pmd_t *pmd; |
10030 |
++ pte_t* pte; |
10031 |
++ unsigned int i; |
10032 |
++ unsigned long vaddr = (unsigned long)virtual_source; |
10033 |
++ |
10034 |
++ pgd = pgd_offset_k(vaddr); |
10035 |
++ pud = pud_offset(pgd, vaddr); |
10036 |
++ pmd = pmd_offset(pud, vaddr); |
10037 |
++ pte = pte_offset_kernel(pmd, vaddr); |
10038 |
+ |
10039 |
+- pte = boot_vaddr_to_pte(virtual_source); |
10040 |
+ for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) { |
10041 |
+ set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL)); |
10042 |
+- __flush_tlb_one(&vaddr[i*PAGE_SIZE]); |
10043 |
++ __flush_tlb_one(&virtual_source[i*PAGE_SIZE]); |
10044 |
+ } |
10045 |
+ } |
10046 |
+ |
10047 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/extable_32.c linux-2.6.24.4/arch/x86/mm/extable_32.c |
10048 |
+--- linux-2.6.24.4/arch/x86/mm/extable_32.c 2008-03-24 14:49:18.000000000 -0400 |
10049 |
++++ linux-2.6.24.4/arch/x86/mm/extable_32.c 2008-03-26 17:56:55.000000000 -0400 |
10050 |
+@@ -4,14 +4,63 @@ |
10051 |
+ |
10052 |
+ #include <linux/module.h> |
10053 |
+ #include <linux/spinlock.h> |
10054 |
++#include <linux/sort.h> |
10055 |
+ #include <asm/uaccess.h> |
10056 |
+ |
10057 |
++/* |
10058 |
++ * The exception table needs to be sorted so that the binary |
10059 |
++ * search that we use to find entries in it works properly. |
10060 |
++ * This is used both for the kernel exception table and for |
10061 |
++ * the exception tables of modules that get loaded. |
10062 |
++ */ |
10063 |
++static int cmp_ex(const void *a, const void *b) |
10064 |
++{ |
10065 |
++ const struct exception_table_entry *x = a, *y = b; |
10066 |
++ |
10067 |
++ /* avoid overflow */ |
10068 |
++ if (x->insn > y->insn) |
10069 |
++ return 1; |
10070 |
++ if (x->insn < y->insn) |
10071 |
++ return -1; |
10072 |
++ return 0; |
10073 |
++} |
10074 |
++ |
10075 |
++static void swap_ex(void *a, void *b, int size) |
10076 |
++{ |
10077 |
++ struct exception_table_entry t, *x = a, *y = b; |
10078 |
++ |
10079 |
++#ifdef CONFIG_PAX_KERNEXEC |
10080 |
++ unsigned long cr0; |
10081 |
++#endif |
10082 |
++ |
10083 |
++ t = *x; |
10084 |
++ |
10085 |
++#ifdef CONFIG_PAX_KERNEXEC |
10086 |
++ pax_open_kernel(cr0); |
10087 |
++#endif |
10088 |
++ |
10089 |
++ *x = *y; |
10090 |
++ *y = t; |
10091 |
++ |
10092 |
++#ifdef CONFIG_PAX_KERNEXEC |
10093 |
++ pax_close_kernel(cr0); |
10094 |
++#endif |
10095 |
++ |
10096 |
++} |
10097 |
++ |
10098 |
++void sort_extable(struct exception_table_entry *start, |
10099 |
++ struct exception_table_entry *finish) |
10100 |
++{ |
10101 |
++ sort(start, finish - start, sizeof(struct exception_table_entry), |
10102 |
++ cmp_ex, swap_ex); |
10103 |
++} |
10104 |
++ |
10105 |
+ int fixup_exception(struct pt_regs *regs) |
10106 |
+ { |
10107 |
+ const struct exception_table_entry *fixup; |
10108 |
+ |
10109 |
+ #ifdef CONFIG_PNPBIOS |
10110 |
+- if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs))) |
10111 |
++ if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs))) |
10112 |
+ { |
10113 |
+ extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; |
10114 |
+ extern u32 pnp_bios_is_utter_crap; |
10115 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/extable_64.c linux-2.6.24.4/arch/x86/mm/extable_64.c |
10116 |
+--- linux-2.6.24.4/arch/x86/mm/extable_64.c 2008-03-24 14:49:18.000000000 -0400 |
10117 |
++++ linux-2.6.24.4/arch/x86/mm/extable_64.c 2008-03-26 17:56:55.000000000 -0400 |
10118 |
+@@ -4,9 +4,58 @@ |
10119 |
+ |
10120 |
+ #include <linux/module.h> |
10121 |
+ #include <linux/spinlock.h> |
10122 |
++#include <linux/sort.h> |
10123 |
+ #include <linux/init.h> |
10124 |
+ #include <asm/uaccess.h> |
10125 |
+ |
10126 |
++/* |
10127 |
++ * The exception table needs to be sorted so that the binary |
10128 |
++ * search that we use to find entries in it works properly. |
10129 |
++ * This is used both for the kernel exception table and for |
10130 |
++ * the exception tables of modules that get loaded. |
10131 |
++ */ |
10132 |
++static int cmp_ex(const void *a, const void *b) |
10133 |
++{ |
10134 |
++ const struct exception_table_entry *x = a, *y = b; |
10135 |
++ |
10136 |
++ /* avoid overflow */ |
10137 |
++ if (x->insn > y->insn) |
10138 |
++ return 1; |
10139 |
++ if (x->insn < y->insn) |
10140 |
++ return -1; |
10141 |
++ return 0; |
10142 |
++} |
10143 |
++ |
10144 |
++static void swap_ex(void *a, void *b, int size) |
10145 |
++{ |
10146 |
++ struct exception_table_entry t, *x = a, *y = b; |
10147 |
++ |
10148 |
++#ifdef CONFIG_PAX_KERNEXEC |
10149 |
++ unsigned long cr0; |
10150 |
++#endif |
10151 |
++ |
10152 |
++ t = *x; |
10153 |
++ |
10154 |
++#ifdef CONFIG_PAX_KERNEXEC |
10155 |
++ pax_open_kernel(cr0); |
10156 |
++#endif |
10157 |
++ |
10158 |
++ *x = *y; |
10159 |
++ *y = t; |
10160 |
++ |
10161 |
++#ifdef CONFIG_PAX_KERNEXEC |
10162 |
++ pax_close_kernel(cr0); |
10163 |
++#endif |
10164 |
++ |
10165 |
++} |
10166 |
++ |
10167 |
++void sort_extable(struct exception_table_entry *start, |
10168 |
++ struct exception_table_entry *finish) |
10169 |
++{ |
10170 |
++ sort(start, finish - start, sizeof(struct exception_table_entry), |
10171 |
++ cmp_ex, swap_ex); |
10172 |
++} |
10173 |
++ |
10174 |
+ /* Simple binary search */ |
10175 |
+ const struct exception_table_entry * |
10176 |
+ search_extable(const struct exception_table_entry *first, |
10177 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/fault_32.c linux-2.6.24.4/arch/x86/mm/fault_32.c |
10178 |
+--- linux-2.6.24.4/arch/x86/mm/fault_32.c 2008-03-24 14:49:18.000000000 -0400 |
10179 |
++++ linux-2.6.24.4/arch/x86/mm/fault_32.c 2008-03-26 18:53:27.000000000 -0400 |
10180 |
+@@ -26,10 +26,14 @@ |
10181 |
+ #include <linux/uaccess.h> |
10182 |
+ #include <linux/kdebug.h> |
10183 |
+ #include <linux/kprobes.h> |
10184 |
++#include <linux/unistd.h> |
10185 |
++#include <linux/compiler.h> |
10186 |
++#include <linux/binfmts.h> |
10187 |
+ |
10188 |
+ #include <asm/system.h> |
10189 |
+ #include <asm/desc.h> |
10190 |
+ #include <asm/segment.h> |
10191 |
++#include <asm/tlbflush.h> |
10192 |
+ |
10193 |
+ extern void die(const char *,struct pt_regs *,long); |
10194 |
+ |
10195 |
+@@ -39,7 +43,7 @@ static inline int notify_page_fault(stru |
10196 |
+ int ret = 0; |
10197 |
+ |
10198 |
+ /* kprobe_running() needs smp_processor_id() */ |
10199 |
+- if (!user_mode_vm(regs)) { |
10200 |
++ if (!user_mode(regs)) { |
10201 |
+ preempt_disable(); |
10202 |
+ if (kprobe_running() && kprobe_fault_handler(regs, 14)) |
10203 |
+ ret = 1; |
10204 |
+@@ -74,7 +78,8 @@ static inline unsigned long get_segment_ |
10205 |
+ { |
10206 |
+ unsigned long eip = regs->eip; |
10207 |
+ unsigned seg = regs->xcs & 0xffff; |
10208 |
+- u32 seg_ar, seg_limit, base, *desc; |
10209 |
++ u32 seg_ar, seg_limit, base; |
10210 |
++ struct desc_struct *desc; |
10211 |
+ |
10212 |
+ /* Unlikely, but must come before segment checks. */ |
10213 |
+ if (unlikely(regs->eflags & VM_MASK)) { |
10214 |
+@@ -88,7 +93,7 @@ static inline unsigned long get_segment_ |
10215 |
+ |
10216 |
+ /* By far the most common cases. */ |
10217 |
+ if (likely(SEGMENT_IS_FLAT_CODE(seg))) |
10218 |
+- return eip; |
10219 |
++ return seg == __KERNEL_CS ? ktla_ktva(eip) : eip; |
10220 |
+ |
10221 |
+ /* Check the segment exists, is within the current LDT/GDT size, |
10222 |
+ that kernel/user (ring 0..3) has the appropriate privilege, |
10223 |
+@@ -103,21 +108,24 @@ static inline unsigned long get_segment_ |
10224 |
+ /* Get the GDT/LDT descriptor base. |
10225 |
+ When you look for races in this code remember that |
10226 |
+ LDT and other horrors are only used in user space. */ |
10227 |
+- if (seg & (1<<2)) { |
10228 |
++ if (seg & SEGMENT_LDT) { |
10229 |
+ /* Must lock the LDT while reading it. */ |
10230 |
+ mutex_lock(¤t->mm->context.lock); |
10231 |
+- desc = current->mm->context.ldt; |
10232 |
+- desc = (void *)desc + (seg & ~7); |
10233 |
++ if ((seg >> 3) >= current->mm->context.size) { |
10234 |
++ mutex_unlock(¤t->mm->context.lock); |
10235 |
++ *eip_limit = 0; |
10236 |
++ return 1; /* So that returned eip > *eip_limit. */ |
10237 |
++ } |
10238 |
++ desc = ¤t->mm->context.ldt[seg >> 3]; |
10239 |
+ } else { |
10240 |
+ /* Must disable preemption while reading the GDT. */ |
10241 |
+- desc = (u32 *)get_cpu_gdt_table(get_cpu()); |
10242 |
+- desc = (void *)desc + (seg & ~7); |
10243 |
++ desc = &get_cpu_gdt_table(get_cpu())[seg >> 3]; |
10244 |
+ } |
10245 |
+ |
10246 |
+ /* Decode the code segment base from the descriptor */ |
10247 |
+- base = get_desc_base((unsigned long *)desc); |
10248 |
++ base = get_desc_base(desc); |
10249 |
+ |
10250 |
+- if (seg & (1<<2)) { |
10251 |
++ if (seg & SEGMENT_LDT) { |
10252 |
+ mutex_unlock(¤t->mm->context.lock); |
10253 |
+ } else |
10254 |
+ put_cpu(); |
10255 |
+@@ -216,6 +224,30 @@ static noinline void force_sig_info_faul |
10256 |
+ |
10257 |
+ fastcall void do_invalid_op(struct pt_regs *, unsigned long); |
10258 |
+ |
10259 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
10260 |
++static int pax_handle_fetch_fault(struct pt_regs *regs); |
10261 |
++#endif |
10262 |
++ |
10263 |
++#ifdef CONFIG_PAX_PAGEEXEC |
10264 |
++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address) |
10265 |
++{ |
10266 |
++ pgd_t *pgd; |
10267 |
++ pud_t *pud; |
10268 |
++ pmd_t *pmd; |
10269 |
++ |
10270 |
++ pgd = pgd_offset(mm, address); |
10271 |
++ if (!pgd_present(*pgd)) |
10272 |
++ return NULL; |
10273 |
++ pud = pud_offset(pgd, address); |
10274 |
++ if (!pud_present(*pud)) |
10275 |
++ return NULL; |
10276 |
++ pmd = pmd_offset(pud, address); |
10277 |
++ if (!pmd_present(*pmd)) |
10278 |
++ return NULL; |
10279 |
++ return pmd; |
10280 |
++} |
10281 |
++#endif |
10282 |
++ |
10283 |
+ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) |
10284 |
+ { |
10285 |
+ unsigned index = pgd_index(address); |
10286 |
+@@ -299,19 +331,26 @@ fastcall void __kprobes do_page_fault(st |
10287 |
+ struct task_struct *tsk; |
10288 |
+ struct mm_struct *mm; |
10289 |
+ struct vm_area_struct * vma; |
10290 |
+- unsigned long address; |
10291 |
+ int write, si_code; |
10292 |
+ int fault; |
10293 |
++ pte_t *pte; |
10294 |
++ |
10295 |
++#ifdef CONFIG_PAX_PAGEEXEC |
10296 |
++ pmd_t *pmd; |
10297 |
++ spinlock_t *ptl; |
10298 |
++ unsigned char pte_mask; |
10299 |
++#endif |
10300 |
++ |
10301 |
++ /* get the address */ |
10302 |
++ const unsigned long address = read_cr2(); |
10303 |
+ |
10304 |
+ /* |
10305 |
+ * We can fault from pretty much anywhere, with unknown IRQ state. |
10306 |
+ */ |
10307 |
+ trace_hardirqs_fixup(); |
10308 |
+ |
10309 |
+- /* get the address */ |
10310 |
+- address = read_cr2(); |
10311 |
+- |
10312 |
+ tsk = current; |
10313 |
++ mm = tsk->mm; |
10314 |
+ |
10315 |
+ si_code = SEGV_MAPERR; |
10316 |
+ |
10317 |
+@@ -348,14 +387,12 @@ fastcall void __kprobes do_page_fault(st |
10318 |
+ if (regs->eflags & (X86_EFLAGS_IF|VM_MASK)) |
10319 |
+ local_irq_enable(); |
10320 |
+ |
10321 |
+- mm = tsk->mm; |
10322 |
+- |
10323 |
+ /* |
10324 |
+ * If we're in an interrupt, have no user context or are running in an |
10325 |
+ * atomic region then we must not take the fault.. |
10326 |
+ */ |
10327 |
+ if (in_atomic() || !mm) |
10328 |
+- goto bad_area_nosemaphore; |
10329 |
++ goto bad_area_nopax; |
10330 |
+ |
10331 |
+ /* When running in the kernel we expect faults to occur only to |
10332 |
+ * addresses in user space. All other faults represent errors in the |
10333 |
+@@ -375,10 +412,104 @@ fastcall void __kprobes do_page_fault(st |
10334 |
+ if (!down_read_trylock(&mm->mmap_sem)) { |
10335 |
+ if ((error_code & 4) == 0 && |
10336 |
+ !search_exception_tables(regs->eip)) |
10337 |
+- goto bad_area_nosemaphore; |
10338 |
++ goto bad_area_nopax; |
10339 |
+ down_read(&mm->mmap_sem); |
10340 |
+ } |
10341 |
+ |
10342 |
++#ifdef CONFIG_PAX_PAGEEXEC |
10343 |
++ if (nx_enabled || (error_code & 5) != 5 || (regs->eflags & X86_EFLAGS_VM) || |
10344 |
++ !(mm->pax_flags & MF_PAX_PAGEEXEC)) |
10345 |
++ goto not_pax_fault; |
10346 |
++ |
10347 |
++ /* PaX: it's our fault, let's handle it if we can */ |
10348 |
++ |
10349 |
++ /* PaX: take a look at read faults before acquiring any locks */ |
10350 |
++ if (unlikely(!(error_code & 2) && (regs->eip == address))) { |
10351 |
++ /* instruction fetch attempt from a protected page in user mode */ |
10352 |
++ up_read(&mm->mmap_sem); |
10353 |
++ |
10354 |
++#ifdef CONFIG_PAX_EMUTRAMP |
10355 |
++ switch (pax_handle_fetch_fault(regs)) { |
10356 |
++ case 2: |
10357 |
++ return; |
10358 |
++ } |
10359 |
++#endif |
10360 |
++ |
10361 |
++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp); |
10362 |
++ do_group_exit(SIGKILL); |
10363 |
++ } |
10364 |
++ |
10365 |
++ pmd = pax_get_pmd(mm, address); |
10366 |
++ if (unlikely(!pmd)) |
10367 |
++ goto not_pax_fault; |
10368 |
++ |
10369 |
++ pte = pte_offset_map_lock(mm, pmd, address, &ptl); |
10370 |
++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) { |
10371 |
++ pte_unmap_unlock(pte, ptl); |
10372 |
++ goto not_pax_fault; |
10373 |
++ } |
10374 |
++ |
10375 |
++ if (unlikely((error_code & 2) && !pte_write(*pte))) { |
10376 |
++ /* write attempt to a protected page in user mode */ |
10377 |
++ pte_unmap_unlock(pte, ptl); |
10378 |
++ goto not_pax_fault; |
10379 |
++ } |
10380 |
++ |
10381 |
++#ifdef CONFIG_SMP |
10382 |
++ if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask))) |
10383 |
++#else |
10384 |
++ if (likely(address > get_limit(regs->xcs))) |
10385 |
++#endif |
10386 |
++ { |
10387 |
++ set_pte(pte, pte_mkread(*pte)); |
10388 |
++ __flush_tlb_one(address); |
10389 |
++ pte_unmap_unlock(pte, ptl); |
10390 |
++ up_read(&mm->mmap_sem); |
10391 |
++ return; |
10392 |
++ } |
10393 |
++ |
10394 |
++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1)); |
10395 |
++ |
10396 |
++ /* |
10397 |
++ * PaX: fill DTLB with user rights and retry |
10398 |
++ */ |
10399 |
++ __asm__ __volatile__ ( |
10400 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
10401 |
++ "movw %w4,%%es\n" |
10402 |
++#endif |
10403 |
++ "orb %2,(%1)\n" |
10404 |
++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC) |
10405 |
++/* |
10406 |
++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's |
10407 |
++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any* |
10408 |
++ * page fault when examined during a TLB load attempt. this is true not only |
10409 |
++ * for PTEs holding a non-present entry but also present entries that will |
10410 |
++ * raise a page fault (such as those set up by PaX, or the copy-on-write |
10411 |
++ * mechanism). in effect it means that we do *not* need to flush the TLBs |
10412 |
++ * for our target pages since their PTEs are simply not in the TLBs at all. |
10413 |
++ |
10414 |
++ * the best thing in omitting it is that we gain around 15-20% speed in the |
10415 |
++ * fast path of the page fault handler and can get rid of tracing since we |
10416 |
++ * can no longer flush unintended entries. |
10417 |
++ */ |
10418 |
++ "invlpg (%0)\n" |
10419 |
++#endif |
10420 |
++ "testb $0,%%es:(%0)\n" |
10421 |
++ "xorb %3,(%1)\n" |
10422 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
10423 |
++ "pushl %%ss\n" |
10424 |
++ "popl %%es\n" |
10425 |
++#endif |
10426 |
++ : |
10427 |
++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS) |
10428 |
++ : "memory", "cc"); |
10429 |
++ pte_unmap_unlock(pte, ptl); |
10430 |
++ up_read(&mm->mmap_sem); |
10431 |
++ return; |
10432 |
++ |
10433 |
++not_pax_fault: |
10434 |
++#endif |
10435 |
++ |
10436 |
+ vma = find_vma(mm, address); |
10437 |
+ if (!vma) |
10438 |
+ goto bad_area; |
10439 |
+@@ -396,6 +527,12 @@ fastcall void __kprobes do_page_fault(st |
10440 |
+ if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp) |
10441 |
+ goto bad_area; |
10442 |
+ } |
10443 |
++ |
10444 |
++#ifdef CONFIG_PAX_SEGMEXEC |
10445 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1) |
10446 |
++ goto bad_area; |
10447 |
++#endif |
10448 |
++ |
10449 |
+ if (expand_stack(vma, address)) |
10450 |
+ goto bad_area; |
10451 |
+ /* |
10452 |
+@@ -405,6 +542,8 @@ fastcall void __kprobes do_page_fault(st |
10453 |
+ good_area: |
10454 |
+ si_code = SEGV_ACCERR; |
10455 |
+ write = 0; |
10456 |
++ if (nx_enabled && (error_code & 16) && !(vma->vm_flags & VM_EXEC)) |
10457 |
++ goto bad_area; |
10458 |
+ switch (error_code & 3) { |
10459 |
+ default: /* 3: write, present */ |
10460 |
+ /* fall through */ |
10461 |
+@@ -458,6 +597,49 @@ bad_area: |
10462 |
+ up_read(&mm->mmap_sem); |
10463 |
+ |
10464 |
+ bad_area_nosemaphore: |
10465 |
++ |
10466 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
10467 |
++ if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) { |
10468 |
++ /* |
10469 |
++ * It's possible to have interrupts off here. |
10470 |
++ */ |
10471 |
++ local_irq_enable(); |
10472 |
++ |
10473 |
++#ifdef CONFIG_PAX_PAGEEXEC |
10474 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && |
10475 |
++ ((nx_enabled && ((error_code & 16) || !(error_code & 3)) && (regs->eip == address)))) { |
10476 |
++ |
10477 |
++#ifdef CONFIG_PAX_EMUTRAMP |
10478 |
++ switch (pax_handle_fetch_fault(regs)) { |
10479 |
++ case 2: |
10480 |
++ return; |
10481 |
++ } |
10482 |
++#endif |
10483 |
++ |
10484 |
++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp); |
10485 |
++ do_group_exit(SIGKILL); |
10486 |
++ } |
10487 |
++#endif |
10488 |
++ |
10489 |
++#ifdef CONFIG_PAX_SEGMEXEC |
10490 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) { |
10491 |
++ |
10492 |
++#ifdef CONFIG_PAX_EMUTRAMP |
10493 |
++ switch (pax_handle_fetch_fault(regs)) { |
10494 |
++ case 2: |
10495 |
++ return; |
10496 |
++ } |
10497 |
++#endif |
10498 |
++ |
10499 |
++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp); |
10500 |
++ do_group_exit(SIGKILL); |
10501 |
++ } |
10502 |
++#endif |
10503 |
++ |
10504 |
++ } |
10505 |
++#endif |
10506 |
++ |
10507 |
++bad_area_nopax: |
10508 |
+ /* User mode accesses just cause a SIGSEGV */ |
10509 |
+ if (error_code & 4) { |
10510 |
+ /* |
10511 |
+@@ -495,7 +677,7 @@ bad_area_nosemaphore: |
10512 |
+ if (boot_cpu_data.f00f_bug) { |
10513 |
+ unsigned long nr; |
10514 |
+ |
10515 |
+- nr = (address - idt_descr.address) >> 3; |
10516 |
++ nr = (address - (unsigned long)idt_descr.address) >> 3; |
10517 |
+ |
10518 |
+ if (nr == 6) { |
10519 |
+ do_invalid_op(regs, 0); |
10520 |
+@@ -528,18 +710,34 @@ no_context: |
10521 |
+ __typeof__(pte_val(__pte(0))) page; |
10522 |
+ |
10523 |
+ #ifdef CONFIG_X86_PAE |
10524 |
+- if (error_code & 16) { |
10525 |
+- pte_t *pte = lookup_address(address); |
10526 |
++ if (nx_enabled && (error_code & 16)) { |
10527 |
++ pte = lookup_address(address); |
10528 |
+ |
10529 |
+ if (pte && pte_present(*pte) && !pte_exec_kernel(*pte)) |
10530 |
+ printk(KERN_CRIT "kernel tried to execute " |
10531 |
+ "NX-protected page - exploit attempt? " |
10532 |
+- "(uid: %d)\n", current->uid); |
10533 |
++ "(uid: %d, task: %s, pid: %d)\n", |
10534 |
++ tsk->uid, tsk->comm, task_pid_nr(tsk)); |
10535 |
+ } |
10536 |
+ #endif |
10537 |
+ if (address < PAGE_SIZE) |
10538 |
+ printk(KERN_ALERT "BUG: unable to handle kernel NULL " |
10539 |
+ "pointer dereference"); |
10540 |
++ |
10541 |
++#ifdef CONFIG_PAX_KERNEXEC |
10542 |
++#ifdef CONFIG_MODULES |
10543 |
++ else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END) |
10544 |
++#else |
10545 |
++ else if (init_mm.start_code <= address && address < init_mm.end_code) |
10546 |
++#endif |
10547 |
++ if (tsk->signal->curr_ip) |
10548 |
++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", |
10549 |
++ NIPQUAD(tsk->signal->curr_ip), tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid); |
10550 |
++ else |
10551 |
++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", |
10552 |
++ tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid); |
10553 |
++#endif |
10554 |
++ |
10555 |
+ else |
10556 |
+ printk(KERN_ALERT "BUG: unable to handle kernel paging" |
10557 |
+ " request"); |
10558 |
+@@ -585,7 +783,7 @@ no_context: |
10559 |
+ tsk->thread.error_code = error_code; |
10560 |
+ die("Oops", regs, error_code); |
10561 |
+ bust_spinlocks(0); |
10562 |
+- do_exit(SIGKILL); |
10563 |
++ do_group_exit(SIGKILL); |
10564 |
+ |
10565 |
+ /* |
10566 |
+ * We ran out of memory, or some other thing happened to us that made |
10567 |
+@@ -657,3 +855,92 @@ void vmalloc_sync_all(void) |
10568 |
+ start = address + PGDIR_SIZE; |
10569 |
+ } |
10570 |
+ } |
10571 |
++ |
10572 |
++#ifdef CONFIG_PAX_EMUTRAMP |
10573 |
++/* |
10574 |
++ * PaX: decide what to do with offenders (regs->eip = fault address) |
10575 |
++ * |
10576 |
++ * returns 1 when task should be killed |
10577 |
++ * 2 when gcc trampoline was detected |
10578 |
++ */ |
10579 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
10580 |
++{ |
10581 |
++ int err; |
10582 |
++ |
10583 |
++ if (regs->eflags & X86_EFLAGS_VM) |
10584 |
++ return 1; |
10585 |
++ |
10586 |
++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) |
10587 |
++ return 1; |
10588 |
++ |
10589 |
++ do { /* PaX: gcc trampoline emulation #1 */ |
10590 |
++ unsigned char mov1, mov2; |
10591 |
++ unsigned short jmp; |
10592 |
++ unsigned long addr1, addr2; |
10593 |
++ |
10594 |
++ err = get_user(mov1, (unsigned char __user *)regs->eip); |
10595 |
++ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1)); |
10596 |
++ err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5)); |
10597 |
++ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6)); |
10598 |
++ err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10)); |
10599 |
++ |
10600 |
++ if (err) |
10601 |
++ break; |
10602 |
++ |
10603 |
++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) { |
10604 |
++ regs->ecx = addr1; |
10605 |
++ regs->eax = addr2; |
10606 |
++ regs->eip = addr2; |
10607 |
++ return 2; |
10608 |
++ } |
10609 |
++ } while (0); |
10610 |
++ |
10611 |
++ do { /* PaX: gcc trampoline emulation #2 */ |
10612 |
++ unsigned char mov, jmp; |
10613 |
++ unsigned long addr1, addr2; |
10614 |
++ |
10615 |
++ err = get_user(mov, (unsigned char __user *)regs->eip); |
10616 |
++ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1)); |
10617 |
++ err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5)); |
10618 |
++ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6)); |
10619 |
++ |
10620 |
++ if (err) |
10621 |
++ break; |
10622 |
++ |
10623 |
++ if (mov == 0xB9 && jmp == 0xE9) { |
10624 |
++ regs->ecx = addr1; |
10625 |
++ regs->eip += addr2 + 10; |
10626 |
++ return 2; |
10627 |
++ } |
10628 |
++ } while (0); |
10629 |
++ |
10630 |
++ return 1; /* PaX in action */ |
10631 |
++} |
10632 |
++#endif |
10633 |
++ |
10634 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
10635 |
++void pax_report_insns(void *pc, void *sp) |
10636 |
++{ |
10637 |
++ long i; |
10638 |
++ |
10639 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
10640 |
++ for (i = 0; i < 20; i++) { |
10641 |
++ unsigned char c; |
10642 |
++ if (get_user(c, (unsigned char __user *)pc+i)) |
10643 |
++ printk("?? "); |
10644 |
++ else |
10645 |
++ printk("%02x ", c); |
10646 |
++ } |
10647 |
++ printk("\n"); |
10648 |
++ |
10649 |
++ printk(KERN_ERR "PAX: bytes at SP-4: "); |
10650 |
++ for (i = -1; i < 20; i++) { |
10651 |
++ unsigned long c; |
10652 |
++ if (get_user(c, (unsigned long __user *)sp+i)) |
10653 |
++ printk("???????? "); |
10654 |
++ else |
10655 |
++ printk("%08lx ", c); |
10656 |
++ } |
10657 |
++ printk("\n"); |
10658 |
++} |
10659 |
++#endif |
10660 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/fault_64.c linux-2.6.24.4/arch/x86/mm/fault_64.c |
10661 |
+--- linux-2.6.24.4/arch/x86/mm/fault_64.c 2008-03-24 14:49:18.000000000 -0400 |
10662 |
++++ linux-2.6.24.4/arch/x86/mm/fault_64.c 2008-03-26 18:53:27.000000000 -0400 |
10663 |
+@@ -26,6 +26,7 @@ |
10664 |
+ #include <linux/uaccess.h> |
10665 |
+ #include <linux/kdebug.h> |
10666 |
+ #include <linux/kprobes.h> |
10667 |
++#include <linux/binfmts.h> |
10668 |
+ |
10669 |
+ #include <asm/system.h> |
10670 |
+ #include <asm/pgalloc.h> |
10671 |
+@@ -285,6 +286,163 @@ static int vmalloc_fault(unsigned long a |
10672 |
+ return 0; |
10673 |
+ } |
10674 |
+ |
10675 |
++#ifdef CONFIG_PAX_EMUTRAMP |
10676 |
++static int pax_handle_fetch_fault_32(struct pt_regs *regs) |
10677 |
++{ |
10678 |
++ int err; |
10679 |
++ |
10680 |
++ do { /* PaX: gcc trampoline emulation #1 */ |
10681 |
++ unsigned char mov1, mov2; |
10682 |
++ unsigned short jmp; |
10683 |
++ unsigned int addr1, addr2; |
10684 |
++ |
10685 |
++ if ((regs->rip + 11) >> 32) |
10686 |
++ break; |
10687 |
++ |
10688 |
++ err = get_user(mov1, (unsigned char __user *)regs->rip); |
10689 |
++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1)); |
10690 |
++ err |= get_user(mov2, (unsigned char __user *)(regs->rip + 5)); |
10691 |
++ err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6)); |
10692 |
++ err |= get_user(jmp, (unsigned short __user *)(regs->rip + 10)); |
10693 |
++ |
10694 |
++ if (err) |
10695 |
++ break; |
10696 |
++ |
10697 |
++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) { |
10698 |
++ regs->rcx = addr1; |
10699 |
++ regs->rax = addr2; |
10700 |
++ regs->rip = addr2; |
10701 |
++ return 2; |
10702 |
++ } |
10703 |
++ } while (0); |
10704 |
++ |
10705 |
++ do { /* PaX: gcc trampoline emulation #2 */ |
10706 |
++ unsigned char mov, jmp; |
10707 |
++ unsigned int addr1, addr2; |
10708 |
++ |
10709 |
++ if ((regs->rip + 9) >> 32) |
10710 |
++ break; |
10711 |
++ |
10712 |
++ err = get_user(mov, (unsigned char __user *)regs->rip); |
10713 |
++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1)); |
10714 |
++ err |= get_user(jmp, (unsigned char __user *)(regs->rip + 5)); |
10715 |
++ err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6)); |
10716 |
++ |
10717 |
++ if (err) |
10718 |
++ break; |
10719 |
++ |
10720 |
++ if (mov == 0xB9 && jmp == 0xE9) { |
10721 |
++ regs->rcx = addr1; |
10722 |
++ regs->rip = (unsigned int)(regs->rip + addr2 + 10); |
10723 |
++ return 2; |
10724 |
++ } |
10725 |
++ } while (0); |
10726 |
++ |
10727 |
++ return 1; /* PaX in action */ |
10728 |
++} |
10729 |
++ |
10730 |
++static int pax_handle_fetch_fault_64(struct pt_regs *regs) |
10731 |
++{ |
10732 |
++ int err; |
10733 |
++ |
10734 |
++ do { /* PaX: gcc trampoline emulation #1 */ |
10735 |
++ unsigned short mov1, mov2, jmp1; |
10736 |
++ unsigned char jmp2; |
10737 |
++ unsigned int addr1; |
10738 |
++ unsigned long addr2; |
10739 |
++ |
10740 |
++ err = get_user(mov1, (unsigned short __user *)regs->rip); |
10741 |
++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 2)); |
10742 |
++ err |= get_user(mov2, (unsigned short __user *)(regs->rip + 6)); |
10743 |
++ err |= get_user(addr2, (unsigned long __user *)(regs->rip + 8)); |
10744 |
++ err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 16)); |
10745 |
++ err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 18)); |
10746 |
++ |
10747 |
++ if (err) |
10748 |
++ break; |
10749 |
++ |
10750 |
++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) { |
10751 |
++ regs->r11 = addr1; |
10752 |
++ regs->r10 = addr2; |
10753 |
++ regs->rip = addr1; |
10754 |
++ return 2; |
10755 |
++ } |
10756 |
++ } while (0); |
10757 |
++ |
10758 |
++ do { /* PaX: gcc trampoline emulation #2 */ |
10759 |
++ unsigned short mov1, mov2, jmp1; |
10760 |
++ unsigned char jmp2; |
10761 |
++ unsigned long addr1, addr2; |
10762 |
++ |
10763 |
++ err = get_user(mov1, (unsigned short __user *)regs->rip); |
10764 |
++ err |= get_user(addr1, (unsigned long __user *)(regs->rip + 2)); |
10765 |
++ err |= get_user(mov2, (unsigned short __user *)(regs->rip + 10)); |
10766 |
++ err |= get_user(addr2, (unsigned long __user *)(regs->rip + 12)); |
10767 |
++ err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 20)); |
10768 |
++ err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 22)); |
10769 |
++ |
10770 |
++ if (err) |
10771 |
++ break; |
10772 |
++ |
10773 |
++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) { |
10774 |
++ regs->r11 = addr1; |
10775 |
++ regs->r10 = addr2; |
10776 |
++ regs->rip = addr1; |
10777 |
++ return 2; |
10778 |
++ } |
10779 |
++ } while (0); |
10780 |
++ |
10781 |
++ return 1; /* PaX in action */ |
10782 |
++} |
10783 |
++ |
10784 |
++/* |
10785 |
++ * PaX: decide what to do with offenders (regs->rip = fault address) |
10786 |
++ * |
10787 |
++ * returns 1 when task should be killed |
10788 |
++ * 2 when gcc trampoline was detected |
10789 |
++ */ |
10790 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
10791 |
++{ |
10792 |
++ if (regs->eflags & X86_EFLAGS_VM) |
10793 |
++ return 1; |
10794 |
++ |
10795 |
++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) |
10796 |
++ return 1; |
10797 |
++ |
10798 |
++ if (regs->cs == __USER32_CS || (regs->cs & (1<<2))) |
10799 |
++ return pax_handle_fetch_fault_32(regs); |
10800 |
++ else |
10801 |
++ return pax_handle_fetch_fault_64(regs); |
10802 |
++} |
10803 |
++#endif |
10804 |
++ |
10805 |
++#ifdef CONFIG_PAX_PAGEEXEC |
10806 |
++void pax_report_insns(void *pc, void *sp) |
10807 |
++{ |
10808 |
++ long i; |
10809 |
++ |
10810 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
10811 |
++ for (i = 0; i < 20; i++) { |
10812 |
++ unsigned char c; |
10813 |
++ if (get_user(c, (unsigned char __user *)pc+i)) |
10814 |
++ printk("?? "); |
10815 |
++ else |
10816 |
++ printk("%02x ", c); |
10817 |
++ } |
10818 |
++ printk("\n"); |
10819 |
++ |
10820 |
++ printk(KERN_ERR "PAX: bytes at SP-8: "); |
10821 |
++ for (i = -1; i < 10; i++) { |
10822 |
++ unsigned long c; |
10823 |
++ if (get_user(c, (unsigned long __user *)sp+i)) |
10824 |
++ printk("???????????????? "); |
10825 |
++ else |
10826 |
++ printk("%016lx ", c); |
10827 |
++ } |
10828 |
++ printk("\n"); |
10829 |
++} |
10830 |
++#endif |
10831 |
++ |
10832 |
+ int show_unhandled_signals = 1; |
10833 |
+ |
10834 |
+ /* |
10835 |
+@@ -405,7 +563,7 @@ asmlinkage void __kprobes do_page_fault( |
10836 |
+ goto good_area; |
10837 |
+ if (!(vma->vm_flags & VM_GROWSDOWN)) |
10838 |
+ goto bad_area; |
10839 |
+- if (error_code & 4) { |
10840 |
++ if (error_code & PF_USER) { |
10841 |
+ /* Allow userspace just enough access below the stack pointer |
10842 |
+ * to let the 'enter' instruction work. |
10843 |
+ */ |
10844 |
+@@ -421,6 +579,8 @@ asmlinkage void __kprobes do_page_fault( |
10845 |
+ good_area: |
10846 |
+ info.si_code = SEGV_ACCERR; |
10847 |
+ write = 0; |
10848 |
++ if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC)) |
10849 |
++ goto bad_area; |
10850 |
+ switch (error_code & (PF_PROT|PF_WRITE)) { |
10851 |
+ default: /* 3: write, present */ |
10852 |
+ /* fall through */ |
10853 |
+@@ -472,6 +632,21 @@ bad_area_nosemaphore: |
10854 |
+ */ |
10855 |
+ local_irq_enable(); |
10856 |
+ |
10857 |
++#ifdef CONFIG_PAX_PAGEEXEC |
10858 |
++ if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & PF_INSTR)) { |
10859 |
++ |
10860 |
++#ifdef CONFIG_PAX_EMUTRAMP |
10861 |
++ switch (pax_handle_fetch_fault(regs)) { |
10862 |
++ case 2: |
10863 |
++ return; |
10864 |
++ } |
10865 |
++#endif |
10866 |
++ |
10867 |
++ pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp); |
10868 |
++ do_group_exit(SIGKILL); |
10869 |
++ } |
10870 |
++#endif |
10871 |
++ |
10872 |
+ if (is_prefetch(regs, address, error_code)) |
10873 |
+ return; |
10874 |
+ |
10875 |
+@@ -489,8 +664,8 @@ bad_area_nosemaphore: |
10876 |
+ printk_ratelimit()) { |
10877 |
+ printk( |
10878 |
+ "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n", |
10879 |
+- tsk->pid > 1 ? KERN_INFO : KERN_EMERG, |
10880 |
+- tsk->comm, tsk->pid, address, regs->rip, |
10881 |
++ task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, |
10882 |
++ tsk->comm, task_pid_nr(tsk), address, regs->rip, |
10883 |
+ regs->rsp, error_code); |
10884 |
+ } |
10885 |
+ |
10886 |
+@@ -534,6 +709,9 @@ no_context: |
10887 |
+ |
10888 |
+ if (address < PAGE_SIZE) |
10889 |
+ printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); |
10890 |
++ else if (error_code & PF_INSTR) |
10891 |
++ printk(KERN_ALERT "PAX: %s:%d, uid/euid: %u/%u, invalid execution attempt", |
10892 |
++ tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid); |
10893 |
+ else |
10894 |
+ printk(KERN_ALERT "Unable to handle kernel paging request"); |
10895 |
+ printk(" at %016lx RIP: \n" KERN_ALERT,address); |
10896 |
+@@ -546,7 +724,7 @@ no_context: |
10897 |
+ /* Executive summary in case the body of the oops scrolled away */ |
10898 |
+ printk(KERN_EMERG "CR2: %016lx\n", address); |
10899 |
+ oops_end(flags); |
10900 |
+- do_exit(SIGKILL); |
10901 |
++ do_group_exit(SIGKILL); |
10902 |
+ |
10903 |
+ /* |
10904 |
+ * We ran out of memory, or some other thing happened to us that made |
10905 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/highmem_32.c linux-2.6.24.4/arch/x86/mm/highmem_32.c |
10906 |
+--- linux-2.6.24.4/arch/x86/mm/highmem_32.c 2008-03-24 14:49:18.000000000 -0400 |
10907 |
++++ linux-2.6.24.4/arch/x86/mm/highmem_32.c 2008-03-26 17:56:55.000000000 -0400 |
10908 |
+@@ -31,6 +31,10 @@ void *kmap_atomic_prot(struct page *page |
10909 |
+ enum fixed_addresses idx; |
10910 |
+ unsigned long vaddr; |
10911 |
+ |
10912 |
++#ifdef CONFIG_PAX_KERNEXEC |
10913 |
++ unsigned long cr0; |
10914 |
++#endif |
10915 |
++ |
10916 |
+ /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ |
10917 |
+ pagefault_disable(); |
10918 |
+ |
10919 |
+@@ -40,7 +44,17 @@ void *kmap_atomic_prot(struct page *page |
10920 |
+ idx = type + KM_TYPE_NR*smp_processor_id(); |
10921 |
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
10922 |
+ BUG_ON(!pte_none(*(kmap_pte-idx))); |
10923 |
++ |
10924 |
++#ifdef CONFIG_PAX_KERNEXEC |
10925 |
++ pax_open_kernel(cr0); |
10926 |
++#endif |
10927 |
++ |
10928 |
+ set_pte(kmap_pte-idx, mk_pte(page, prot)); |
10929 |
++ |
10930 |
++#ifdef CONFIG_PAX_KERNEXEC |
10931 |
++ pax_close_kernel(cr0); |
10932 |
++#endif |
10933 |
++ |
10934 |
+ arch_flush_lazy_mmu_mode(); |
10935 |
+ |
10936 |
+ return (void *)vaddr; |
10937 |
+@@ -56,15 +70,29 @@ void kunmap_atomic(void *kvaddr, enum km |
10938 |
+ unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
10939 |
+ enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); |
10940 |
+ |
10941 |
++#ifdef CONFIG_PAX_KERNEXEC |
10942 |
++ unsigned long cr0; |
10943 |
++#endif |
10944 |
++ |
10945 |
+ /* |
10946 |
+ * Force other mappings to Oops if they'll try to access this pte |
10947 |
+ * without first remap it. Keeping stale mappings around is a bad idea |
10948 |
+ * also, in case the page changes cacheability attributes or becomes |
10949 |
+ * a protected page in a hypervisor. |
10950 |
+ */ |
10951 |
+- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) |
10952 |
++ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) { |
10953 |
++ |
10954 |
++#ifdef CONFIG_PAX_KERNEXEC |
10955 |
++ pax_open_kernel(cr0); |
10956 |
++#endif |
10957 |
++ |
10958 |
+ kpte_clear_flush(kmap_pte-idx, vaddr); |
10959 |
+- else { |
10960 |
++ |
10961 |
++#ifdef CONFIG_PAX_KERNEXEC |
10962 |
++ pax_close_kernel(cr0); |
10963 |
++#endif |
10964 |
++ |
10965 |
++ } else { |
10966 |
+ #ifdef CONFIG_DEBUG_HIGHMEM |
10967 |
+ BUG_ON(vaddr < PAGE_OFFSET); |
10968 |
+ BUG_ON(vaddr >= (unsigned long)high_memory); |
10969 |
+@@ -83,11 +111,25 @@ void *kmap_atomic_pfn(unsigned long pfn, |
10970 |
+ enum fixed_addresses idx; |
10971 |
+ unsigned long vaddr; |
10972 |
+ |
10973 |
++#ifdef CONFIG_PAX_KERNEXEC |
10974 |
++ unsigned long cr0; |
10975 |
++#endif |
10976 |
++ |
10977 |
+ pagefault_disable(); |
10978 |
+ |
10979 |
+ idx = type + KM_TYPE_NR*smp_processor_id(); |
10980 |
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
10981 |
++ |
10982 |
++#ifdef CONFIG_PAX_KERNEXEC |
10983 |
++ pax_open_kernel(cr0); |
10984 |
++#endif |
10985 |
++ |
10986 |
+ set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); |
10987 |
++ |
10988 |
++#ifdef CONFIG_PAX_KERNEXEC |
10989 |
++ pax_close_kernel(cr0); |
10990 |
++#endif |
10991 |
++ |
10992 |
+ arch_flush_lazy_mmu_mode(); |
10993 |
+ |
10994 |
+ return (void*) vaddr; |
10995 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/hugetlbpage.c linux-2.6.24.4/arch/x86/mm/hugetlbpage.c |
10996 |
+--- linux-2.6.24.4/arch/x86/mm/hugetlbpage.c 2008-03-24 14:49:18.000000000 -0400 |
10997 |
++++ linux-2.6.24.4/arch/x86/mm/hugetlbpage.c 2008-03-26 17:56:55.000000000 -0400 |
10998 |
+@@ -229,13 +229,18 @@ static unsigned long hugetlb_get_unmappe |
10999 |
+ { |
11000 |
+ struct mm_struct *mm = current->mm; |
11001 |
+ struct vm_area_struct *vma; |
11002 |
+- unsigned long start_addr; |
11003 |
++ unsigned long start_addr, task_size = TASK_SIZE; |
11004 |
++ |
11005 |
++#ifdef CONFIG_PAX_SEGMEXEC |
11006 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
11007 |
++ task_size = SEGMEXEC_TASK_SIZE; |
11008 |
++#endif |
11009 |
+ |
11010 |
+ if (len > mm->cached_hole_size) { |
11011 |
+- start_addr = mm->free_area_cache; |
11012 |
++ start_addr = mm->free_area_cache; |
11013 |
+ } else { |
11014 |
+- start_addr = TASK_UNMAPPED_BASE; |
11015 |
+- mm->cached_hole_size = 0; |
11016 |
++ start_addr = mm->mmap_base; |
11017 |
++ mm->cached_hole_size = 0; |
11018 |
+ } |
11019 |
+ |
11020 |
+ full_search: |
11021 |
+@@ -243,13 +248,13 @@ full_search: |
11022 |
+ |
11023 |
+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { |
11024 |
+ /* At this point: (!vma || addr < vma->vm_end). */ |
11025 |
+- if (TASK_SIZE - len < addr) { |
11026 |
++ if (task_size - len < addr) { |
11027 |
+ /* |
11028 |
+ * Start a new search - just in case we missed |
11029 |
+ * some holes. |
11030 |
+ */ |
11031 |
+- if (start_addr != TASK_UNMAPPED_BASE) { |
11032 |
+- start_addr = TASK_UNMAPPED_BASE; |
11033 |
++ if (start_addr != mm->mmap_base) { |
11034 |
++ start_addr = mm->mmap_base; |
11035 |
+ mm->cached_hole_size = 0; |
11036 |
+ goto full_search; |
11037 |
+ } |
11038 |
+@@ -271,9 +276,8 @@ static unsigned long hugetlb_get_unmappe |
11039 |
+ { |
11040 |
+ struct mm_struct *mm = current->mm; |
11041 |
+ struct vm_area_struct *vma, *prev_vma; |
11042 |
+- unsigned long base = mm->mmap_base, addr = addr0; |
11043 |
++ unsigned long base = mm->mmap_base, addr; |
11044 |
+ unsigned long largest_hole = mm->cached_hole_size; |
11045 |
+- int first_time = 1; |
11046 |
+ |
11047 |
+ /* don't allow allocations above current base */ |
11048 |
+ if (mm->free_area_cache > base) |
11049 |
+@@ -283,7 +287,7 @@ static unsigned long hugetlb_get_unmappe |
11050 |
+ largest_hole = 0; |
11051 |
+ mm->free_area_cache = base; |
11052 |
+ } |
11053 |
+-try_again: |
11054 |
++ |
11055 |
+ /* make sure it can fit in the remaining address space */ |
11056 |
+ if (mm->free_area_cache < len) |
11057 |
+ goto fail; |
11058 |
+@@ -325,22 +329,26 @@ try_again: |
11059 |
+ |
11060 |
+ fail: |
11061 |
+ /* |
11062 |
+- * if hint left us with no space for the requested |
11063 |
+- * mapping then try again: |
11064 |
+- */ |
11065 |
+- if (first_time) { |
11066 |
+- mm->free_area_cache = base; |
11067 |
+- largest_hole = 0; |
11068 |
+- first_time = 0; |
11069 |
+- goto try_again; |
11070 |
+- } |
11071 |
+- /* |
11072 |
+ * A failed mmap() very likely causes application failure, |
11073 |
+ * so fall back to the bottom-up function here. This scenario |
11074 |
+ * can happen with large stack limits and large mmap() |
11075 |
+ * allocations. |
11076 |
+ */ |
11077 |
+- mm->free_area_cache = TASK_UNMAPPED_BASE; |
11078 |
++ |
11079 |
++#ifdef CONFIG_PAX_SEGMEXEC |
11080 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
11081 |
++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE; |
11082 |
++ else |
11083 |
++#endif |
11084 |
++ |
11085 |
++ mm->mmap_base = TASK_UNMAPPED_BASE; |
11086 |
++ |
11087 |
++#ifdef CONFIG_PAX_RANDMMAP |
11088 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
11089 |
++ mm->mmap_base += mm->delta_mmap; |
11090 |
++#endif |
11091 |
++ |
11092 |
++ mm->free_area_cache = mm->mmap_base; |
11093 |
+ mm->cached_hole_size = ~0UL; |
11094 |
+ addr = hugetlb_get_unmapped_area_bottomup(file, addr0, |
11095 |
+ len, pgoff, flags); |
11096 |
+@@ -348,6 +356,7 @@ fail: |
11097 |
+ /* |
11098 |
+ * Restore the topdown base: |
11099 |
+ */ |
11100 |
++ mm->mmap_base = base; |
11101 |
+ mm->free_area_cache = base; |
11102 |
+ mm->cached_hole_size = ~0UL; |
11103 |
+ |
11104 |
+@@ -360,10 +369,17 @@ hugetlb_get_unmapped_area(struct file *f |
11105 |
+ { |
11106 |
+ struct mm_struct *mm = current->mm; |
11107 |
+ struct vm_area_struct *vma; |
11108 |
++ unsigned long task_size = TASK_SIZE; |
11109 |
+ |
11110 |
+ if (len & ~HPAGE_MASK) |
11111 |
+ return -EINVAL; |
11112 |
+- if (len > TASK_SIZE) |
11113 |
++ |
11114 |
++#ifdef CONFIG_PAX_SEGMEXEC |
11115 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
11116 |
++ task_size = SEGMEXEC_TASK_SIZE; |
11117 |
++#endif |
11118 |
++ |
11119 |
++ if (len > task_size) |
11120 |
+ return -ENOMEM; |
11121 |
+ |
11122 |
+ if (flags & MAP_FIXED) { |
11123 |
+@@ -375,7 +391,7 @@ hugetlb_get_unmapped_area(struct file *f |
11124 |
+ if (addr) { |
11125 |
+ addr = ALIGN(addr, HPAGE_SIZE); |
11126 |
+ vma = find_vma(mm, addr); |
11127 |
+- if (TASK_SIZE - len >= addr && |
11128 |
++ if (task_size - len >= addr && |
11129 |
+ (!vma || addr + len <= vma->vm_start)) |
11130 |
+ return addr; |
11131 |
+ } |
11132 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/init_32.c linux-2.6.24.4/arch/x86/mm/init_32.c |
11133 |
+--- linux-2.6.24.4/arch/x86/mm/init_32.c 2008-03-24 14:49:18.000000000 -0400 |
11134 |
++++ linux-2.6.24.4/arch/x86/mm/init_32.c 2008-03-26 17:56:55.000000000 -0400 |
11135 |
+@@ -44,6 +44,7 @@ |
11136 |
+ #include <asm/tlbflush.h> |
11137 |
+ #include <asm/sections.h> |
11138 |
+ #include <asm/paravirt.h> |
11139 |
++#include <asm/desc.h> |
11140 |
+ |
11141 |
+ unsigned int __VMALLOC_RESERVE = 128 << 20; |
11142 |
+ |
11143 |
+@@ -53,32 +54,6 @@ unsigned long highstart_pfn, highend_pfn |
11144 |
+ static int noinline do_test_wp_bit(void); |
11145 |
+ |
11146 |
+ /* |
11147 |
+- * Creates a middle page table and puts a pointer to it in the |
11148 |
+- * given global directory entry. This only returns the gd entry |
11149 |
+- * in non-PAE compilation mode, since the middle layer is folded. |
11150 |
+- */ |
11151 |
+-static pmd_t * __init one_md_table_init(pgd_t *pgd) |
11152 |
+-{ |
11153 |
+- pud_t *pud; |
11154 |
+- pmd_t *pmd_table; |
11155 |
+- |
11156 |
+-#ifdef CONFIG_X86_PAE |
11157 |
+- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) { |
11158 |
+- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); |
11159 |
+- |
11160 |
+- paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT); |
11161 |
+- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); |
11162 |
+- pud = pud_offset(pgd, 0); |
11163 |
+- if (pmd_table != pmd_offset(pud, 0)) |
11164 |
+- BUG(); |
11165 |
+- } |
11166 |
+-#endif |
11167 |
+- pud = pud_offset(pgd, 0); |
11168 |
+- pmd_table = pmd_offset(pud, 0); |
11169 |
+- return pmd_table; |
11170 |
+-} |
11171 |
+- |
11172 |
+-/* |
11173 |
+ * Create a page table and place a pointer to it in a middle page |
11174 |
+ * directory entry. |
11175 |
+ */ |
11176 |
+@@ -95,7 +70,11 @@ static pte_t * __init one_page_table_ini |
11177 |
+ (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE); |
11178 |
+ |
11179 |
+ paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT); |
11180 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
11181 |
++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE)); |
11182 |
++#else |
11183 |
+ set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE)); |
11184 |
++#endif |
11185 |
+ BUG_ON(page_table != pte_offset_kernel(pmd, 0)); |
11186 |
+ } |
11187 |
+ |
11188 |
+@@ -116,6 +95,7 @@ static pte_t * __init one_page_table_ini |
11189 |
+ static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base) |
11190 |
+ { |
11191 |
+ pgd_t *pgd; |
11192 |
++ pud_t *pud; |
11193 |
+ pmd_t *pmd; |
11194 |
+ int pgd_idx, pmd_idx; |
11195 |
+ unsigned long vaddr; |
11196 |
+@@ -126,8 +106,13 @@ static void __init page_table_range_init |
11197 |
+ pgd = pgd_base + pgd_idx; |
11198 |
+ |
11199 |
+ for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) { |
11200 |
+- pmd = one_md_table_init(pgd); |
11201 |
+- pmd = pmd + pmd_index(vaddr); |
11202 |
++ pud = pud_offset(pgd, vaddr); |
11203 |
++ pmd = pmd_offset(pud, vaddr); |
11204 |
++ |
11205 |
++#ifdef CONFIG_X86_PAE |
11206 |
++ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT); |
11207 |
++#endif |
11208 |
++ |
11209 |
+ for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) { |
11210 |
+ one_page_table_init(pmd); |
11211 |
+ |
11212 |
+@@ -137,11 +122,23 @@ static void __init page_table_range_init |
11213 |
+ } |
11214 |
+ } |
11215 |
+ |
11216 |
+-static inline int is_kernel_text(unsigned long addr) |
11217 |
++static inline int is_kernel_text(unsigned long start, unsigned long end) |
11218 |
+ { |
11219 |
+- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end) |
11220 |
+- return 1; |
11221 |
+- return 0; |
11222 |
++ unsigned long etext; |
11223 |
++ |
11224 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
11225 |
++ etext = ktva_ktla((unsigned long)&MODULES_END); |
11226 |
++#else |
11227 |
++ etext = (unsigned long)&_etext; |
11228 |
++#endif |
11229 |
++ |
11230 |
++ if ((start > ktla_ktva(etext) || |
11231 |
++ end <= ktla_ktva((unsigned long)_stext)) && |
11232 |
++ (start > ktla_ktva((unsigned long)_einittext) || |
11233 |
++ end <= ktla_ktva((unsigned long)_sinittext)) && |
11234 |
++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000))) |
11235 |
++ return 0; |
11236 |
++ return 1; |
11237 |
+ } |
11238 |
+ |
11239 |
+ /* |
11240 |
+@@ -153,25 +150,29 @@ static void __init kernel_physical_mappi |
11241 |
+ { |
11242 |
+ unsigned long pfn; |
11243 |
+ pgd_t *pgd; |
11244 |
++ pud_t *pud; |
11245 |
+ pmd_t *pmd; |
11246 |
+ pte_t *pte; |
11247 |
+- int pgd_idx, pmd_idx, pte_ofs; |
11248 |
++ unsigned int pgd_idx, pmd_idx, pte_ofs; |
11249 |
+ |
11250 |
+ pgd_idx = pgd_index(PAGE_OFFSET); |
11251 |
+ pgd = pgd_base + pgd_idx; |
11252 |
+ pfn = 0; |
11253 |
+ |
11254 |
+- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) { |
11255 |
+- pmd = one_md_table_init(pgd); |
11256 |
+- if (pfn >= max_low_pfn) |
11257 |
+- continue; |
11258 |
++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) { |
11259 |
++ pud = pud_offset(pgd, 0); |
11260 |
++ pmd = pmd_offset(pud, 0); |
11261 |
++ |
11262 |
++#ifdef CONFIG_X86_PAE |
11263 |
++ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT); |
11264 |
++#endif |
11265 |
++ |
11266 |
+ for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) { |
11267 |
+- unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET; |
11268 |
++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET; |
11269 |
+ |
11270 |
+ /* Map with big pages if possible, otherwise create normal page tables. */ |
11271 |
+- if (cpu_has_pse) { |
11272 |
+- unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1; |
11273 |
+- if (is_kernel_text(address) || is_kernel_text(address2)) |
11274 |
++ if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) { |
11275 |
++ if (is_kernel_text(address, address + PMD_SIZE)) |
11276 |
+ set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC)); |
11277 |
+ else |
11278 |
+ set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE)); |
11279 |
+@@ -183,7 +184,7 @@ static void __init kernel_physical_mappi |
11280 |
+ for (pte_ofs = 0; |
11281 |
+ pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; |
11282 |
+ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) { |
11283 |
+- if (is_kernel_text(address)) |
11284 |
++ if (is_kernel_text(address, address + PAGE_SIZE)) |
11285 |
+ set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); |
11286 |
+ else |
11287 |
+ set_pte(pte, pfn_pte(pfn, PAGE_KERNEL)); |
11288 |
+@@ -338,9 +339,9 @@ static void __init set_highmem_pages_ini |
11289 |
+ #define set_highmem_pages_init(bad_ppro) do { } while (0) |
11290 |
+ #endif /* CONFIG_HIGHMEM */ |
11291 |
+ |
11292 |
+-unsigned long long __PAGE_KERNEL = _PAGE_KERNEL; |
11293 |
++unsigned long long __PAGE_KERNEL __read_only = _PAGE_KERNEL; |
11294 |
+ EXPORT_SYMBOL(__PAGE_KERNEL); |
11295 |
+-unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC; |
11296 |
++unsigned long long __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC; |
11297 |
+ |
11298 |
+ #ifdef CONFIG_NUMA |
11299 |
+ extern void __init remap_numa_kva(void); |
11300 |
+@@ -351,26 +352,10 @@ extern void __init remap_numa_kva(void); |
11301 |
+ void __init native_pagetable_setup_start(pgd_t *base) |
11302 |
+ { |
11303 |
+ #ifdef CONFIG_X86_PAE |
11304 |
+- int i; |
11305 |
+- |
11306 |
+- /* |
11307 |
+- * Init entries of the first-level page table to the |
11308 |
+- * zero page, if they haven't already been set up. |
11309 |
+- * |
11310 |
+- * In a normal native boot, we'll be running on a |
11311 |
+- * pagetable rooted in swapper_pg_dir, but not in PAE |
11312 |
+- * mode, so this will end up clobbering the mappings |
11313 |
+- * for the lower 24Mbytes of the address space, |
11314 |
+- * without affecting the kernel address space. |
11315 |
+- */ |
11316 |
+- for (i = 0; i < USER_PTRS_PER_PGD; i++) |
11317 |
+- set_pgd(&base[i], |
11318 |
+- __pgd(__pa(empty_zero_page) | _PAGE_PRESENT)); |
11319 |
++ unsigned int i; |
11320 |
+ |
11321 |
+- /* Make sure kernel address space is empty so that a pagetable |
11322 |
+- will be allocated for it. */ |
11323 |
+- memset(&base[USER_PTRS_PER_PGD], 0, |
11324 |
+- KERNEL_PGD_PTRS * sizeof(pgd_t)); |
11325 |
++ for (i = 0; i < PTRS_PER_PGD; i++) |
11326 |
++ paravirt_alloc_pd(__pa(swapper_pm_dir + i) >> PAGE_SHIFT); |
11327 |
+ #else |
11328 |
+ paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT); |
11329 |
+ #endif |
11330 |
+@@ -378,16 +363,6 @@ void __init native_pagetable_setup_start |
11331 |
+ |
11332 |
+ void __init native_pagetable_setup_done(pgd_t *base) |
11333 |
+ { |
11334 |
+-#ifdef CONFIG_X86_PAE |
11335 |
+- /* |
11336 |
+- * Add low memory identity-mappings - SMP needs it when |
11337 |
+- * starting up on an AP from real-mode. In the non-PAE |
11338 |
+- * case we already have these mappings through head.S. |
11339 |
+- * All user-space mappings are explicitly cleared after |
11340 |
+- * SMP startup. |
11341 |
+- */ |
11342 |
+- set_pgd(&base[0], base[USER_PTRS_PER_PGD]); |
11343 |
+-#endif |
11344 |
+ } |
11345 |
+ |
11346 |
+ /* |
11347 |
+@@ -449,12 +424,12 @@ static void __init pagetable_init (void) |
11348 |
+ * Swap suspend & friends need this for resume because things like the intel-agp |
11349 |
+ * driver might have split up a kernel 4MB mapping. |
11350 |
+ */ |
11351 |
+-char __nosavedata swsusp_pg_dir[PAGE_SIZE] |
11352 |
++pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD] |
11353 |
+ __attribute__ ((aligned (PAGE_SIZE))); |
11354 |
+ |
11355 |
+ static inline void save_pg_dir(void) |
11356 |
+ { |
11357 |
+- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE); |
11358 |
++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD); |
11359 |
+ } |
11360 |
+ #else |
11361 |
+ static inline void save_pg_dir(void) |
11362 |
+@@ -483,12 +458,11 @@ void zap_low_mappings (void) |
11363 |
+ flush_tlb_all(); |
11364 |
+ } |
11365 |
+ |
11366 |
+-int nx_enabled = 0; |
11367 |
++int nx_enabled; |
11368 |
+ |
11369 |
+ #ifdef CONFIG_X86_PAE |
11370 |
+ |
11371 |
+-static int disable_nx __initdata = 0; |
11372 |
+-u64 __supported_pte_mask __read_mostly = ~_PAGE_NX; |
11373 |
++u64 __supported_pte_mask __read_only = ~_PAGE_NX; |
11374 |
+ EXPORT_SYMBOL_GPL(__supported_pte_mask); |
11375 |
+ |
11376 |
+ /* |
11377 |
+@@ -499,36 +473,31 @@ EXPORT_SYMBOL_GPL(__supported_pte_mask); |
11378 |
+ * on Enable |
11379 |
+ * off Disable |
11380 |
+ */ |
11381 |
++#if !defined(CONFIG_PAX_PAGEEXEC) |
11382 |
+ static int __init noexec_setup(char *str) |
11383 |
+ { |
11384 |
+ if (!str || !strcmp(str, "on")) { |
11385 |
+- if (cpu_has_nx) { |
11386 |
+- __supported_pte_mask |= _PAGE_NX; |
11387 |
+- disable_nx = 0; |
11388 |
+- } |
11389 |
++ if (cpu_has_nx) |
11390 |
++ nx_enabled = 1; |
11391 |
+ } else if (!strcmp(str,"off")) { |
11392 |
+- disable_nx = 1; |
11393 |
+- __supported_pte_mask &= ~_PAGE_NX; |
11394 |
++ nx_enabled = 0; |
11395 |
+ } else |
11396 |
+ return -EINVAL; |
11397 |
+ |
11398 |
+ return 0; |
11399 |
+ } |
11400 |
+ early_param("noexec", noexec_setup); |
11401 |
++#endif |
11402 |
+ |
11403 |
+ static void __init set_nx(void) |
11404 |
+ { |
11405 |
+- unsigned int v[4], l, h; |
11406 |
++ if (!nx_enabled && cpu_has_nx) { |
11407 |
++ unsigned l, h; |
11408 |
+ |
11409 |
+- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) { |
11410 |
+- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]); |
11411 |
+- if ((v[3] & (1 << 20)) && !disable_nx) { |
11412 |
+- rdmsr(MSR_EFER, l, h); |
11413 |
+- l |= EFER_NX; |
11414 |
+- wrmsr(MSR_EFER, l, h); |
11415 |
+- nx_enabled = 1; |
11416 |
+- __supported_pte_mask |= _PAGE_NX; |
11417 |
+- } |
11418 |
++ __supported_pte_mask &= ~_PAGE_NX; |
11419 |
++ rdmsr(MSR_EFER, l, h); |
11420 |
++ l &= ~EFER_NX; |
11421 |
++ wrmsr(MSR_EFER, l, h); |
11422 |
+ } |
11423 |
+ } |
11424 |
+ |
11425 |
+@@ -581,14 +550,6 @@ void __init paging_init(void) |
11426 |
+ |
11427 |
+ load_cr3(swapper_pg_dir); |
11428 |
+ |
11429 |
+-#ifdef CONFIG_X86_PAE |
11430 |
+- /* |
11431 |
+- * We will bail out later - printk doesn't work right now so |
11432 |
+- * the user would just see a hanging kernel. |
11433 |
+- */ |
11434 |
+- if (cpu_has_pae) |
11435 |
+- set_in_cr4(X86_CR4_PAE); |
11436 |
+-#endif |
11437 |
+ __flush_tlb_all(); |
11438 |
+ |
11439 |
+ kmap_init(); |
11440 |
+@@ -659,7 +620,7 @@ void __init mem_init(void) |
11441 |
+ set_highmem_pages_init(bad_ppro); |
11442 |
+ |
11443 |
+ codesize = (unsigned long) &_etext - (unsigned long) &_text; |
11444 |
+- datasize = (unsigned long) &_edata - (unsigned long) &_etext; |
11445 |
++ datasize = (unsigned long) &_edata - (unsigned long) &_data; |
11446 |
+ initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; |
11447 |
+ |
11448 |
+ kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); |
11449 |
+@@ -704,10 +665,10 @@ void __init mem_init(void) |
11450 |
+ (unsigned long)&__init_begin, (unsigned long)&__init_end, |
11451 |
+ ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10, |
11452 |
+ |
11453 |
+- (unsigned long)&_etext, (unsigned long)&_edata, |
11454 |
+- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10, |
11455 |
++ (unsigned long)&_data, (unsigned long)&_edata, |
11456 |
++ ((unsigned long)&_edata - (unsigned long)&_data) >> 10, |
11457 |
+ |
11458 |
+- (unsigned long)&_text, (unsigned long)&_etext, |
11459 |
++ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext), |
11460 |
+ ((unsigned long)&_etext - (unsigned long)&_text) >> 10); |
11461 |
+ |
11462 |
+ #ifdef CONFIG_HIGHMEM |
11463 |
+@@ -718,10 +679,6 @@ void __init mem_init(void) |
11464 |
+ BUG_ON((unsigned long)high_memory > VMALLOC_START); |
11465 |
+ #endif /* double-sanity-check paranoia */ |
11466 |
+ |
11467 |
+-#ifdef CONFIG_X86_PAE |
11468 |
+- if (!cpu_has_pae) |
11469 |
+- panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!"); |
11470 |
+-#endif |
11471 |
+ if (boot_cpu_data.wp_works_ok < 0) |
11472 |
+ test_wp_bit(); |
11473 |
+ |
11474 |
+@@ -839,6 +796,46 @@ void free_init_pages(char *what, unsigne |
11475 |
+ |
11476 |
+ void free_initmem(void) |
11477 |
+ { |
11478 |
++ |
11479 |
++#ifdef CONFIG_PAX_KERNEXEC |
11480 |
++ /* PaX: limit KERNEL_CS to actual size */ |
11481 |
++ unsigned long addr, limit; |
11482 |
++ __u32 a, b; |
11483 |
++ int cpu; |
11484 |
++ pgd_t *pgd; |
11485 |
++ pud_t *pud; |
11486 |
++ pmd_t *pmd; |
11487 |
++ |
11488 |
++#ifdef CONFIG_MODULES |
11489 |
++ limit = ktva_ktla((unsigned long)&MODULES_END); |
11490 |
++#else |
11491 |
++ limit = (unsigned long)&_etext; |
11492 |
++#endif |
11493 |
++ limit = (limit - 1UL) >> PAGE_SHIFT; |
11494 |
++ |
11495 |
++ for (cpu = 0; cpu < NR_CPUS; cpu++) { |
11496 |
++ pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC); |
11497 |
++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b); |
11498 |
++ } |
11499 |
++ |
11500 |
++ /* PaX: make KERNEL_CS read-only */ |
11501 |
++ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) { |
11502 |
++ pgd = pgd_offset_k(addr); |
11503 |
++ pud = pud_offset(pgd, addr); |
11504 |
++ pmd = pmd_offset(pud, addr); |
11505 |
++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW)); |
11506 |
++ } |
11507 |
++#ifdef CONFIG_X86_PAE |
11508 |
++ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) { |
11509 |
++ pgd = pgd_offset_k(addr); |
11510 |
++ pud = pud_offset(pgd, addr); |
11511 |
++ pmd = pmd_offset(pud, addr); |
11512 |
++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask))); |
11513 |
++ } |
11514 |
++#endif |
11515 |
++ flush_tlb_all(); |
11516 |
++#endif |
11517 |
++ |
11518 |
+ free_init_pages("unused kernel memory", |
11519 |
+ (unsigned long)(&__init_begin), |
11520 |
+ (unsigned long)(&__init_end)); |
11521 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/init_64.c linux-2.6.24.4/arch/x86/mm/init_64.c |
11522 |
+--- linux-2.6.24.4/arch/x86/mm/init_64.c 2008-03-24 14:49:18.000000000 -0400 |
11523 |
++++ linux-2.6.24.4/arch/x86/mm/init_64.c 2008-03-26 17:56:55.000000000 -0400 |
11524 |
+@@ -45,7 +45,7 @@ |
11525 |
+ #include <asm/sections.h> |
11526 |
+ |
11527 |
+ #ifndef Dprintk |
11528 |
+-#define Dprintk(x...) |
11529 |
++#define Dprintk(x...) do {} while (0) |
11530 |
+ #endif |
11531 |
+ |
11532 |
+ const struct dma_mapping_ops* dma_ops; |
11533 |
+@@ -121,6 +121,10 @@ static __init void set_pte_phys(unsigned |
11534 |
+ pmd_t *pmd; |
11535 |
+ pte_t *pte, new_pte; |
11536 |
+ |
11537 |
++#ifdef CONFIG_PAX_KERNEXEC |
11538 |
++ unsigned long cr0; |
11539 |
++#endif |
11540 |
++ |
11541 |
+ Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys); |
11542 |
+ |
11543 |
+ pgd = pgd_offset_k(vaddr); |
11544 |
+@@ -131,7 +135,7 @@ static __init void set_pte_phys(unsigned |
11545 |
+ pud = pud_offset(pgd, vaddr); |
11546 |
+ if (pud_none(*pud)) { |
11547 |
+ pmd = (pmd_t *) spp_getpage(); |
11548 |
+- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER)); |
11549 |
++ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE)); |
11550 |
+ if (pmd != pmd_offset(pud, 0)) { |
11551 |
+ printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0)); |
11552 |
+ return; |
11553 |
+@@ -140,7 +144,7 @@ static __init void set_pte_phys(unsigned |
11554 |
+ pmd = pmd_offset(pud, vaddr); |
11555 |
+ if (pmd_none(*pmd)) { |
11556 |
+ pte = (pte_t *) spp_getpage(); |
11557 |
+- set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); |
11558 |
++ set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE)); |
11559 |
+ if (pte != pte_offset_kernel(pmd, 0)) { |
11560 |
+ printk("PAGETABLE BUG #02!\n"); |
11561 |
+ return; |
11562 |
+@@ -152,8 +156,17 @@ static __init void set_pte_phys(unsigned |
11563 |
+ if (!pte_none(*pte) && |
11564 |
+ pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask)) |
11565 |
+ pte_ERROR(*pte); |
11566 |
++ |
11567 |
++#ifdef CONFIG_PAX_KERNEXEC |
11568 |
++ pax_open_kernel(cr0); |
11569 |
++#endif |
11570 |
++ |
11571 |
+ set_pte(pte, new_pte); |
11572 |
+ |
11573 |
++#ifdef CONFIG_PAX_KERNEXEC |
11574 |
++ pax_close_kernel(cr0); |
11575 |
++#endif |
11576 |
++ |
11577 |
+ /* |
11578 |
+ * It's enough to flush this one mapping. |
11579 |
+ * (PGE mappings get flushed as well) |
11580 |
+@@ -225,7 +238,7 @@ __meminit void *early_ioremap(unsigned l |
11581 |
+ addr &= PMD_MASK; |
11582 |
+ for (i = 0; i < pmds; i++, addr += PMD_SIZE) |
11583 |
+ set_pmd(pmd + i,__pmd(addr | _KERNPG_TABLE | _PAGE_PSE)); |
11584 |
+- __flush_tlb(); |
11585 |
++ __flush_tlb_all(); |
11586 |
+ return (void *)vaddr; |
11587 |
+ next: |
11588 |
+ ; |
11589 |
+@@ -246,7 +259,7 @@ __meminit void early_iounmap(void *addr, |
11590 |
+ pmd = level2_kernel_pgt + pmd_index(vaddr); |
11591 |
+ for (i = 0; i < pmds; i++) |
11592 |
+ pmd_clear(pmd + i); |
11593 |
+- __flush_tlb(); |
11594 |
++ __flush_tlb_all(); |
11595 |
+ } |
11596 |
+ |
11597 |
+ static void __meminit |
11598 |
+@@ -314,7 +327,7 @@ static void __meminit phys_pud_init(pud_ |
11599 |
+ spin_unlock(&init_mm.page_table_lock); |
11600 |
+ unmap_low_page(pmd); |
11601 |
+ } |
11602 |
+- __flush_tlb(); |
11603 |
++ __flush_tlb_all(); |
11604 |
+ } |
11605 |
+ |
11606 |
+ static void __init find_early_table_space(unsigned long end) |
11607 |
+@@ -583,6 +596,39 @@ void free_init_pages(char *what, unsigne |
11608 |
+ |
11609 |
+ void free_initmem(void) |
11610 |
+ { |
11611 |
++ |
11612 |
++#ifdef CONFIG_PAX_KERNEXEC |
11613 |
++ unsigned long addr, end; |
11614 |
++ pgd_t *pgd; |
11615 |
++ pud_t *pud; |
11616 |
++ pmd_t *pmd; |
11617 |
++ |
11618 |
++ /* PaX: make kernel code/rodata read-only, rest non-executable */ |
11619 |
++ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_TEXT_SIZE; addr += PMD_SIZE) { |
11620 |
++ pgd = pgd_offset_k(addr); |
11621 |
++ pud = pud_offset(pgd, addr); |
11622 |
++ pmd = pmd_offset(pud, addr); |
11623 |
++ if ((unsigned long)_text <= addr && addr < (unsigned long)_data) |
11624 |
++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW)); |
11625 |
++ else |
11626 |
++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask))); |
11627 |
++ } |
11628 |
++ |
11629 |
++ addr = (unsigned long)__va(__pa(__START_KERNEL_map)); |
11630 |
++ end = addr + KERNEL_TEXT_SIZE; |
11631 |
++ for (; addr < end; addr += PMD_SIZE) { |
11632 |
++ pgd = pgd_offset_k(addr); |
11633 |
++ pud = pud_offset(pgd, addr); |
11634 |
++ pmd = pmd_offset(pud, addr); |
11635 |
++ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data))) |
11636 |
++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW)); |
11637 |
++ else |
11638 |
++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask))); |
11639 |
++ } |
11640 |
++ |
11641 |
++ flush_tlb_all(); |
11642 |
++#endif |
11643 |
++ |
11644 |
+ free_init_pages("unused kernel memory", |
11645 |
+ (unsigned long)(&__init_begin), |
11646 |
+ (unsigned long)(&__init_end)); |
11647 |
+@@ -730,7 +776,7 @@ int in_gate_area_no_task(unsigned long a |
11648 |
+ |
11649 |
+ const char *arch_vma_name(struct vm_area_struct *vma) |
11650 |
+ { |
11651 |
+- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) |
11652 |
++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso) |
11653 |
+ return "[vdso]"; |
11654 |
+ if (vma == &gate_vma) |
11655 |
+ return "[vsyscall]"; |
11656 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/ioremap_32.c linux-2.6.24.4/arch/x86/mm/ioremap_32.c |
11657 |
+--- linux-2.6.24.4/arch/x86/mm/ioremap_32.c 2008-03-24 14:49:18.000000000 -0400 |
11658 |
++++ linux-2.6.24.4/arch/x86/mm/ioremap_32.c 2008-03-26 17:56:55.000000000 -0400 |
11659 |
+@@ -67,8 +67,11 @@ void __iomem * __ioremap(unsigned long p |
11660 |
+ return NULL; |
11661 |
+ } |
11662 |
+ |
11663 |
+- prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY |
11664 |
+- | _PAGE_ACCESSED | flags); |
11665 |
++#ifdef CONFIG_X86_PAE |
11666 |
++ prot = __pgprot((__PAGE_KERNEL | _PAGE_GLOBAL | flags) & __supported_pte_mask); |
11667 |
++#else |
11668 |
++ prot = __pgprot(__PAGE_KERNEL | _PAGE_GLOBAL | flags); |
11669 |
++#endif |
11670 |
+ |
11671 |
+ /* |
11672 |
+ * Mappings have to be page-aligned |
11673 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/ioremap_64.c linux-2.6.24.4/arch/x86/mm/ioremap_64.c |
11674 |
+--- linux-2.6.24.4/arch/x86/mm/ioremap_64.c 2008-03-24 14:49:18.000000000 -0400 |
11675 |
++++ linux-2.6.24.4/arch/x86/mm/ioremap_64.c 2008-03-26 17:56:55.000000000 -0400 |
11676 |
+@@ -48,7 +48,7 @@ ioremap_change_attr(unsigned long phys_a |
11677 |
+ * Must use a address here and not struct page because the phys addr |
11678 |
+ * can be a in hole between nodes and not have an memmap entry. |
11679 |
+ */ |
11680 |
+- err = change_page_attr_addr(vaddr,npages,__pgprot(__PAGE_KERNEL|flags)); |
11681 |
++ err = change_page_attr_addr(vaddr,npages,__pgprot((__PAGE_KERNEL|_PAGE_GLOBAL|flags) & __supported_pte_mask)); |
11682 |
+ if (!err) |
11683 |
+ global_flush_tlb(); |
11684 |
+ } |
11685 |
+@@ -103,8 +103,8 @@ void __iomem * __ioremap(unsigned long p |
11686 |
+ } |
11687 |
+ #endif |
11688 |
+ |
11689 |
+- pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_GLOBAL |
11690 |
+- | _PAGE_DIRTY | _PAGE_ACCESSED | flags); |
11691 |
++ pgprot = __pgprot((__PAGE_KERNEL | _PAGE_GLOBAL | flags) & __supported_pte_mask); |
11692 |
++ |
11693 |
+ /* |
11694 |
+ * Mappings have to be page-aligned |
11695 |
+ */ |
11696 |
+@@ -126,7 +126,7 @@ void __iomem * __ioremap(unsigned long p |
11697 |
+ return NULL; |
11698 |
+ } |
11699 |
+ if (flags && ioremap_change_attr(phys_addr, size, flags) < 0) { |
11700 |
+- area->flags &= 0xffffff; |
11701 |
++ area->flags &= 0xfffff; |
11702 |
+ vunmap(addr); |
11703 |
+ return NULL; |
11704 |
+ } |
11705 |
+@@ -199,7 +199,7 @@ void iounmap(volatile void __iomem *addr |
11706 |
+ |
11707 |
+ /* Reset the direct mapping. Can block */ |
11708 |
+ if (p->flags >> 20) |
11709 |
+- ioremap_change_attr(p->phys_addr, p->size, 0); |
11710 |
++ ioremap_change_attr(p->phys_addr, p->size - PAGE_SIZE, 0); |
11711 |
+ |
11712 |
+ /* Finally remove it */ |
11713 |
+ o = remove_vm_area((void *)addr); |
11714 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/mmap_32.c linux-2.6.24.4/arch/x86/mm/mmap_32.c |
11715 |
+--- linux-2.6.24.4/arch/x86/mm/mmap_32.c 2008-03-24 14:49:18.000000000 -0400 |
11716 |
++++ linux-2.6.24.4/arch/x86/mm/mmap_32.c 2008-03-26 17:56:55.000000000 -0400 |
11717 |
+@@ -35,12 +35,18 @@ |
11718 |
+ * Leave an at least ~128 MB hole. |
11719 |
+ */ |
11720 |
+ #define MIN_GAP (128*1024*1024) |
11721 |
+-#define MAX_GAP (TASK_SIZE/6*5) |
11722 |
++#define MAX_GAP (task_size/6*5) |
11723 |
+ |
11724 |
+ static inline unsigned long mmap_base(struct mm_struct *mm) |
11725 |
+ { |
11726 |
+ unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; |
11727 |
+ unsigned long random_factor = 0; |
11728 |
++ unsigned long task_size = TASK_SIZE; |
11729 |
++ |
11730 |
++#ifdef CONFIG_PAX_SEGMEXEC |
11731 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
11732 |
++ task_size = SEGMEXEC_TASK_SIZE; |
11733 |
++#endif |
11734 |
+ |
11735 |
+ if (current->flags & PF_RANDOMIZE) |
11736 |
+ random_factor = get_random_int() % (1024*1024); |
11737 |
+@@ -50,7 +56,7 @@ static inline unsigned long mmap_base(st |
11738 |
+ else if (gap > MAX_GAP) |
11739 |
+ gap = MAX_GAP; |
11740 |
+ |
11741 |
+- return PAGE_ALIGN(TASK_SIZE - gap - random_factor); |
11742 |
++ return PAGE_ALIGN(task_size - gap - random_factor); |
11743 |
+ } |
11744 |
+ |
11745 |
+ /* |
11746 |
+@@ -66,11 +72,30 @@ void arch_pick_mmap_layout(struct mm_str |
11747 |
+ if (sysctl_legacy_va_layout || |
11748 |
+ (current->personality & ADDR_COMPAT_LAYOUT) || |
11749 |
+ current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) { |
11750 |
++ |
11751 |
++#ifdef CONFIG_PAX_SEGMEXEC |
11752 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
11753 |
++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE; |
11754 |
++ else |
11755 |
++#endif |
11756 |
++ |
11757 |
+ mm->mmap_base = TASK_UNMAPPED_BASE; |
11758 |
++ |
11759 |
++#ifdef CONFIG_PAX_RANDMMAP |
11760 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
11761 |
++ mm->mmap_base += mm->delta_mmap; |
11762 |
++#endif |
11763 |
++ |
11764 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
11765 |
+ mm->unmap_area = arch_unmap_area; |
11766 |
+ } else { |
11767 |
+ mm->mmap_base = mmap_base(mm); |
11768 |
++ |
11769 |
++#ifdef CONFIG_PAX_RANDMMAP |
11770 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
11771 |
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; |
11772 |
++#endif |
11773 |
++ |
11774 |
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
11775 |
+ mm->unmap_area = arch_unmap_area_topdown; |
11776 |
+ } |
11777 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/mmap_64.c linux-2.6.24.4/arch/x86/mm/mmap_64.c |
11778 |
+--- linux-2.6.24.4/arch/x86/mm/mmap_64.c 2008-03-24 14:49:18.000000000 -0400 |
11779 |
++++ linux-2.6.24.4/arch/x86/mm/mmap_64.c 2008-03-26 17:56:55.000000000 -0400 |
11780 |
+@@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str |
11781 |
+ unsigned rnd = get_random_int() & 0xfffffff; |
11782 |
+ mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT; |
11783 |
+ } |
11784 |
++ |
11785 |
++#ifdef CONFIG_PAX_RANDMMAP |
11786 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
11787 |
++ mm->mmap_base += mm->delta_mmap; |
11788 |
++#endif |
11789 |
++ |
11790 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
11791 |
+ mm->unmap_area = arch_unmap_area; |
11792 |
+ } |
11793 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/numa_64.c linux-2.6.24.4/arch/x86/mm/numa_64.c |
11794 |
+--- linux-2.6.24.4/arch/x86/mm/numa_64.c 2008-03-24 14:49:18.000000000 -0400 |
11795 |
++++ linux-2.6.24.4/arch/x86/mm/numa_64.c 2008-03-26 17:56:55.000000000 -0400 |
11796 |
+@@ -19,7 +19,7 @@ |
11797 |
+ #include <asm/acpi.h> |
11798 |
+ |
11799 |
+ #ifndef Dprintk |
11800 |
+-#define Dprintk(x...) |
11801 |
++#define Dprintk(x...) do {} while (0) |
11802 |
+ #endif |
11803 |
+ |
11804 |
+ struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; |
11805 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/pageattr_32.c linux-2.6.24.4/arch/x86/mm/pageattr_32.c |
11806 |
+--- linux-2.6.24.4/arch/x86/mm/pageattr_32.c 2008-03-24 14:49:18.000000000 -0400 |
11807 |
++++ linux-2.6.24.4/arch/x86/mm/pageattr_32.c 2008-03-26 17:56:55.000000000 -0400 |
11808 |
+@@ -13,6 +13,7 @@ |
11809 |
+ #include <asm/tlbflush.h> |
11810 |
+ #include <asm/pgalloc.h> |
11811 |
+ #include <asm/sections.h> |
11812 |
++#include <asm/desc.h> |
11813 |
+ |
11814 |
+ static DEFINE_SPINLOCK(cpa_lock); |
11815 |
+ static struct list_head df_list = LIST_HEAD_INIT(df_list); |
11816 |
+@@ -37,16 +38,16 @@ pte_t *lookup_address(unsigned long addr |
11817 |
+ } |
11818 |
+ |
11819 |
+ static struct page *split_large_page(unsigned long address, pgprot_t prot, |
11820 |
+- pgprot_t ref_prot) |
11821 |
++ pgprot_t ref_prot, unsigned long flags) |
11822 |
+ { |
11823 |
+ int i; |
11824 |
+ unsigned long addr; |
11825 |
+ struct page *base; |
11826 |
+ pte_t *pbase; |
11827 |
+ |
11828 |
+- spin_unlock_irq(&cpa_lock); |
11829 |
++ spin_unlock_irqrestore(&cpa_lock, flags); |
11830 |
+ base = alloc_pages(GFP_KERNEL, 0); |
11831 |
+- spin_lock_irq(&cpa_lock); |
11832 |
++ spin_lock_irqsave(&cpa_lock, flags); |
11833 |
+ if (!base) |
11834 |
+ return NULL; |
11835 |
+ |
11836 |
+@@ -99,7 +100,18 @@ static void set_pmd_pte(pte_t *kpte, uns |
11837 |
+ struct page *page; |
11838 |
+ unsigned long flags; |
11839 |
+ |
11840 |
++#ifdef CONFIG_PAX_KERNEXEC |
11841 |
++ unsigned long cr0; |
11842 |
++ |
11843 |
++ pax_open_kernel(cr0); |
11844 |
++#endif |
11845 |
++ |
11846 |
+ set_pte_atomic(kpte, pte); /* change init_mm */ |
11847 |
++ |
11848 |
++#ifdef CONFIG_PAX_KERNEXEC |
11849 |
++ pax_close_kernel(cr0); |
11850 |
++#endif |
11851 |
++ |
11852 |
+ if (SHARED_KERNEL_PMD) |
11853 |
+ return; |
11854 |
+ |
11855 |
+@@ -126,7 +138,7 @@ static inline void revert_page(struct pa |
11856 |
+ pte_t *linear; |
11857 |
+ |
11858 |
+ ref_prot = |
11859 |
+- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext) |
11860 |
++ ((address & LARGE_PAGE_MASK) < ktla_ktva((unsigned long)&_etext)) |
11861 |
+ ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE; |
11862 |
+ |
11863 |
+ linear = (pte_t *) |
11864 |
+@@ -143,7 +155,7 @@ static inline void save_page(struct page |
11865 |
+ } |
11866 |
+ |
11867 |
+ static int |
11868 |
+-__change_page_attr(struct page *page, pgprot_t prot) |
11869 |
++__change_page_attr(struct page *page, pgprot_t prot, unsigned long flags) |
11870 |
+ { |
11871 |
+ pte_t *kpte; |
11872 |
+ unsigned long address; |
11873 |
+@@ -167,13 +179,20 @@ __change_page_attr(struct page *page, pg |
11874 |
+ struct page *split; |
11875 |
+ |
11876 |
+ ref_prot = |
11877 |
+- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext) |
11878 |
++ ((address & LARGE_PAGE_MASK) < ktla_ktva((unsigned long)&_etext)) |
11879 |
+ ? PAGE_KERNEL_EXEC : PAGE_KERNEL; |
11880 |
+- split = split_large_page(address, prot, ref_prot); |
11881 |
++ split = split_large_page(address, prot, ref_prot, flags); |
11882 |
+ if (!split) |
11883 |
+ return -ENOMEM; |
11884 |
+- set_pmd_pte(kpte,address,mk_pte(split, ref_prot)); |
11885 |
+- kpte_page = split; |
11886 |
++ if (pte_huge(*kpte)) { |
11887 |
++ set_pmd_pte(kpte,address,mk_pte(split, ref_prot)); |
11888 |
++ kpte_page = split; |
11889 |
++ } else { |
11890 |
++ __free_pages(split, 0); |
11891 |
++ kpte = lookup_address(address); |
11892 |
++ kpte_page = virt_to_page(kpte); |
11893 |
++ set_pte_atomic(kpte, mk_pte(page, prot)); |
11894 |
++ } |
11895 |
+ } |
11896 |
+ page_private(kpte_page)++; |
11897 |
+ } else if (!pte_huge(*kpte)) { |
11898 |
+@@ -225,7 +244,7 @@ int change_page_attr(struct page *page, |
11899 |
+ |
11900 |
+ spin_lock_irqsave(&cpa_lock, flags); |
11901 |
+ for (i = 0; i < numpages; i++, page++) { |
11902 |
+- err = __change_page_attr(page, prot); |
11903 |
++ err = __change_page_attr(page, prot, flags); |
11904 |
+ if (err) |
11905 |
+ break; |
11906 |
+ } |
11907 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/pageattr_64.c linux-2.6.24.4/arch/x86/mm/pageattr_64.c |
11908 |
+--- linux-2.6.24.4/arch/x86/mm/pageattr_64.c 2008-03-24 14:49:18.000000000 -0400 |
11909 |
++++ linux-2.6.24.4/arch/x86/mm/pageattr_64.c 2008-03-26 17:56:55.000000000 -0400 |
11910 |
+@@ -110,6 +110,10 @@ static void revert_page(unsigned long ad |
11911 |
+ pte_t large_pte; |
11912 |
+ unsigned long pfn; |
11913 |
+ |
11914 |
++#ifdef CONFIG_PAX_KERNEXEC |
11915 |
++ unsigned long cr0; |
11916 |
++#endif |
11917 |
++ |
11918 |
+ pgd = pgd_offset_k(address); |
11919 |
+ BUG_ON(pgd_none(*pgd)); |
11920 |
+ pud = pud_offset(pgd,address); |
11921 |
+@@ -119,8 +123,18 @@ static void revert_page(unsigned long ad |
11922 |
+ pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT; |
11923 |
+ large_pte = pfn_pte(pfn, ref_prot); |
11924 |
+ large_pte = pte_mkhuge(large_pte); |
11925 |
++ |
11926 |
++#ifdef CONFIG_PAX_KERNEXEC |
11927 |
++ pax_open_kernel(cr0); |
11928 |
++#endif |
11929 |
++ |
11930 |
+ set_pte((pte_t *)pmd, large_pte); |
11931 |
+-} |
11932 |
++ |
11933 |
++#ifdef CONFIG_PAX_KERNEXEC |
11934 |
++ pax_close_kernel(cr0); |
11935 |
++#endif |
11936 |
++ |
11937 |
++} |
11938 |
+ |
11939 |
+ static int |
11940 |
+ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, |
11941 |
+@@ -136,22 +150,36 @@ __change_page_attr(unsigned long address |
11942 |
+ BUG_ON(PageLRU(kpte_page)); |
11943 |
+ BUG_ON(PageCompound(kpte_page)); |
11944 |
+ if (pgprot_val(prot) != pgprot_val(ref_prot)) { |
11945 |
+- if (!pte_huge(*kpte)) { |
11946 |
+- set_pte(kpte, pfn_pte(pfn, prot)); |
11947 |
+- } else { |
11948 |
++ if (pte_huge(*kpte)) { |
11949 |
+ /* |
11950 |
+ * split_large_page will take the reference for this |
11951 |
+ * change_page_attr on the split page. |
11952 |
+ */ |
11953 |
+ struct page *split; |
11954 |
++ |
11955 |
++#ifdef CONFIG_PAX_KERNEXEC |
11956 |
++ unsigned long cr0; |
11957 |
++#endif |
11958 |
++ |
11959 |
+ ref_prot2 = pte_pgprot(pte_clrhuge(*kpte)); |
11960 |
+ split = split_large_page(address, prot, ref_prot2); |
11961 |
+ if (!split) |
11962 |
+ return -ENOMEM; |
11963 |
+ pgprot_val(ref_prot2) &= ~_PAGE_NX; |
11964 |
++ |
11965 |
++#ifdef CONFIG_PAX_KERNEXEC |
11966 |
++ pax_open_kernel(cr0); |
11967 |
++#endif |
11968 |
++ |
11969 |
+ set_pte(kpte, mk_pte(split, ref_prot2)); |
11970 |
++ |
11971 |
++#ifdef CONFIG_PAX_KERNEXEC |
11972 |
++ pax_close_kernel(cr0); |
11973 |
++#endif |
11974 |
++ |
11975 |
+ kpte_page = split; |
11976 |
+- } |
11977 |
++ } else |
11978 |
++ set_pte(kpte, pfn_pte(pfn, prot)); |
11979 |
+ page_private(kpte_page)++; |
11980 |
+ } else if (!pte_huge(*kpte)) { |
11981 |
+ set_pte(kpte, pfn_pte(pfn, ref_prot)); |
11982 |
+diff -urNp linux-2.6.24.4/arch/x86/mm/pgtable_32.c linux-2.6.24.4/arch/x86/mm/pgtable_32.c |
11983 |
+--- linux-2.6.24.4/arch/x86/mm/pgtable_32.c 2008-03-24 14:49:18.000000000 -0400 |
11984 |
++++ linux-2.6.24.4/arch/x86/mm/pgtable_32.c 2008-03-26 17:56:55.000000000 -0400 |
11985 |
+@@ -83,6 +83,10 @@ static void set_pte_pfn(unsigned long va |
11986 |
+ pmd_t *pmd; |
11987 |
+ pte_t *pte; |
11988 |
+ |
11989 |
++#ifdef CONFIG_PAX_KERNEXEC |
11990 |
++ unsigned long cr0; |
11991 |
++#endif |
11992 |
++ |
11993 |
+ pgd = swapper_pg_dir + pgd_index(vaddr); |
11994 |
+ if (pgd_none(*pgd)) { |
11995 |
+ BUG(); |
11996 |
+@@ -99,11 +103,20 @@ static void set_pte_pfn(unsigned long va |
11997 |
+ return; |
11998 |
+ } |
11999 |
+ pte = pte_offset_kernel(pmd, vaddr); |
12000 |
++ |
12001 |
++#ifdef CONFIG_PAX_KERNEXEC |
12002 |
++ pax_open_kernel(cr0); |
12003 |
++#endif |
12004 |
++ |
12005 |
+ if (pgprot_val(flags)) |
12006 |
+ set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags)); |
12007 |
+ else |
12008 |
+ pte_clear(&init_mm, vaddr, pte); |
12009 |
+ |
12010 |
++#ifdef CONFIG_PAX_KERNEXEC |
12011 |
++ pax_close_kernel(cr0); |
12012 |
++#endif |
12013 |
++ |
12014 |
+ /* |
12015 |
+ * It's enough to flush this one mapping. |
12016 |
+ * (PGE mappings get flushed as well) |
12017 |
+diff -urNp linux-2.6.24.4/arch/x86/oprofile/backtrace.c linux-2.6.24.4/arch/x86/oprofile/backtrace.c |
12018 |
+--- linux-2.6.24.4/arch/x86/oprofile/backtrace.c 2008-03-24 14:49:18.000000000 -0400 |
12019 |
++++ linux-2.6.24.4/arch/x86/oprofile/backtrace.c 2008-03-26 17:56:55.000000000 -0400 |
12020 |
+@@ -37,7 +37,7 @@ static void backtrace_address(void *data |
12021 |
+ unsigned int *depth = data; |
12022 |
+ |
12023 |
+ if ((*depth)--) |
12024 |
+- oprofile_add_trace(addr); |
12025 |
++ oprofile_add_trace(ktla_ktva(addr)); |
12026 |
+ } |
12027 |
+ |
12028 |
+ static struct stacktrace_ops backtrace_ops = { |
12029 |
+@@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg |
12030 |
+ struct frame_head *head = (struct frame_head *)frame_pointer(regs); |
12031 |
+ unsigned long stack = stack_pointer(regs); |
12032 |
+ |
12033 |
+- if (!user_mode_vm(regs)) { |
12034 |
++ if (!user_mode(regs)) { |
12035 |
+ if (depth) |
12036 |
+ dump_trace(NULL, regs, (unsigned long *)stack, |
12037 |
+ &backtrace_ops, &depth); |
12038 |
+diff -urNp linux-2.6.24.4/arch/x86/oprofile/op_model_p4.c linux-2.6.24.4/arch/x86/oprofile/op_model_p4.c |
12039 |
+--- linux-2.6.24.4/arch/x86/oprofile/op_model_p4.c 2008-03-24 14:49:18.000000000 -0400 |
12040 |
++++ linux-2.6.24.4/arch/x86/oprofile/op_model_p4.c 2008-03-26 17:56:55.000000000 -0400 |
12041 |
+@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo |
12042 |
+ #endif |
12043 |
+ } |
12044 |
+ |
12045 |
+-static int inline addr_increment(void) |
12046 |
++static inline int addr_increment(void) |
12047 |
+ { |
12048 |
+ #ifdef CONFIG_SMP |
12049 |
+ return smp_num_siblings == 2 ? 2 : 1; |
12050 |
+diff -urNp linux-2.6.24.4/arch/x86/pci/common.c linux-2.6.24.4/arch/x86/pci/common.c |
12051 |
+--- linux-2.6.24.4/arch/x86/pci/common.c 2008-03-24 14:49:18.000000000 -0400 |
12052 |
++++ linux-2.6.24.4/arch/x86/pci/common.c 2008-03-26 17:56:55.000000000 -0400 |
12053 |
+@@ -331,7 +331,7 @@ static struct dmi_system_id __devinitdat |
12054 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"), |
12055 |
+ }, |
12056 |
+ }, |
12057 |
+- {} |
12058 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL} |
12059 |
+ }; |
12060 |
+ |
12061 |
+ struct pci_bus * __devinit pcibios_scan_root(int busnum) |
12062 |
+diff -urNp linux-2.6.24.4/arch/x86/pci/early.c linux-2.6.24.4/arch/x86/pci/early.c |
12063 |
+--- linux-2.6.24.4/arch/x86/pci/early.c 2008-03-24 14:49:18.000000000 -0400 |
12064 |
++++ linux-2.6.24.4/arch/x86/pci/early.c 2008-03-26 17:56:55.000000000 -0400 |
12065 |
+@@ -7,7 +7,7 @@ |
12066 |
+ /* Direct PCI access. This is used for PCI accesses in early boot before |
12067 |
+ the PCI subsystem works. */ |
12068 |
+ |
12069 |
+-#define PDprintk(x...) |
12070 |
++#define PDprintk(x...) do {} while (0) |
12071 |
+ |
12072 |
+ u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) |
12073 |
+ { |
12074 |
+diff -urNp linux-2.6.24.4/arch/x86/pci/fixup.c linux-2.6.24.4/arch/x86/pci/fixup.c |
12075 |
+--- linux-2.6.24.4/arch/x86/pci/fixup.c 2008-03-24 14:49:18.000000000 -0400 |
12076 |
++++ linux-2.6.24.4/arch/x86/pci/fixup.c 2008-03-26 17:56:55.000000000 -0400 |
12077 |
+@@ -362,7 +362,7 @@ static struct dmi_system_id __devinitdat |
12078 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"), |
12079 |
+ }, |
12080 |
+ }, |
12081 |
+- {} |
12082 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
12083 |
+ }; |
12084 |
+ |
12085 |
+ /* |
12086 |
+@@ -433,7 +433,7 @@ static struct dmi_system_id __devinitdat |
12087 |
+ DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"), |
12088 |
+ }, |
12089 |
+ }, |
12090 |
+- { } |
12091 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
12092 |
+ }; |
12093 |
+ |
12094 |
+ static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev) |
12095 |
+diff -urNp linux-2.6.24.4/arch/x86/pci/irq.c linux-2.6.24.4/arch/x86/pci/irq.c |
12096 |
+--- linux-2.6.24.4/arch/x86/pci/irq.c 2008-03-24 14:49:18.000000000 -0400 |
12097 |
++++ linux-2.6.24.4/arch/x86/pci/irq.c 2008-03-26 17:56:55.000000000 -0400 |
12098 |
+@@ -528,7 +528,7 @@ static __init int intel_router_probe(str |
12099 |
+ static struct pci_device_id __initdata pirq_440gx[] = { |
12100 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) }, |
12101 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) }, |
12102 |
+- { }, |
12103 |
++ { PCI_DEVICE(0, 0) } |
12104 |
+ }; |
12105 |
+ |
12106 |
+ /* 440GX has a proprietary PIRQ router -- don't use it */ |
12107 |
+@@ -1090,7 +1090,7 @@ static struct dmi_system_id __initdata p |
12108 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), |
12109 |
+ }, |
12110 |
+ }, |
12111 |
+- { } |
12112 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
12113 |
+ }; |
12114 |
+ |
12115 |
+ static int __init pcibios_irq_init(void) |
12116 |
+diff -urNp linux-2.6.24.4/arch/x86/pci/pcbios.c linux-2.6.24.4/arch/x86/pci/pcbios.c |
12117 |
+--- linux-2.6.24.4/arch/x86/pci/pcbios.c 2008-03-24 14:49:18.000000000 -0400 |
12118 |
++++ linux-2.6.24.4/arch/x86/pci/pcbios.c 2008-03-26 17:56:55.000000000 -0400 |
12119 |
+@@ -57,50 +57,124 @@ union bios32 { |
12120 |
+ static struct { |
12121 |
+ unsigned long address; |
12122 |
+ unsigned short segment; |
12123 |
+-} bios32_indirect = { 0, __KERNEL_CS }; |
12124 |
++} bios32_indirect __read_only = { 0, __PCIBIOS_CS }; |
12125 |
+ |
12126 |
+ /* |
12127 |
+ * Returns the entry point for the given service, NULL on error |
12128 |
+ */ |
12129 |
+ |
12130 |
+-static unsigned long bios32_service(unsigned long service) |
12131 |
++static unsigned long __devinit bios32_service(unsigned long service) |
12132 |
+ { |
12133 |
+ unsigned char return_code; /* %al */ |
12134 |
+ unsigned long address; /* %ebx */ |
12135 |
+ unsigned long length; /* %ecx */ |
12136 |
+ unsigned long entry; /* %edx */ |
12137 |
+ unsigned long flags; |
12138 |
++ struct desc_struct *gdt; |
12139 |
++ |
12140 |
++#ifdef CONFIG_PAX_KERNEXEC |
12141 |
++ unsigned long cr0; |
12142 |
++#endif |
12143 |
+ |
12144 |
+ local_irq_save(flags); |
12145 |
+- __asm__("lcall *(%%edi); cld" |
12146 |
++ |
12147 |
++ gdt = get_cpu_gdt_table(smp_processor_id()); |
12148 |
++ |
12149 |
++#ifdef CONFIG_PAX_KERNEXEC |
12150 |
++ pax_open_kernel(cr0); |
12151 |
++#endif |
12152 |
++ |
12153 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a, |
12154 |
++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b, |
12155 |
++ 0UL, 0xFFFFFUL, 0x9B, 0xC); |
12156 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a, |
12157 |
++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b, |
12158 |
++ 0UL, 0xFFFFFUL, 0x93, 0xC); |
12159 |
++ |
12160 |
++#ifdef CONFIG_PAX_KERNEXEC |
12161 |
++ pax_close_kernel(cr0); |
12162 |
++#endif |
12163 |
++ |
12164 |
++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld" |
12165 |
+ : "=a" (return_code), |
12166 |
+ "=b" (address), |
12167 |
+ "=c" (length), |
12168 |
+ "=d" (entry) |
12169 |
+ : "0" (service), |
12170 |
+ "1" (0), |
12171 |
+- "D" (&bios32_indirect)); |
12172 |
++ "D" (&bios32_indirect), |
12173 |
++ "r"(__PCIBIOS_DS) |
12174 |
++ : "memory"); |
12175 |
++ |
12176 |
++#ifdef CONFIG_PAX_KERNEXEC |
12177 |
++ pax_open_kernel(cr0); |
12178 |
++#endif |
12179 |
++ |
12180 |
++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0; |
12181 |
++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0; |
12182 |
++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0; |
12183 |
++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0; |
12184 |
++ |
12185 |
++#ifdef CONFIG_PAX_KERNEXEC |
12186 |
++ pax_close_kernel(cr0); |
12187 |
++#endif |
12188 |
++ |
12189 |
+ local_irq_restore(flags); |
12190 |
+ |
12191 |
+ switch (return_code) { |
12192 |
+- case 0: |
12193 |
+- return address + entry; |
12194 |
+- case 0x80: /* Not present */ |
12195 |
+- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service); |
12196 |
+- return 0; |
12197 |
+- default: /* Shouldn't happen */ |
12198 |
+- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n", |
12199 |
+- service, return_code); |
12200 |
++ case 0: { |
12201 |
++ int cpu; |
12202 |
++ unsigned char flags; |
12203 |
++ |
12204 |
++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry); |
12205 |
++ if (address >= 0xFFFF0 || length >= 0xFFFF0 - address || length <= entry) { |
12206 |
++ printk(KERN_WARNING "bios32_service: not valid\n"); |
12207 |
+ return 0; |
12208 |
++ } |
12209 |
++ address = address + PAGE_OFFSET; |
12210 |
++ length += 16UL; /* some BIOSs underreport this... */ |
12211 |
++ flags = 4; |
12212 |
++ if (length >= 64*1024*1024) { |
12213 |
++ length >>= PAGE_SHIFT; |
12214 |
++ flags |= 8; |
12215 |
++ } |
12216 |
++ |
12217 |
++#ifdef CONFIG_PAX_KERNEXEC |
12218 |
++ pax_open_kernel(cr0); |
12219 |
++#endif |
12220 |
++ |
12221 |
++ for (cpu = 0; cpu < NR_CPUS; cpu++) { |
12222 |
++ gdt = get_cpu_gdt_table(cpu); |
12223 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a, |
12224 |
++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b, |
12225 |
++ address, length, 0x9b, flags); |
12226 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a, |
12227 |
++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b, |
12228 |
++ address, length, 0x93, flags); |
12229 |
++ } |
12230 |
++ |
12231 |
++#ifdef CONFIG_PAX_KERNEXEC |
12232 |
++ pax_close_kernel(cr0); |
12233 |
++#endif |
12234 |
++ |
12235 |
++ return entry; |
12236 |
++ } |
12237 |
++ case 0x80: /* Not present */ |
12238 |
++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service); |
12239 |
++ return 0; |
12240 |
++ default: /* Shouldn't happen */ |
12241 |
++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n", |
12242 |
++ service, return_code); |
12243 |
++ return 0; |
12244 |
+ } |
12245 |
+ } |
12246 |
+ |
12247 |
+ static struct { |
12248 |
+ unsigned long address; |
12249 |
+ unsigned short segment; |
12250 |
+-} pci_indirect = { 0, __KERNEL_CS }; |
12251 |
++} pci_indirect __read_only = { 0, __PCIBIOS_CS }; |
12252 |
+ |
12253 |
+-static int pci_bios_present; |
12254 |
++static int pci_bios_present __read_only; |
12255 |
+ |
12256 |
+ static int __devinit check_pcibios(void) |
12257 |
+ { |
12258 |
+@@ -109,11 +183,13 @@ static int __devinit check_pcibios(void) |
12259 |
+ unsigned long flags, pcibios_entry; |
12260 |
+ |
12261 |
+ if ((pcibios_entry = bios32_service(PCI_SERVICE))) { |
12262 |
+- pci_indirect.address = pcibios_entry + PAGE_OFFSET; |
12263 |
++ pci_indirect.address = pcibios_entry; |
12264 |
+ |
12265 |
+ local_irq_save(flags); |
12266 |
+- __asm__( |
12267 |
+- "lcall *(%%edi); cld\n\t" |
12268 |
++ __asm__("movw %w6, %%ds\n\t" |
12269 |
++ "lcall *%%ss:(%%edi); cld\n\t" |
12270 |
++ "push %%ss\n\t" |
12271 |
++ "pop %%ds\n\t" |
12272 |
+ "jc 1f\n\t" |
12273 |
+ "xor %%ah, %%ah\n" |
12274 |
+ "1:" |
12275 |
+@@ -122,7 +198,8 @@ static int __devinit check_pcibios(void) |
12276 |
+ "=b" (ebx), |
12277 |
+ "=c" (ecx) |
12278 |
+ : "1" (PCIBIOS_PCI_BIOS_PRESENT), |
12279 |
+- "D" (&pci_indirect) |
12280 |
++ "D" (&pci_indirect), |
12281 |
++ "r" (__PCIBIOS_DS) |
12282 |
+ : "memory"); |
12283 |
+ local_irq_restore(flags); |
12284 |
+ |
12285 |
+@@ -158,7 +235,10 @@ static int __devinit pci_bios_find_devic |
12286 |
+ unsigned short bx; |
12287 |
+ unsigned short ret; |
12288 |
+ |
12289 |
+- __asm__("lcall *(%%edi); cld\n\t" |
12290 |
++ __asm__("movw %w7, %%ds\n\t" |
12291 |
++ "lcall *%%ss:(%%edi); cld\n\t" |
12292 |
++ "push %%ss\n\t" |
12293 |
++ "pop %%ds\n\t" |
12294 |
+ "jc 1f\n\t" |
12295 |
+ "xor %%ah, %%ah\n" |
12296 |
+ "1:" |
12297 |
+@@ -168,7 +248,8 @@ static int __devinit pci_bios_find_devic |
12298 |
+ "c" (device_id), |
12299 |
+ "d" (vendor), |
12300 |
+ "S" ((int) index), |
12301 |
+- "D" (&pci_indirect)); |
12302 |
++ "D" (&pci_indirect), |
12303 |
++ "r" (__PCIBIOS_DS)); |
12304 |
+ *bus = (bx >> 8) & 0xff; |
12305 |
+ *device_fn = bx & 0xff; |
12306 |
+ return (int) (ret & 0xff00) >> 8; |
12307 |
+@@ -188,7 +269,10 @@ static int pci_bios_read(unsigned int se |
12308 |
+ |
12309 |
+ switch (len) { |
12310 |
+ case 1: |
12311 |
+- __asm__("lcall *(%%esi); cld\n\t" |
12312 |
++ __asm__("movw %w6, %%ds\n\t" |
12313 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
12314 |
++ "push %%ss\n\t" |
12315 |
++ "pop %%ds\n\t" |
12316 |
+ "jc 1f\n\t" |
12317 |
+ "xor %%ah, %%ah\n" |
12318 |
+ "1:" |
12319 |
+@@ -197,10 +281,14 @@ static int pci_bios_read(unsigned int se |
12320 |
+ : "1" (PCIBIOS_READ_CONFIG_BYTE), |
12321 |
+ "b" (bx), |
12322 |
+ "D" ((long)reg), |
12323 |
+- "S" (&pci_indirect)); |
12324 |
++ "S" (&pci_indirect), |
12325 |
++ "r" (__PCIBIOS_DS)); |
12326 |
+ break; |
12327 |
+ case 2: |
12328 |
+- __asm__("lcall *(%%esi); cld\n\t" |
12329 |
++ __asm__("movw %w6, %%ds\n\t" |
12330 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
12331 |
++ "push %%ss\n\t" |
12332 |
++ "pop %%ds\n\t" |
12333 |
+ "jc 1f\n\t" |
12334 |
+ "xor %%ah, %%ah\n" |
12335 |
+ "1:" |
12336 |
+@@ -209,10 +297,14 @@ static int pci_bios_read(unsigned int se |
12337 |
+ : "1" (PCIBIOS_READ_CONFIG_WORD), |
12338 |
+ "b" (bx), |
12339 |
+ "D" ((long)reg), |
12340 |
+- "S" (&pci_indirect)); |
12341 |
++ "S" (&pci_indirect), |
12342 |
++ "r" (__PCIBIOS_DS)); |
12343 |
+ break; |
12344 |
+ case 4: |
12345 |
+- __asm__("lcall *(%%esi); cld\n\t" |
12346 |
++ __asm__("movw %w6, %%ds\n\t" |
12347 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
12348 |
++ "push %%ss\n\t" |
12349 |
++ "pop %%ds\n\t" |
12350 |
+ "jc 1f\n\t" |
12351 |
+ "xor %%ah, %%ah\n" |
12352 |
+ "1:" |
12353 |
+@@ -221,7 +313,8 @@ static int pci_bios_read(unsigned int se |
12354 |
+ : "1" (PCIBIOS_READ_CONFIG_DWORD), |
12355 |
+ "b" (bx), |
12356 |
+ "D" ((long)reg), |
12357 |
+- "S" (&pci_indirect)); |
12358 |
++ "S" (&pci_indirect), |
12359 |
++ "r" (__PCIBIOS_DS)); |
12360 |
+ break; |
12361 |
+ } |
12362 |
+ |
12363 |
+@@ -244,7 +337,10 @@ static int pci_bios_write(unsigned int s |
12364 |
+ |
12365 |
+ switch (len) { |
12366 |
+ case 1: |
12367 |
+- __asm__("lcall *(%%esi); cld\n\t" |
12368 |
++ __asm__("movw %w6, %%ds\n\t" |
12369 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
12370 |
++ "push %%ss\n\t" |
12371 |
++ "pop %%ds\n\t" |
12372 |
+ "jc 1f\n\t" |
12373 |
+ "xor %%ah, %%ah\n" |
12374 |
+ "1:" |
12375 |
+@@ -253,10 +349,14 @@ static int pci_bios_write(unsigned int s |
12376 |
+ "c" (value), |
12377 |
+ "b" (bx), |
12378 |
+ "D" ((long)reg), |
12379 |
+- "S" (&pci_indirect)); |
12380 |
++ "S" (&pci_indirect), |
12381 |
++ "r" (__PCIBIOS_DS)); |
12382 |
+ break; |
12383 |
+ case 2: |
12384 |
+- __asm__("lcall *(%%esi); cld\n\t" |
12385 |
++ __asm__("movw %w6, %%ds\n\t" |
12386 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
12387 |
++ "push %%ss\n\t" |
12388 |
++ "pop %%ds\n\t" |
12389 |
+ "jc 1f\n\t" |
12390 |
+ "xor %%ah, %%ah\n" |
12391 |
+ "1:" |
12392 |
+@@ -265,10 +365,14 @@ static int pci_bios_write(unsigned int s |
12393 |
+ "c" (value), |
12394 |
+ "b" (bx), |
12395 |
+ "D" ((long)reg), |
12396 |
+- "S" (&pci_indirect)); |
12397 |
++ "S" (&pci_indirect), |
12398 |
++ "r" (__PCIBIOS_DS)); |
12399 |
+ break; |
12400 |
+ case 4: |
12401 |
+- __asm__("lcall *(%%esi); cld\n\t" |
12402 |
++ __asm__("movw %w6, %%ds\n\t" |
12403 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
12404 |
++ "push %%ss\n\t" |
12405 |
++ "pop %%ds\n\t" |
12406 |
+ "jc 1f\n\t" |
12407 |
+ "xor %%ah, %%ah\n" |
12408 |
+ "1:" |
12409 |
+@@ -277,7 +381,8 @@ static int pci_bios_write(unsigned int s |
12410 |
+ "c" (value), |
12411 |
+ "b" (bx), |
12412 |
+ "D" ((long)reg), |
12413 |
+- "S" (&pci_indirect)); |
12414 |
++ "S" (&pci_indirect), |
12415 |
++ "r" (__PCIBIOS_DS)); |
12416 |
+ break; |
12417 |
+ } |
12418 |
+ |
12419 |
+@@ -430,10 +535,13 @@ struct irq_routing_table * pcibios_get_i |
12420 |
+ |
12421 |
+ DBG("PCI: Fetching IRQ routing table... "); |
12422 |
+ __asm__("push %%es\n\t" |
12423 |
++ "movw %w8, %%ds\n\t" |
12424 |
+ "push %%ds\n\t" |
12425 |
+ "pop %%es\n\t" |
12426 |
+- "lcall *(%%esi); cld\n\t" |
12427 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
12428 |
+ "pop %%es\n\t" |
12429 |
++ "push %%ss\n\t" |
12430 |
++ "pop %%ds\n" |
12431 |
+ "jc 1f\n\t" |
12432 |
+ "xor %%ah, %%ah\n" |
12433 |
+ "1:" |
12434 |
+@@ -444,7 +552,8 @@ struct irq_routing_table * pcibios_get_i |
12435 |
+ "1" (0), |
12436 |
+ "D" ((long) &opt), |
12437 |
+ "S" (&pci_indirect), |
12438 |
+- "m" (opt) |
12439 |
++ "m" (opt), |
12440 |
++ "r" (__PCIBIOS_DS) |
12441 |
+ : "memory"); |
12442 |
+ DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map); |
12443 |
+ if (ret & 0xff00) |
12444 |
+@@ -468,7 +577,10 @@ int pcibios_set_irq_routing(struct pci_d |
12445 |
+ { |
12446 |
+ int ret; |
12447 |
+ |
12448 |
+- __asm__("lcall *(%%esi); cld\n\t" |
12449 |
++ __asm__("movw %w5, %%ds\n\t" |
12450 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
12451 |
++ "push %%ss\n\t" |
12452 |
++ "pop %%ds\n" |
12453 |
+ "jc 1f\n\t" |
12454 |
+ "xor %%ah, %%ah\n" |
12455 |
+ "1:" |
12456 |
+@@ -476,7 +588,8 @@ int pcibios_set_irq_routing(struct pci_d |
12457 |
+ : "0" (PCIBIOS_SET_PCI_HW_INT), |
12458 |
+ "b" ((dev->bus->number << 8) | dev->devfn), |
12459 |
+ "c" ((irq << 8) | (pin + 10)), |
12460 |
+- "S" (&pci_indirect)); |
12461 |
++ "S" (&pci_indirect), |
12462 |
++ "r" (__PCIBIOS_DS)); |
12463 |
+ return !(ret & 0xff00); |
12464 |
+ } |
12465 |
+ EXPORT_SYMBOL(pcibios_set_irq_routing); |
12466 |
+diff -urNp linux-2.6.24.4/arch/x86/power/cpu.c linux-2.6.24.4/arch/x86/power/cpu.c |
12467 |
+--- linux-2.6.24.4/arch/x86/power/cpu.c 2008-03-24 14:49:18.000000000 -0400 |
12468 |
++++ linux-2.6.24.4/arch/x86/power/cpu.c 2008-03-26 17:56:55.000000000 -0400 |
12469 |
+@@ -64,10 +64,20 @@ static void do_fpu_end(void) |
12470 |
+ static void fix_processor_context(void) |
12471 |
+ { |
12472 |
+ int cpu = smp_processor_id(); |
12473 |
+- struct tss_struct * t = &per_cpu(init_tss, cpu); |
12474 |
++ struct tss_struct *t = init_tss + cpu; |
12475 |
++ |
12476 |
++#ifdef CONFIG_PAX_KERNEXEC |
12477 |
++ unsigned long cr0; |
12478 |
++ |
12479 |
++ pax_open_kernel(cr0); |
12480 |
++#endif |
12481 |
+ |
12482 |
+ 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. */ |
12483 |
+ |
12484 |
++#ifdef CONFIG_PAX_KERNEXEC |
12485 |
++ pax_close_kernel(cr0); |
12486 |
++#endif |
12487 |
++ |
12488 |
+ load_TR_desc(); /* This does ltr */ |
12489 |
+ load_LDT(¤t->active_mm->context); /* This does lldt */ |
12490 |
+ |
12491 |
+diff -urNp linux-2.6.24.4/arch/x86/vdso/vma.c linux-2.6.24.4/arch/x86/vdso/vma.c |
12492 |
+--- linux-2.6.24.4/arch/x86/vdso/vma.c 2008-03-24 14:49:18.000000000 -0400 |
12493 |
++++ linux-2.6.24.4/arch/x86/vdso/vma.c 2008-03-26 17:56:55.000000000 -0400 |
12494 |
+@@ -126,7 +126,7 @@ int arch_setup_additional_pages(struct l |
12495 |
+ if (ret) |
12496 |
+ goto up_fail; |
12497 |
+ |
12498 |
+- current->mm->context.vdso = (void *)addr; |
12499 |
++ current->mm->context.vdso = addr; |
12500 |
+ up_fail: |
12501 |
+ up_write(&mm->mmap_sem); |
12502 |
+ return ret; |
12503 |
+diff -urNp linux-2.6.24.4/arch/x86/xen/enlighten.c linux-2.6.24.4/arch/x86/xen/enlighten.c |
12504 |
+--- linux-2.6.24.4/arch/x86/xen/enlighten.c 2008-03-24 14:49:18.000000000 -0400 |
12505 |
++++ linux-2.6.24.4/arch/x86/xen/enlighten.c 2008-03-26 17:56:55.000000000 -0400 |
12506 |
+@@ -298,7 +298,7 @@ static void xen_set_ldt(const void *addr |
12507 |
+ static void xen_load_gdt(const struct Xgt_desc_struct *dtr) |
12508 |
+ { |
12509 |
+ unsigned long *frames; |
12510 |
+- unsigned long va = dtr->address; |
12511 |
++ unsigned long va = (unsigned long)dtr->address; |
12512 |
+ unsigned int size = dtr->size + 1; |
12513 |
+ unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; |
12514 |
+ int f; |
12515 |
+@@ -313,7 +313,7 @@ static void xen_load_gdt(const struct Xg |
12516 |
+ mcs = xen_mc_entry(sizeof(*frames) * pages); |
12517 |
+ frames = mcs.args; |
12518 |
+ |
12519 |
+- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { |
12520 |
++ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) { |
12521 |
+ frames[f] = virt_to_mfn(va); |
12522 |
+ make_lowmem_page_readonly((void *)va); |
12523 |
+ } |
12524 |
+@@ -407,7 +407,7 @@ static void xen_write_idt_entry(struct d |
12525 |
+ |
12526 |
+ preempt_disable(); |
12527 |
+ |
12528 |
+- start = __get_cpu_var(idt_desc).address; |
12529 |
++ start = (unsigned long)__get_cpu_var(idt_desc).address; |
12530 |
+ end = start + __get_cpu_var(idt_desc).size + 1; |
12531 |
+ |
12532 |
+ xen_mc_flush(); |
12533 |
+diff -urNp linux-2.6.24.4/arch/x86/xen/smp.c linux-2.6.24.4/arch/x86/xen/smp.c |
12534 |
+--- linux-2.6.24.4/arch/x86/xen/smp.c 2008-03-24 14:49:18.000000000 -0400 |
12535 |
++++ linux-2.6.24.4/arch/x86/xen/smp.c 2008-03-26 17:56:55.000000000 -0400 |
12536 |
+@@ -144,7 +144,7 @@ void __init xen_smp_prepare_boot_cpu(voi |
12537 |
+ |
12538 |
+ /* We've switched to the "real" per-cpu gdt, so make sure the |
12539 |
+ old memory can be recycled */ |
12540 |
+- make_lowmem_page_readwrite(&per_cpu__gdt_page); |
12541 |
++ make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id())); |
12542 |
+ |
12543 |
+ for (cpu = 0; cpu < NR_CPUS; cpu++) { |
12544 |
+ cpus_clear(per_cpu(cpu_sibling_map, cpu)); |
12545 |
+@@ -208,7 +208,7 @@ static __cpuinit int |
12546 |
+ cpu_initialize_context(unsigned int cpu, struct task_struct *idle) |
12547 |
+ { |
12548 |
+ struct vcpu_guest_context *ctxt; |
12549 |
+- struct gdt_page *gdt = &per_cpu(gdt_page, cpu); |
12550 |
++ struct desc_struct *gdt = get_cpu_gdt_table(cpu); |
12551 |
+ |
12552 |
+ if (cpu_test_and_set(cpu, cpu_initialized_map)) |
12553 |
+ return 0; |
12554 |
+@@ -218,8 +218,8 @@ cpu_initialize_context(unsigned int cpu, |
12555 |
+ return -ENOMEM; |
12556 |
+ |
12557 |
+ ctxt->flags = VGCF_IN_KERNEL; |
12558 |
+- ctxt->user_regs.ds = __USER_DS; |
12559 |
+- ctxt->user_regs.es = __USER_DS; |
12560 |
++ ctxt->user_regs.ds = __KERNEL_DS; |
12561 |
++ ctxt->user_regs.es = __KERNEL_DS; |
12562 |
+ ctxt->user_regs.fs = __KERNEL_PERCPU; |
12563 |
+ ctxt->user_regs.gs = 0; |
12564 |
+ ctxt->user_regs.ss = __KERNEL_DS; |
12565 |
+@@ -232,11 +232,11 @@ cpu_initialize_context(unsigned int cpu, |
12566 |
+ |
12567 |
+ ctxt->ldt_ents = 0; |
12568 |
+ |
12569 |
+- BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK); |
12570 |
+- make_lowmem_page_readonly(gdt->gdt); |
12571 |
++ BUG_ON((unsigned long)gdt & ~PAGE_MASK); |
12572 |
++ make_lowmem_page_readonly(gdt); |
12573 |
+ |
12574 |
+- ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt); |
12575 |
+- ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt); |
12576 |
++ ctxt->gdt_frames[0] = virt_to_mfn(gdt); |
12577 |
++ ctxt->gdt_ents = GDT_ENTRIES; |
12578 |
+ |
12579 |
+ ctxt->user_regs.cs = __KERNEL_CS; |
12580 |
+ ctxt->user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs); |
12581 |
+diff -urNp linux-2.6.24.4/crypto/async_tx/async_tx.c linux-2.6.24.4/crypto/async_tx/async_tx.c |
12582 |
+--- linux-2.6.24.4/crypto/async_tx/async_tx.c 2008-03-24 14:49:18.000000000 -0400 |
12583 |
++++ linux-2.6.24.4/crypto/async_tx/async_tx.c 2008-03-26 17:56:55.000000000 -0400 |
12584 |
+@@ -342,8 +342,8 @@ async_tx_init(void) |
12585 |
+ err: |
12586 |
+ printk(KERN_ERR "async_tx: initialization failure\n"); |
12587 |
+ |
12588 |
+- while (--cap >= 0) |
12589 |
+- free_percpu(channel_table[cap]); |
12590 |
++ while (cap) |
12591 |
++ free_percpu(channel_table[--cap]); |
12592 |
+ |
12593 |
+ return 1; |
12594 |
+ } |
12595 |
+diff -urNp linux-2.6.24.4/crypto/lrw.c linux-2.6.24.4/crypto/lrw.c |
12596 |
+--- linux-2.6.24.4/crypto/lrw.c 2008-03-24 14:49:18.000000000 -0400 |
12597 |
++++ linux-2.6.24.4/crypto/lrw.c 2008-03-26 17:56:55.000000000 -0400 |
12598 |
+@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par |
12599 |
+ struct priv *ctx = crypto_tfm_ctx(parent); |
12600 |
+ struct crypto_cipher *child = ctx->child; |
12601 |
+ int err, i; |
12602 |
+- be128 tmp = { 0 }; |
12603 |
++ be128 tmp = { 0, 0 }; |
12604 |
+ int bsize = crypto_cipher_blocksize(child); |
12605 |
+ |
12606 |
+ crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); |
12607 |
+diff -urNp linux-2.6.24.4/Documentation/dontdiff linux-2.6.24.4/Documentation/dontdiff |
12608 |
+--- linux-2.6.24.4/Documentation/dontdiff 2008-03-24 14:49:18.000000000 -0400 |
12609 |
++++ linux-2.6.24.4/Documentation/dontdiff 2008-03-26 17:56:55.000000000 -0400 |
12610 |
+@@ -3,6 +3,7 @@ |
12611 |
+ *.bin |
12612 |
+ *.cpio |
12613 |
+ *.css |
12614 |
++*.dbg |
12615 |
+ *.dvi |
12616 |
+ *.eps |
12617 |
+ *.gif |
12618 |
+@@ -183,11 +184,14 @@ version.h* |
12619 |
+ vmlinux |
12620 |
+ vmlinux-* |
12621 |
+ vmlinux.aout |
12622 |
+-vmlinux*.lds* |
12623 |
++vmlinux.bin.all |
12624 |
++vmlinux*.lds |
12625 |
++vmlinux.relocs |
12626 |
+ vmlinux*.scr |
12627 |
+-vsyscall.lds |
12628 |
++vsyscall*.lds |
12629 |
+ wanxlfw.inc |
12630 |
+ uImage |
12631 |
+ unifdef |
12632 |
++utsrelease.h |
12633 |
+ zImage* |
12634 |
+ zconf.hash.c |
12635 |
+diff -urNp linux-2.6.24.4/drivers/acpi/blacklist.c linux-2.6.24.4/drivers/acpi/blacklist.c |
12636 |
+--- linux-2.6.24.4/drivers/acpi/blacklist.c 2008-03-24 14:49:18.000000000 -0400 |
12637 |
++++ linux-2.6.24.4/drivers/acpi/blacklist.c 2008-03-26 17:56:55.000000000 -0400 |
12638 |
+@@ -73,7 +73,7 @@ static struct acpi_blacklist_item acpi_b |
12639 |
+ {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions, |
12640 |
+ "Bogus PCI routing", 1}, |
12641 |
+ |
12642 |
+- {""} |
12643 |
++ {"", "", 0, 0, 0, all_versions, 0} |
12644 |
+ }; |
12645 |
+ |
12646 |
+ #if CONFIG_ACPI_BLACKLIST_YEAR |
12647 |
+diff -urNp linux-2.6.24.4/drivers/acpi/osl.c linux-2.6.24.4/drivers/acpi/osl.c |
12648 |
+--- linux-2.6.24.4/drivers/acpi/osl.c 2008-03-24 14:49:18.000000000 -0400 |
12649 |
++++ linux-2.6.24.4/drivers/acpi/osl.c 2008-03-26 17:56:55.000000000 -0400 |
12650 |
+@@ -470,6 +470,8 @@ acpi_os_read_memory(acpi_physical_addres |
12651 |
+ void __iomem *virt_addr; |
12652 |
+ |
12653 |
+ virt_addr = ioremap(phys_addr, width); |
12654 |
++ if (!virt_addr) |
12655 |
++ return AE_NO_MEMORY; |
12656 |
+ if (!value) |
12657 |
+ value = &dummy; |
12658 |
+ |
12659 |
+@@ -498,6 +500,8 @@ acpi_os_write_memory(acpi_physical_addre |
12660 |
+ void __iomem *virt_addr; |
12661 |
+ |
12662 |
+ virt_addr = ioremap(phys_addr, width); |
12663 |
++ if (!virt_addr) |
12664 |
++ return AE_NO_MEMORY; |
12665 |
+ |
12666 |
+ switch (width) { |
12667 |
+ case 8: |
12668 |
+@@ -520,7 +524,7 @@ acpi_os_write_memory(acpi_physical_addre |
12669 |
+ |
12670 |
+ acpi_status |
12671 |
+ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, |
12672 |
+- void *value, u32 width) |
12673 |
++ u32 *value, u32 width) |
12674 |
+ { |
12675 |
+ int result, size; |
12676 |
+ |
12677 |
+@@ -592,7 +596,7 @@ static void acpi_os_derive_pci_id_2(acpi |
12678 |
+ acpi_status status; |
12679 |
+ unsigned long temp; |
12680 |
+ acpi_object_type type; |
12681 |
+- u8 tu8; |
12682 |
++ u32 tu8; |
12683 |
+ |
12684 |
+ acpi_get_parent(chandle, &handle); |
12685 |
+ if (handle != rhandle) { |
12686 |
+diff -urNp linux-2.6.24.4/drivers/acpi/processor_core.c linux-2.6.24.4/drivers/acpi/processor_core.c |
12687 |
+--- linux-2.6.24.4/drivers/acpi/processor_core.c 2008-03-24 14:49:18.000000000 -0400 |
12688 |
++++ linux-2.6.24.4/drivers/acpi/processor_core.c 2008-03-26 17:56:55.000000000 -0400 |
12689 |
+@@ -632,7 +632,7 @@ static int __cpuinit acpi_processor_star |
12690 |
+ return 0; |
12691 |
+ } |
12692 |
+ |
12693 |
+- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); |
12694 |
++ BUG_ON(pr->id >= nr_cpu_ids); |
12695 |
+ |
12696 |
+ /* |
12697 |
+ * Buggy BIOS check |
12698 |
+diff -urNp linux-2.6.24.4/drivers/acpi/processor_idle.c linux-2.6.24.4/drivers/acpi/processor_idle.c |
12699 |
+--- linux-2.6.24.4/drivers/acpi/processor_idle.c 2008-03-24 14:49:18.000000000 -0400 |
12700 |
++++ linux-2.6.24.4/drivers/acpi/processor_idle.c 2008-03-26 17:56:55.000000000 -0400 |
12701 |
+@@ -178,7 +178,7 @@ static struct dmi_system_id __cpuinitdat |
12702 |
+ DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), |
12703 |
+ DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, |
12704 |
+ (void *)2}, |
12705 |
+- {}, |
12706 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}, |
12707 |
+ }; |
12708 |
+ |
12709 |
+ static inline u32 ticks_elapsed(u32 t1, u32 t2) |
12710 |
+diff -urNp linux-2.6.24.4/drivers/acpi/sleep/main.c linux-2.6.24.4/drivers/acpi/sleep/main.c |
12711 |
+--- linux-2.6.24.4/drivers/acpi/sleep/main.c 2008-03-24 14:49:18.000000000 -0400 |
12712 |
++++ linux-2.6.24.4/drivers/acpi/sleep/main.c 2008-03-26 17:56:55.000000000 -0400 |
12713 |
+@@ -224,7 +224,7 @@ static struct dmi_system_id __initdata a |
12714 |
+ .ident = "Toshiba Satellite 4030cdt", |
12715 |
+ .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),}, |
12716 |
+ }, |
12717 |
+- {}, |
12718 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}, |
12719 |
+ }; |
12720 |
+ #endif /* CONFIG_SUSPEND */ |
12721 |
+ |
12722 |
+diff -urNp linux-2.6.24.4/drivers/acpi/tables/tbfadt.c linux-2.6.24.4/drivers/acpi/tables/tbfadt.c |
12723 |
+--- linux-2.6.24.4/drivers/acpi/tables/tbfadt.c 2008-03-24 14:49:18.000000000 -0400 |
12724 |
++++ linux-2.6.24.4/drivers/acpi/tables/tbfadt.c 2008-03-26 17:56:55.000000000 -0400 |
12725 |
+@@ -48,7 +48,7 @@ |
12726 |
+ ACPI_MODULE_NAME("tbfadt") |
12727 |
+ |
12728 |
+ /* Local prototypes */ |
12729 |
+-static void inline |
12730 |
++static inline void |
12731 |
+ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
12732 |
+ u8 bit_width, u64 address); |
12733 |
+ |
12734 |
+@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t |
12735 |
+ * |
12736 |
+ ******************************************************************************/ |
12737 |
+ |
12738 |
+-static void inline |
12739 |
++static inline void |
12740 |
+ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
12741 |
+ u8 bit_width, u64 address) |
12742 |
+ { |
12743 |
+diff -urNp linux-2.6.24.4/drivers/acpi/tables/tbxface.c linux-2.6.24.4/drivers/acpi/tables/tbxface.c |
12744 |
+--- linux-2.6.24.4/drivers/acpi/tables/tbxface.c 2008-03-24 14:49:18.000000000 -0400 |
12745 |
++++ linux-2.6.24.4/drivers/acpi/tables/tbxface.c 2008-03-26 17:56:55.000000000 -0400 |
12746 |
+@@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespac |
12747 |
+ acpi_tb_print_table_header(0, table); |
12748 |
+ |
12749 |
+ if (no_auto_ssdt == 0) { |
12750 |
+- printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\""); |
12751 |
++ printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n"); |
12752 |
+ } |
12753 |
+ } |
12754 |
+ |
12755 |
+diff -urNp linux-2.6.24.4/drivers/ata/ahci.c linux-2.6.24.4/drivers/ata/ahci.c |
12756 |
+--- linux-2.6.24.4/drivers/ata/ahci.c 2008-03-24 14:49:18.000000000 -0400 |
12757 |
++++ linux-2.6.24.4/drivers/ata/ahci.c 2008-03-26 17:56:55.000000000 -0400 |
12758 |
+@@ -563,7 +563,7 @@ static const struct pci_device_id ahci_p |
12759 |
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
12760 |
+ PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, |
12761 |
+ |
12762 |
+- { } /* terminate list */ |
12763 |
++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ |
12764 |
+ }; |
12765 |
+ |
12766 |
+ |
12767 |
+diff -urNp linux-2.6.24.4/drivers/ata/ata_piix.c linux-2.6.24.4/drivers/ata/ata_piix.c |
12768 |
+--- linux-2.6.24.4/drivers/ata/ata_piix.c 2008-03-24 14:49:18.000000000 -0400 |
12769 |
++++ linux-2.6.24.4/drivers/ata/ata_piix.c 2008-03-26 17:56:55.000000000 -0400 |
12770 |
+@@ -264,7 +264,7 @@ static const struct pci_device_id piix_p |
12771 |
+ /* SATA Controller IDE (Tolapai) */ |
12772 |
+ { 0x8086, 0x5028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, tolapai_sata_ahci }, |
12773 |
+ |
12774 |
+- { } /* terminate list */ |
12775 |
++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ |
12776 |
+ }; |
12777 |
+ |
12778 |
+ static struct pci_driver piix_pci_driver = { |
12779 |
+@@ -701,7 +701,7 @@ static const struct ich_laptop ich_lapto |
12780 |
+ { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ |
12781 |
+ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ |
12782 |
+ /* end marker */ |
12783 |
+- { 0, } |
12784 |
++ { 0, 0, 0 } |
12785 |
+ }; |
12786 |
+ |
12787 |
+ /** |
12788 |
+@@ -1097,7 +1097,7 @@ static int piix_broken_suspend(void) |
12789 |
+ }, |
12790 |
+ }, |
12791 |
+ |
12792 |
+- { } /* terminate list */ |
12793 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */ |
12794 |
+ }; |
12795 |
+ static const char *oemstrs[] = { |
12796 |
+ "Tecra M3,", |
12797 |
+diff -urNp linux-2.6.24.4/drivers/ata/libata-core.c linux-2.6.24.4/drivers/ata/libata-core.c |
12798 |
+--- linux-2.6.24.4/drivers/ata/libata-core.c 2008-03-24 14:49:18.000000000 -0400 |
12799 |
++++ linux-2.6.24.4/drivers/ata/libata-core.c 2008-03-26 17:56:55.000000000 -0400 |
12800 |
+@@ -489,7 +489,7 @@ static const struct ata_xfer_ent { |
12801 |
+ { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 }, |
12802 |
+ { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 }, |
12803 |
+ { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 }, |
12804 |
+- { -1, }, |
12805 |
++ { -1, 0, 0 }, |
12806 |
+ }; |
12807 |
+ |
12808 |
+ /** |
12809 |
+@@ -2814,7 +2814,7 @@ static const struct ata_timing ata_timin |
12810 |
+ |
12811 |
+ /* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */ |
12812 |
+ |
12813 |
+- { 0xFF } |
12814 |
++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 } |
12815 |
+ }; |
12816 |
+ |
12817 |
+ #define ENOUGH(v, unit) (((v)-1)/(unit)+1) |
12818 |
+@@ -4178,7 +4178,7 @@ static const struct ata_blacklist_entry |
12819 |
+ { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, }, |
12820 |
+ |
12821 |
+ /* End Marker */ |
12822 |
+- { } |
12823 |
++ { NULL, NULL, 0 } |
12824 |
+ }; |
12825 |
+ |
12826 |
+ static int strn_pattern_cmp(const char *patt, const char *name, int wildchar) |
12827 |
+diff -urNp linux-2.6.24.4/drivers/char/agp/frontend.c linux-2.6.24.4/drivers/char/agp/frontend.c |
12828 |
+--- linux-2.6.24.4/drivers/char/agp/frontend.c 2008-03-24 14:49:18.000000000 -0400 |
12829 |
++++ linux-2.6.24.4/drivers/char/agp/frontend.c 2008-03-26 17:56:55.000000000 -0400 |
12830 |
+@@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag |
12831 |
+ if (copy_from_user(&reserve, arg, sizeof(struct agp_region))) |
12832 |
+ return -EFAULT; |
12833 |
+ |
12834 |
+- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment)) |
12835 |
++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv)) |
12836 |
+ return -EFAULT; |
12837 |
+ |
12838 |
+ client = agp_find_client_by_pid(reserve.pid); |
12839 |
+diff -urNp linux-2.6.24.4/drivers/char/agp/intel-agp.c linux-2.6.24.4/drivers/char/agp/intel-agp.c |
12840 |
+--- linux-2.6.24.4/drivers/char/agp/intel-agp.c 2008-03-24 14:49:18.000000000 -0400 |
12841 |
++++ linux-2.6.24.4/drivers/char/agp/intel-agp.c 2008-03-26 17:56:55.000000000 -0400 |
12842 |
+@@ -2080,7 +2080,7 @@ static struct pci_device_id agp_intel_pc |
12843 |
+ ID(PCI_DEVICE_ID_INTEL_G33_HB), |
12844 |
+ ID(PCI_DEVICE_ID_INTEL_Q35_HB), |
12845 |
+ ID(PCI_DEVICE_ID_INTEL_Q33_HB), |
12846 |
+- { } |
12847 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
12848 |
+ }; |
12849 |
+ |
12850 |
+ MODULE_DEVICE_TABLE(pci, agp_intel_pci_table); |
12851 |
+diff -urNp linux-2.6.24.4/drivers/char/drm/drm_pciids.h linux-2.6.24.4/drivers/char/drm/drm_pciids.h |
12852 |
+--- linux-2.6.24.4/drivers/char/drm/drm_pciids.h 2008-03-24 14:49:18.000000000 -0400 |
12853 |
++++ linux-2.6.24.4/drivers/char/drm/drm_pciids.h 2008-03-26 17:56:55.000000000 -0400 |
12854 |
+@@ -249,7 +249,7 @@ |
12855 |
+ {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
12856 |
+ {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
12857 |
+ {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
12858 |
+- {0, 0, 0} |
12859 |
++ {0, 0, 0, 0, 0, 0, 0 } |
12860 |
+ |
12861 |
+ #define i830_PCI_IDS \ |
12862 |
+ {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
12863 |
+diff -urNp linux-2.6.24.4/drivers/char/hpet.c linux-2.6.24.4/drivers/char/hpet.c |
12864 |
+--- linux-2.6.24.4/drivers/char/hpet.c 2008-03-24 14:49:18.000000000 -0400 |
12865 |
++++ linux-2.6.24.4/drivers/char/hpet.c 2008-03-26 17:56:55.000000000 -0400 |
12866 |
+@@ -1028,7 +1028,7 @@ static struct acpi_driver hpet_acpi_driv |
12867 |
+ }, |
12868 |
+ }; |
12869 |
+ |
12870 |
+-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops }; |
12871 |
++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL }; |
12872 |
+ |
12873 |
+ static int __init hpet_init(void) |
12874 |
+ { |
12875 |
+diff -urNp linux-2.6.24.4/drivers/char/keyboard.c linux-2.6.24.4/drivers/char/keyboard.c |
12876 |
+--- linux-2.6.24.4/drivers/char/keyboard.c 2008-03-24 14:49:18.000000000 -0400 |
12877 |
++++ linux-2.6.24.4/drivers/char/keyboard.c 2008-03-26 17:56:55.000000000 -0400 |
12878 |
+@@ -631,6 +631,16 @@ static void k_spec(struct vc_data *vc, u |
12879 |
+ kbd->kbdmode == VC_MEDIUMRAW) && |
12880 |
+ value != KVAL(K_SAK)) |
12881 |
+ return; /* SAK is allowed even in raw mode */ |
12882 |
++ |
12883 |
++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP) |
12884 |
++ { |
12885 |
++ void *func = fn_handler[value]; |
12886 |
++ if (func == fn_show_state || func == fn_show_ptregs || |
12887 |
++ func == fn_show_mem) |
12888 |
++ return; |
12889 |
++ } |
12890 |
++#endif |
12891 |
++ |
12892 |
+ fn_handler[value](vc); |
12893 |
+ } |
12894 |
+ |
12895 |
+@@ -1385,7 +1395,7 @@ static const struct input_device_id kbd_ |
12896 |
+ .evbit = { BIT_MASK(EV_SND) }, |
12897 |
+ }, |
12898 |
+ |
12899 |
+- { }, /* Terminating entry */ |
12900 |
++ { 0 }, /* Terminating entry */ |
12901 |
+ }; |
12902 |
+ |
12903 |
+ MODULE_DEVICE_TABLE(input, kbd_ids); |
12904 |
+diff -urNp linux-2.6.24.4/drivers/char/mem.c linux-2.6.24.4/drivers/char/mem.c |
12905 |
+--- linux-2.6.24.4/drivers/char/mem.c 2008-03-24 14:49:18.000000000 -0400 |
12906 |
++++ linux-2.6.24.4/drivers/char/mem.c 2008-03-26 17:56:55.000000000 -0400 |
12907 |
+@@ -26,6 +26,7 @@ |
12908 |
+ #include <linux/bootmem.h> |
12909 |
+ #include <linux/splice.h> |
12910 |
+ #include <linux/pfn.h> |
12911 |
++#include <linux/grsecurity.h> |
12912 |
+ |
12913 |
+ #include <asm/uaccess.h> |
12914 |
+ #include <asm/io.h> |
12915 |
+@@ -34,6 +35,10 @@ |
12916 |
+ # include <linux/efi.h> |
12917 |
+ #endif |
12918 |
+ |
12919 |
++#ifdef CONFIG_GRKERNSEC |
12920 |
++extern struct file_operations grsec_fops; |
12921 |
++#endif |
12922 |
++ |
12923 |
+ /* |
12924 |
+ * Architectures vary in how they handle caching for addresses |
12925 |
+ * outside of main memory. |
12926 |
+@@ -180,6 +185,11 @@ static ssize_t write_mem(struct file * f |
12927 |
+ if (!valid_phys_addr_range(p, count)) |
12928 |
+ return -EFAULT; |
12929 |
+ |
12930 |
++#ifdef CONFIG_GRKERNSEC_KMEM |
12931 |
++ gr_handle_mem_write(); |
12932 |
++ return -EPERM; |
12933 |
++#endif |
12934 |
++ |
12935 |
+ written = 0; |
12936 |
+ |
12937 |
+ #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED |
12938 |
+@@ -281,6 +291,11 @@ static int mmap_mem(struct file * file, |
12939 |
+ if (!private_mapping_ok(vma)) |
12940 |
+ return -ENOSYS; |
12941 |
+ |
12942 |
++#ifdef CONFIG_GRKERNSEC_KMEM |
12943 |
++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma)) |
12944 |
++ return -EPERM; |
12945 |
++#endif |
12946 |
++ |
12947 |
+ vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, |
12948 |
+ size, |
12949 |
+ vma->vm_page_prot); |
12950 |
+@@ -512,6 +527,11 @@ static ssize_t write_kmem(struct file * |
12951 |
+ ssize_t written; |
12952 |
+ char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ |
12953 |
+ |
12954 |
++#ifdef CONFIG_GRKERNSEC_KMEM |
12955 |
++ gr_handle_kmem_write(); |
12956 |
++ return -EPERM; |
12957 |
++#endif |
12958 |
++ |
12959 |
+ if (p < (unsigned long) high_memory) { |
12960 |
+ |
12961 |
+ wrote = count; |
12962 |
+@@ -714,6 +734,16 @@ static loff_t memory_lseek(struct file * |
12963 |
+ |
12964 |
+ static int open_port(struct inode * inode, struct file * filp) |
12965 |
+ { |
12966 |
++#ifdef CONFIG_GRKERNSEC_KMEM |
12967 |
++ gr_handle_open_port(); |
12968 |
++ return -EPERM; |
12969 |
++#endif |
12970 |
++ |
12971 |
++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; |
12972 |
++} |
12973 |
++ |
12974 |
++static int open_mem(struct inode * inode, struct file * filp) |
12975 |
++{ |
12976 |
+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; |
12977 |
+ } |
12978 |
+ |
12979 |
+@@ -721,7 +751,6 @@ static int open_port(struct inode * inod |
12980 |
+ #define full_lseek null_lseek |
12981 |
+ #define write_zero write_null |
12982 |
+ #define read_full read_zero |
12983 |
+-#define open_mem open_port |
12984 |
+ #define open_kmem open_mem |
12985 |
+ #define open_oldmem open_mem |
12986 |
+ |
12987 |
+@@ -854,6 +883,11 @@ static int memory_open(struct inode * in |
12988 |
+ filp->f_op = &oldmem_fops; |
12989 |
+ break; |
12990 |
+ #endif |
12991 |
++#ifdef CONFIG_GRKERNSEC |
12992 |
++ case 13: |
12993 |
++ filp->f_op = &grsec_fops; |
12994 |
++ break; |
12995 |
++#endif |
12996 |
+ default: |
12997 |
+ return -ENXIO; |
12998 |
+ } |
12999 |
+@@ -886,6 +920,9 @@ static const struct { |
13000 |
+ #ifdef CONFIG_CRASH_DUMP |
13001 |
+ {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops}, |
13002 |
+ #endif |
13003 |
++#ifdef CONFIG_GRKERNSEC |
13004 |
++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops}, |
13005 |
++#endif |
13006 |
+ }; |
13007 |
+ |
13008 |
+ static struct class *mem_class; |
13009 |
+diff -urNp linux-2.6.24.4/drivers/char/nvram.c linux-2.6.24.4/drivers/char/nvram.c |
13010 |
+--- linux-2.6.24.4/drivers/char/nvram.c 2008-03-24 14:49:18.000000000 -0400 |
13011 |
++++ linux-2.6.24.4/drivers/char/nvram.c 2008-03-26 17:56:55.000000000 -0400 |
13012 |
+@@ -430,7 +430,10 @@ static const struct file_operations nvra |
13013 |
+ static struct miscdevice nvram_dev = { |
13014 |
+ NVRAM_MINOR, |
13015 |
+ "nvram", |
13016 |
+- &nvram_fops |
13017 |
++ &nvram_fops, |
13018 |
++ {NULL, NULL}, |
13019 |
++ NULL, |
13020 |
++ NULL |
13021 |
+ }; |
13022 |
+ |
13023 |
+ static int __init |
13024 |
+diff -urNp linux-2.6.24.4/drivers/char/random.c linux-2.6.24.4/drivers/char/random.c |
13025 |
+--- linux-2.6.24.4/drivers/char/random.c 2008-03-24 14:49:18.000000000 -0400 |
13026 |
++++ linux-2.6.24.4/drivers/char/random.c 2008-03-26 17:56:55.000000000 -0400 |
13027 |
+@@ -248,8 +248,13 @@ |
13028 |
+ /* |
13029 |
+ * Configuration information |
13030 |
+ */ |
13031 |
++#ifdef CONFIG_GRKERNSEC_RANDNET |
13032 |
++#define INPUT_POOL_WORDS 512 |
13033 |
++#define OUTPUT_POOL_WORDS 128 |
13034 |
++#else |
13035 |
+ #define INPUT_POOL_WORDS 128 |
13036 |
+ #define OUTPUT_POOL_WORDS 32 |
13037 |
++#endif |
13038 |
+ #define SEC_XFER_SIZE 512 |
13039 |
+ |
13040 |
+ /* |
13041 |
+@@ -286,10 +291,17 @@ static struct poolinfo { |
13042 |
+ int poolwords; |
13043 |
+ int tap1, tap2, tap3, tap4, tap5; |
13044 |
+ } poolinfo_table[] = { |
13045 |
++#ifdef CONFIG_GRKERNSEC_RANDNET |
13046 |
++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */ |
13047 |
++ { 512, 411, 308, 208, 104, 1 }, |
13048 |
++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */ |
13049 |
++ { 128, 103, 76, 51, 25, 1 }, |
13050 |
++#else |
13051 |
+ /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */ |
13052 |
+ { 128, 103, 76, 51, 25, 1 }, |
13053 |
+ /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */ |
13054 |
+ { 32, 26, 20, 14, 7, 1 }, |
13055 |
++#endif |
13056 |
+ #if 0 |
13057 |
+ /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ |
13058 |
+ { 2048, 1638, 1231, 819, 411, 1 }, |
13059 |
+@@ -1172,7 +1184,7 @@ EXPORT_SYMBOL(generate_random_uuid); |
13060 |
+ #include <linux/sysctl.h> |
13061 |
+ |
13062 |
+ static int min_read_thresh = 8, min_write_thresh; |
13063 |
+-static int max_read_thresh = INPUT_POOL_WORDS * 32; |
13064 |
++static int max_read_thresh = OUTPUT_POOL_WORDS * 32; |
13065 |
+ static int max_write_thresh = INPUT_POOL_WORDS * 32; |
13066 |
+ static char sysctl_bootid[16]; |
13067 |
+ |
13068 |
+diff -urNp linux-2.6.24.4/drivers/char/vt_ioctl.c linux-2.6.24.4/drivers/char/vt_ioctl.c |
13069 |
+--- linux-2.6.24.4/drivers/char/vt_ioctl.c 2008-03-24 14:49:18.000000000 -0400 |
13070 |
++++ linux-2.6.24.4/drivers/char/vt_ioctl.c 2008-03-26 17:56:55.000000000 -0400 |
13071 |
+@@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __ |
13072 |
+ case KDSKBENT: |
13073 |
+ if (!perm) |
13074 |
+ return -EPERM; |
13075 |
++ |
13076 |
++#ifdef CONFIG_GRKERNSEC |
13077 |
++ if (!capable(CAP_SYS_TTY_CONFIG)) |
13078 |
++ return -EPERM; |
13079 |
++#endif |
13080 |
++ |
13081 |
+ if (!i && v == K_NOSUCHMAP) { |
13082 |
+ /* deallocate map */ |
13083 |
+ key_map = key_maps[s]; |
13084 |
+@@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry |
13085 |
+ goto reterr; |
13086 |
+ } |
13087 |
+ |
13088 |
++#ifdef CONFIG_GRKERNSEC |
13089 |
++ if (!capable(CAP_SYS_TTY_CONFIG)) { |
13090 |
++ ret = -EPERM; |
13091 |
++ goto reterr; |
13092 |
++ } |
13093 |
++#endif |
13094 |
++ |
13095 |
+ q = func_table[i]; |
13096 |
+ first_free = funcbufptr + (funcbufsize - funcbufleft); |
13097 |
+ for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) |
13098 |
+diff -urNp linux-2.6.24.4/drivers/edac/edac_core.h linux-2.6.24.4/drivers/edac/edac_core.h |
13099 |
+--- linux-2.6.24.4/drivers/edac/edac_core.h 2008-03-24 14:49:18.000000000 -0400 |
13100 |
++++ linux-2.6.24.4/drivers/edac/edac_core.h 2008-03-26 17:56:55.000000000 -0400 |
13101 |
+@@ -86,11 +86,11 @@ extern int edac_debug_level; |
13102 |
+ |
13103 |
+ #else /* !CONFIG_EDAC_DEBUG */ |
13104 |
+ |
13105 |
+-#define debugf0( ... ) |
13106 |
+-#define debugf1( ... ) |
13107 |
+-#define debugf2( ... ) |
13108 |
+-#define debugf3( ... ) |
13109 |
+-#define debugf4( ... ) |
13110 |
++#define debugf0( ... ) do {} while (0) |
13111 |
++#define debugf1( ... ) do {} while (0) |
13112 |
++#define debugf2( ... ) do {} while (0) |
13113 |
++#define debugf3( ... ) do {} while (0) |
13114 |
++#define debugf4( ... ) do {} while (0) |
13115 |
+ |
13116 |
+ #endif /* !CONFIG_EDAC_DEBUG */ |
13117 |
+ |
13118 |
+diff -urNp linux-2.6.24.4/drivers/firmware/dmi_scan.c linux-2.6.24.4/drivers/firmware/dmi_scan.c |
13119 |
+--- linux-2.6.24.4/drivers/firmware/dmi_scan.c 2008-03-24 14:49:18.000000000 -0400 |
13120 |
++++ linux-2.6.24.4/drivers/firmware/dmi_scan.c 2008-03-26 17:56:55.000000000 -0400 |
13121 |
+@@ -318,21 +318,19 @@ void __init dmi_scan_machine(void) |
13122 |
+ } |
13123 |
+ } |
13124 |
+ else { |
13125 |
+- /* |
13126 |
+- * no iounmap() for that ioremap(); it would be a no-op, but |
13127 |
+- * it's so early in setup that sucker gets confused into doing |
13128 |
+- * what it shouldn't if we actually call it. |
13129 |
+- */ |
13130 |
+ p = dmi_ioremap(0xF0000, 0x10000); |
13131 |
+ if (p == NULL) |
13132 |
+ goto out; |
13133 |
+ |
13134 |
+ for (q = p; q < p + 0x10000; q += 16) { |
13135 |
+ rc = dmi_present(q); |
13136 |
+- if (!rc) { |
13137 |
+- dmi_available = 1; |
13138 |
+- return; |
13139 |
+- } |
13140 |
++ if (!rc) |
13141 |
++ break; |
13142 |
++ } |
13143 |
++ dmi_iounmap(p, 0x10000); |
13144 |
++ if (!rc) { |
13145 |
++ dmi_available = 1; |
13146 |
++ return; |
13147 |
+ } |
13148 |
+ } |
13149 |
+ out: printk(KERN_INFO "DMI not present or invalid.\n"); |
13150 |
+diff -urNp linux-2.6.24.4/drivers/hwmon/fscpos.c linux-2.6.24.4/drivers/hwmon/fscpos.c |
13151 |
+--- linux-2.6.24.4/drivers/hwmon/fscpos.c 2008-03-24 14:49:18.000000000 -0400 |
13152 |
++++ linux-2.6.24.4/drivers/hwmon/fscpos.c 2008-03-26 17:56:55.000000000 -0400 |
13153 |
+@@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client |
13154 |
+ unsigned long v = simple_strtoul(buf, NULL, 10); |
13155 |
+ |
13156 |
+ /* Range: 0..255 */ |
13157 |
+- if (v < 0) v = 0; |
13158 |
+ if (v > 255) v = 255; |
13159 |
+ |
13160 |
+ mutex_lock(&data->update_lock); |
13161 |
+diff -urNp linux-2.6.24.4/drivers/hwmon/k8temp.c linux-2.6.24.4/drivers/hwmon/k8temp.c |
13162 |
+--- linux-2.6.24.4/drivers/hwmon/k8temp.c 2008-03-24 14:49:18.000000000 -0400 |
13163 |
++++ linux-2.6.24.4/drivers/hwmon/k8temp.c 2008-03-26 17:56:55.000000000 -0400 |
13164 |
+@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n |
13165 |
+ |
13166 |
+ static struct pci_device_id k8temp_ids[] = { |
13167 |
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, |
13168 |
+- { 0 }, |
13169 |
++ { 0, 0, 0, 0, 0, 0, 0 }, |
13170 |
+ }; |
13171 |
+ |
13172 |
+ MODULE_DEVICE_TABLE(pci, k8temp_ids); |
13173 |
+diff -urNp linux-2.6.24.4/drivers/hwmon/sis5595.c linux-2.6.24.4/drivers/hwmon/sis5595.c |
13174 |
+--- linux-2.6.24.4/drivers/hwmon/sis5595.c 2008-03-24 14:49:18.000000000 -0400 |
13175 |
++++ linux-2.6.24.4/drivers/hwmon/sis5595.c 2008-03-26 17:56:55.000000000 -0400 |
13176 |
+@@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda |
13177 |
+ |
13178 |
+ static struct pci_device_id sis5595_pci_ids[] = { |
13179 |
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, |
13180 |
+- { 0, } |
13181 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13182 |
+ }; |
13183 |
+ |
13184 |
+ MODULE_DEVICE_TABLE(pci, sis5595_pci_ids); |
13185 |
+diff -urNp linux-2.6.24.4/drivers/hwmon/thmc50.c linux-2.6.24.4/drivers/hwmon/thmc50.c |
13186 |
+--- linux-2.6.24.4/drivers/hwmon/thmc50.c 2008-03-24 14:49:18.000000000 -0400 |
13187 |
++++ linux-2.6.24.4/drivers/hwmon/thmc50.c 2008-03-26 17:56:55.000000000 -0400 |
13188 |
+@@ -52,9 +52,9 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "L |
13189 |
+ */ |
13190 |
+ #define THMC50_REG_INTR 0x41 |
13191 |
+ |
13192 |
+-const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; |
13193 |
+-const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; |
13194 |
+-const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; |
13195 |
++static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; |
13196 |
++static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; |
13197 |
++static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; |
13198 |
+ |
13199 |
+ #define THMC50_REG_CONF_nFANOFF 0x20 |
13200 |
+ |
13201 |
+diff -urNp linux-2.6.24.4/drivers/hwmon/via686a.c linux-2.6.24.4/drivers/hwmon/via686a.c |
13202 |
+--- linux-2.6.24.4/drivers/hwmon/via686a.c 2008-03-24 14:49:18.000000000 -0400 |
13203 |
++++ linux-2.6.24.4/drivers/hwmon/via686a.c 2008-03-26 17:56:55.000000000 -0400 |
13204 |
+@@ -740,7 +740,7 @@ static struct via686a_data *via686a_upda |
13205 |
+ |
13206 |
+ static struct pci_device_id via686a_pci_ids[] = { |
13207 |
+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) }, |
13208 |
+- { 0, } |
13209 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13210 |
+ }; |
13211 |
+ |
13212 |
+ MODULE_DEVICE_TABLE(pci, via686a_pci_ids); |
13213 |
+diff -urNp linux-2.6.24.4/drivers/hwmon/vt8231.c linux-2.6.24.4/drivers/hwmon/vt8231.c |
13214 |
+--- linux-2.6.24.4/drivers/hwmon/vt8231.c 2008-03-24 14:49:18.000000000 -0400 |
13215 |
++++ linux-2.6.24.4/drivers/hwmon/vt8231.c 2008-03-26 17:56:55.000000000 -0400 |
13216 |
+@@ -662,7 +662,7 @@ static struct platform_driver vt8231_dri |
13217 |
+ |
13218 |
+ static struct pci_device_id vt8231_pci_ids[] = { |
13219 |
+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) }, |
13220 |
+- { 0, } |
13221 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13222 |
+ }; |
13223 |
+ |
13224 |
+ MODULE_DEVICE_TABLE(pci, vt8231_pci_ids); |
13225 |
+diff -urNp linux-2.6.24.4/drivers/hwmon/w83791d.c linux-2.6.24.4/drivers/hwmon/w83791d.c |
13226 |
+--- linux-2.6.24.4/drivers/hwmon/w83791d.c 2008-03-24 14:49:18.000000000 -0400 |
13227 |
++++ linux-2.6.24.4/drivers/hwmon/w83791d.c 2008-03-26 17:56:55.000000000 -0400 |
13228 |
+@@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct |
13229 |
+ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind); |
13230 |
+ static int w83791d_detach_client(struct i2c_client *client); |
13231 |
+ |
13232 |
+-static int w83791d_read(struct i2c_client *client, u8 register); |
13233 |
+-static int w83791d_write(struct i2c_client *client, u8 register, u8 value); |
13234 |
++static int w83791d_read(struct i2c_client *client, u8 reg); |
13235 |
++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value); |
13236 |
+ static struct w83791d_data *w83791d_update_device(struct device *dev); |
13237 |
+ |
13238 |
+ #ifdef DEBUG |
13239 |
+diff -urNp linux-2.6.24.4/drivers/i2c/busses/i2c-i801.c linux-2.6.24.4/drivers/i2c/busses/i2c-i801.c |
13240 |
+--- linux-2.6.24.4/drivers/i2c/busses/i2c-i801.c 2008-03-24 14:49:18.000000000 -0400 |
13241 |
++++ linux-2.6.24.4/drivers/i2c/busses/i2c-i801.c 2008-03-26 17:56:55.000000000 -0400 |
13242 |
+@@ -545,7 +545,7 @@ static struct pci_device_id i801_ids[] = |
13243 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, |
13244 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) }, |
13245 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) }, |
13246 |
+- { 0, } |
13247 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13248 |
+ }; |
13249 |
+ |
13250 |
+ MODULE_DEVICE_TABLE (pci, i801_ids); |
13251 |
+diff -urNp linux-2.6.24.4/drivers/i2c/busses/i2c-i810.c linux-2.6.24.4/drivers/i2c/busses/i2c-i810.c |
13252 |
+--- linux-2.6.24.4/drivers/i2c/busses/i2c-i810.c 2008-03-24 14:49:18.000000000 -0400 |
13253 |
++++ linux-2.6.24.4/drivers/i2c/busses/i2c-i810.c 2008-03-26 17:56:55.000000000 -0400 |
13254 |
+@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _ |
13255 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) }, |
13256 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) }, |
13257 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) }, |
13258 |
+- { 0, }, |
13259 |
++ { 0, 0, 0, 0, 0, 0, 0 }, |
13260 |
+ }; |
13261 |
+ |
13262 |
+ MODULE_DEVICE_TABLE (pci, i810_ids); |
13263 |
+diff -urNp linux-2.6.24.4/drivers/i2c/busses/i2c-piix4.c linux-2.6.24.4/drivers/i2c/busses/i2c-piix4.c |
13264 |
+--- linux-2.6.24.4/drivers/i2c/busses/i2c-piix4.c 2008-03-24 14:49:18.000000000 -0400 |
13265 |
++++ linux-2.6.24.4/drivers/i2c/busses/i2c-piix4.c 2008-03-26 17:56:55.000000000 -0400 |
13266 |
+@@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat |
13267 |
+ .ident = "IBM", |
13268 |
+ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, |
13269 |
+ }, |
13270 |
+- { }, |
13271 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }, |
13272 |
+ }; |
13273 |
+ |
13274 |
+ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, |
13275 |
+@@ -411,7 +411,7 @@ static struct pci_device_id piix4_ids[] |
13276 |
+ .driver_data = 3 }, |
13277 |
+ { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3), |
13278 |
+ .driver_data = 0 }, |
13279 |
+- { 0, } |
13280 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13281 |
+ }; |
13282 |
+ |
13283 |
+ MODULE_DEVICE_TABLE (pci, piix4_ids); |
13284 |
+diff -urNp linux-2.6.24.4/drivers/i2c/busses/i2c-sis630.c linux-2.6.24.4/drivers/i2c/busses/i2c-sis630.c |
13285 |
+--- linux-2.6.24.4/drivers/i2c/busses/i2c-sis630.c 2008-03-24 14:49:18.000000000 -0400 |
13286 |
++++ linux-2.6.24.4/drivers/i2c/busses/i2c-sis630.c 2008-03-26 17:56:56.000000000 -0400 |
13287 |
+@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter |
13288 |
+ static struct pci_device_id sis630_ids[] __devinitdata = { |
13289 |
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, |
13290 |
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) }, |
13291 |
+- { 0, } |
13292 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13293 |
+ }; |
13294 |
+ |
13295 |
+ MODULE_DEVICE_TABLE (pci, sis630_ids); |
13296 |
+diff -urNp linux-2.6.24.4/drivers/i2c/busses/i2c-sis96x.c linux-2.6.24.4/drivers/i2c/busses/i2c-sis96x.c |
13297 |
+--- linux-2.6.24.4/drivers/i2c/busses/i2c-sis96x.c 2008-03-24 14:49:18.000000000 -0400 |
13298 |
++++ linux-2.6.24.4/drivers/i2c/busses/i2c-sis96x.c 2008-03-26 17:56:56.000000000 -0400 |
13299 |
+@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter |
13300 |
+ |
13301 |
+ static struct pci_device_id sis96x_ids[] = { |
13302 |
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) }, |
13303 |
+- { 0, } |
13304 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13305 |
+ }; |
13306 |
+ |
13307 |
+ MODULE_DEVICE_TABLE (pci, sis96x_ids); |
13308 |
+diff -urNp linux-2.6.24.4/drivers/ide/ide-cd.c linux-2.6.24.4/drivers/ide/ide-cd.c |
13309 |
+--- linux-2.6.24.4/drivers/ide/ide-cd.c 2008-03-24 14:49:18.000000000 -0400 |
13310 |
++++ linux-2.6.24.4/drivers/ide/ide-cd.c 2008-03-26 17:56:56.000000000 -0400 |
13311 |
+@@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_ |
13312 |
+ sector &= ~(bio_sectors -1); |
13313 |
+ valid = (sector - failed_command->sector) << 9; |
13314 |
+ |
13315 |
+- if (valid < 0) |
13316 |
+- valid = 0; |
13317 |
+ if (sector < get_capacity(info->disk) && |
13318 |
+ drive->probed_capacity - sector < 4 * 75) { |
13319 |
+ set_capacity(info->disk, sector); |
13320 |
+diff -urNp linux-2.6.24.4/drivers/ieee1394/dv1394.c linux-2.6.24.4/drivers/ieee1394/dv1394.c |
13321 |
+--- linux-2.6.24.4/drivers/ieee1394/dv1394.c 2008-03-24 14:49:18.000000000 -0400 |
13322 |
++++ linux-2.6.24.4/drivers/ieee1394/dv1394.c 2008-03-26 17:56:56.000000000 -0400 |
13323 |
+@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c |
13324 |
+ based upon DIF section and sequence |
13325 |
+ */ |
13326 |
+ |
13327 |
+-static void inline |
13328 |
++static inline void |
13329 |
+ frame_put_packet (struct frame *f, struct packet *p) |
13330 |
+ { |
13331 |
+ int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */ |
13332 |
+@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c |
13333 |
+ /* default SYT offset is 3 cycles */ |
13334 |
+ init->syt_offset = 3; |
13335 |
+ |
13336 |
+- if ( (init->channel > 63) || (init->channel < 0) ) |
13337 |
++ if (init->channel > 63) |
13338 |
+ init->channel = 63; |
13339 |
+ |
13340 |
+ chan_mask = (u64)1 << init->channel; |
13341 |
+@@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_ |
13342 |
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, |
13343 |
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff |
13344 |
+ }, |
13345 |
+- { } |
13346 |
++ { 0, 0, 0, 0, 0, 0 } |
13347 |
+ }; |
13348 |
+ |
13349 |
+ MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table); |
13350 |
+diff -urNp linux-2.6.24.4/drivers/ieee1394/eth1394.c linux-2.6.24.4/drivers/ieee1394/eth1394.c |
13351 |
+--- linux-2.6.24.4/drivers/ieee1394/eth1394.c 2008-03-24 14:49:18.000000000 -0400 |
13352 |
++++ linux-2.6.24.4/drivers/ieee1394/eth1394.c 2008-03-26 17:56:56.000000000 -0400 |
13353 |
+@@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394 |
13354 |
+ .specifier_id = ETHER1394_GASP_SPECIFIER_ID, |
13355 |
+ .version = ETHER1394_GASP_VERSION, |
13356 |
+ }, |
13357 |
+- {} |
13358 |
++ { 0, 0, 0, 0, 0, 0 } |
13359 |
+ }; |
13360 |
+ |
13361 |
+ MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table); |
13362 |
+diff -urNp linux-2.6.24.4/drivers/ieee1394/hosts.c linux-2.6.24.4/drivers/ieee1394/hosts.c |
13363 |
+--- linux-2.6.24.4/drivers/ieee1394/hosts.c 2008-03-24 14:49:18.000000000 -0400 |
13364 |
++++ linux-2.6.24.4/drivers/ieee1394/hosts.c 2008-03-26 17:56:56.000000000 -0400 |
13365 |
+@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso |
13366 |
+ } |
13367 |
+ |
13368 |
+ static struct hpsb_host_driver dummy_driver = { |
13369 |
++ .name = "dummy", |
13370 |
+ .transmit_packet = dummy_transmit_packet, |
13371 |
+ .devctl = dummy_devctl, |
13372 |
+ .isoctl = dummy_isoctl |
13373 |
+diff -urNp linux-2.6.24.4/drivers/ieee1394/ohci1394.c linux-2.6.24.4/drivers/ieee1394/ohci1394.c |
13374 |
+--- linux-2.6.24.4/drivers/ieee1394/ohci1394.c 2008-03-24 14:49:18.000000000 -0400 |
13375 |
++++ linux-2.6.24.4/drivers/ieee1394/ohci1394.c 2008-03-26 17:56:56.000000000 -0400 |
13376 |
+@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_ |
13377 |
+ printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args) |
13378 |
+ |
13379 |
+ /* Module Parameters */ |
13380 |
+-static int phys_dma = 1; |
13381 |
++static int phys_dma; |
13382 |
+ module_param(phys_dma, int, 0444); |
13383 |
+-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1)."); |
13384 |
++MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0)."); |
13385 |
+ |
13386 |
+ static void dma_trm_tasklet(unsigned long data); |
13387 |
+ static void dma_trm_reset(struct dma_trm_ctx *d); |
13388 |
+@@ -3396,7 +3396,7 @@ static struct pci_device_id ohci1394_pci |
13389 |
+ .subvendor = PCI_ANY_ID, |
13390 |
+ .subdevice = PCI_ANY_ID, |
13391 |
+ }, |
13392 |
+- { 0, }, |
13393 |
++ { 0, 0, 0, 0, 0, 0, 0 }, |
13394 |
+ }; |
13395 |
+ |
13396 |
+ MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl); |
13397 |
+diff -urNp linux-2.6.24.4/drivers/ieee1394/raw1394.c linux-2.6.24.4/drivers/ieee1394/raw1394.c |
13398 |
+--- linux-2.6.24.4/drivers/ieee1394/raw1394.c 2008-03-24 14:49:18.000000000 -0400 |
13399 |
++++ linux-2.6.24.4/drivers/ieee1394/raw1394.c 2008-03-26 17:56:56.000000000 -0400 |
13400 |
+@@ -2952,7 +2952,7 @@ static struct ieee1394_device_id raw1394 |
13401 |
+ .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, |
13402 |
+ .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff, |
13403 |
+ .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff}, |
13404 |
+- {} |
13405 |
++ { 0, 0, 0, 0, 0, 0 } |
13406 |
+ }; |
13407 |
+ |
13408 |
+ MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table); |
13409 |
+diff -urNp linux-2.6.24.4/drivers/ieee1394/sbp2.c linux-2.6.24.4/drivers/ieee1394/sbp2.c |
13410 |
+--- linux-2.6.24.4/drivers/ieee1394/sbp2.c 2008-03-24 14:49:18.000000000 -0400 |
13411 |
++++ linux-2.6.24.4/drivers/ieee1394/sbp2.c 2008-03-26 17:56:56.000000000 -0400 |
13412 |
+@@ -274,7 +274,7 @@ static struct ieee1394_device_id sbp2_id |
13413 |
+ .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, |
13414 |
+ .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff, |
13415 |
+ .version = SBP2_SW_VERSION_ENTRY & 0xffffff}, |
13416 |
+- {} |
13417 |
++ { 0, 0, 0, 0, 0, 0 } |
13418 |
+ }; |
13419 |
+ MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table); |
13420 |
+ |
13421 |
+@@ -2078,7 +2078,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot |
13422 |
+ MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME); |
13423 |
+ MODULE_LICENSE("GPL"); |
13424 |
+ |
13425 |
+-static int sbp2_module_init(void) |
13426 |
++static int __init sbp2_module_init(void) |
13427 |
+ { |
13428 |
+ int ret; |
13429 |
+ |
13430 |
+diff -urNp linux-2.6.24.4/drivers/ieee1394/video1394.c linux-2.6.24.4/drivers/ieee1394/video1394.c |
13431 |
+--- linux-2.6.24.4/drivers/ieee1394/video1394.c 2008-03-24 14:49:18.000000000 -0400 |
13432 |
++++ linux-2.6.24.4/drivers/ieee1394/video1394.c 2008-03-26 17:56:56.000000000 -0400 |
13433 |
+@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file |
13434 |
+ if (unlikely(d == NULL)) |
13435 |
+ return -EFAULT; |
13436 |
+ |
13437 |
+- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) { |
13438 |
++ if (unlikely(v.buffer>=d->num_desc - 1)) { |
13439 |
+ PRINT(KERN_ERR, ohci->host->id, |
13440 |
+ "Buffer %d out of range",v.buffer); |
13441 |
+ return -EINVAL; |
13442 |
+@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file |
13443 |
+ if (unlikely(d == NULL)) |
13444 |
+ return -EFAULT; |
13445 |
+ |
13446 |
+- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) { |
13447 |
++ if (unlikely(v.buffer>d->num_desc - 1)) { |
13448 |
+ PRINT(KERN_ERR, ohci->host->id, |
13449 |
+ "Buffer %d out of range",v.buffer); |
13450 |
+ return -EINVAL; |
13451 |
+@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file |
13452 |
+ d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); |
13453 |
+ if (d == NULL) return -EFAULT; |
13454 |
+ |
13455 |
+- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) { |
13456 |
++ if (v.buffer>=d->num_desc - 1) { |
13457 |
+ PRINT(KERN_ERR, ohci->host->id, |
13458 |
+ "Buffer %d out of range",v.buffer); |
13459 |
+ return -EINVAL; |
13460 |
+@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file |
13461 |
+ d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); |
13462 |
+ if (d == NULL) return -EFAULT; |
13463 |
+ |
13464 |
+- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) { |
13465 |
++ if (v.buffer>=d->num_desc-1) { |
13466 |
+ PRINT(KERN_ERR, ohci->host->id, |
13467 |
+ "Buffer %d out of range",v.buffer); |
13468 |
+ return -EINVAL; |
13469 |
+@@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13 |
13470 |
+ .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff, |
13471 |
+ .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff |
13472 |
+ }, |
13473 |
+- { } |
13474 |
++ { 0, 0, 0, 0, 0, 0 } |
13475 |
+ }; |
13476 |
+ |
13477 |
+ MODULE_DEVICE_TABLE(ieee1394, video1394_id_table); |
13478 |
+diff -urNp linux-2.6.24.4/drivers/input/keyboard/atkbd.c linux-2.6.24.4/drivers/input/keyboard/atkbd.c |
13479 |
+--- linux-2.6.24.4/drivers/input/keyboard/atkbd.c 2008-03-24 14:49:18.000000000 -0400 |
13480 |
++++ linux-2.6.24.4/drivers/input/keyboard/atkbd.c 2008-03-26 17:56:56.000000000 -0400 |
13481 |
+@@ -1080,7 +1080,7 @@ static struct serio_device_id atkbd_seri |
13482 |
+ .id = SERIO_ANY, |
13483 |
+ .extra = SERIO_ANY, |
13484 |
+ }, |
13485 |
+- { 0 } |
13486 |
++ { 0, 0, 0, 0 } |
13487 |
+ }; |
13488 |
+ |
13489 |
+ MODULE_DEVICE_TABLE(serio, atkbd_serio_ids); |
13490 |
+diff -urNp linux-2.6.24.4/drivers/input/mouse/lifebook.c linux-2.6.24.4/drivers/input/mouse/lifebook.c |
13491 |
+--- linux-2.6.24.4/drivers/input/mouse/lifebook.c 2008-03-24 14:49:18.000000000 -0400 |
13492 |
++++ linux-2.6.24.4/drivers/input/mouse/lifebook.c 2008-03-26 17:56:56.000000000 -0400 |
13493 |
+@@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo |
13494 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), |
13495 |
+ }, |
13496 |
+ }, |
13497 |
+- { } |
13498 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL} |
13499 |
+ }; |
13500 |
+ |
13501 |
+ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) |
13502 |
+diff -urNp linux-2.6.24.4/drivers/input/mouse/psmouse-base.c linux-2.6.24.4/drivers/input/mouse/psmouse-base.c |
13503 |
+--- linux-2.6.24.4/drivers/input/mouse/psmouse-base.c 2008-03-24 14:49:18.000000000 -0400 |
13504 |
++++ linux-2.6.24.4/drivers/input/mouse/psmouse-base.c 2008-03-26 17:56:56.000000000 -0400 |
13505 |
+@@ -1329,7 +1329,7 @@ static struct serio_device_id psmouse_se |
13506 |
+ .id = SERIO_ANY, |
13507 |
+ .extra = SERIO_ANY, |
13508 |
+ }, |
13509 |
+- { 0 } |
13510 |
++ { 0, 0, 0, 0 } |
13511 |
+ }; |
13512 |
+ |
13513 |
+ MODULE_DEVICE_TABLE(serio, psmouse_serio_ids); |
13514 |
+diff -urNp linux-2.6.24.4/drivers/input/mouse/synaptics.c linux-2.6.24.4/drivers/input/mouse/synaptics.c |
13515 |
+--- linux-2.6.24.4/drivers/input/mouse/synaptics.c 2008-03-24 14:49:18.000000000 -0400 |
13516 |
++++ linux-2.6.24.4/drivers/input/mouse/synaptics.c 2008-03-26 17:56:56.000000000 -0400 |
13517 |
+@@ -417,7 +417,7 @@ static void synaptics_process_packet(str |
13518 |
+ break; |
13519 |
+ case 2: |
13520 |
+ if (SYN_MODEL_PEN(priv->model_id)) |
13521 |
+- ; /* Nothing, treat a pen as a single finger */ |
13522 |
++ break; /* Nothing, treat a pen as a single finger */ |
13523 |
+ break; |
13524 |
+ case 4 ... 15: |
13525 |
+ if (SYN_CAP_PALMDETECT(priv->capabilities)) |
13526 |
+@@ -624,7 +624,7 @@ static const struct dmi_system_id toshib |
13527 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"), |
13528 |
+ }, |
13529 |
+ }, |
13530 |
+- { } |
13531 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
13532 |
+ }; |
13533 |
+ #endif |
13534 |
+ |
13535 |
+diff -urNp linux-2.6.24.4/drivers/input/mousedev.c linux-2.6.24.4/drivers/input/mousedev.c |
13536 |
+--- linux-2.6.24.4/drivers/input/mousedev.c 2008-03-24 14:49:18.000000000 -0400 |
13537 |
++++ linux-2.6.24.4/drivers/input/mousedev.c 2008-03-26 17:56:56.000000000 -0400 |
13538 |
+@@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han |
13539 |
+ |
13540 |
+ #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
13541 |
+ static struct miscdevice psaux_mouse = { |
13542 |
+- PSMOUSE_MINOR, "psaux", &mousedev_fops |
13543 |
++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL |
13544 |
+ }; |
13545 |
+ static int psaux_registered; |
13546 |
+ #endif |
13547 |
+diff -urNp linux-2.6.24.4/drivers/input/serio/i8042-x86ia64io.h linux-2.6.24.4/drivers/input/serio/i8042-x86ia64io.h |
13548 |
+--- linux-2.6.24.4/drivers/input/serio/i8042-x86ia64io.h 2008-03-24 14:49:18.000000000 -0400 |
13549 |
++++ linux-2.6.24.4/drivers/input/serio/i8042-x86ia64io.h 2008-03-26 17:56:56.000000000 -0400 |
13550 |
+@@ -118,7 +118,7 @@ static struct dmi_system_id __initdata i |
13551 |
+ DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"), |
13552 |
+ }, |
13553 |
+ }, |
13554 |
+- { } |
13555 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
13556 |
+ }; |
13557 |
+ |
13558 |
+ /* |
13559 |
+@@ -270,7 +270,7 @@ static struct dmi_system_id __initdata i |
13560 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), |
13561 |
+ }, |
13562 |
+ }, |
13563 |
+- { } |
13564 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
13565 |
+ }; |
13566 |
+ |
13567 |
+ |
13568 |
+diff -urNp linux-2.6.24.4/drivers/input/serio/serio_raw.c linux-2.6.24.4/drivers/input/serio/serio_raw.c |
13569 |
+--- linux-2.6.24.4/drivers/input/serio/serio_raw.c 2008-03-24 14:49:18.000000000 -0400 |
13570 |
++++ linux-2.6.24.4/drivers/input/serio/serio_raw.c 2008-03-26 17:56:56.000000000 -0400 |
13571 |
+@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_ |
13572 |
+ .id = SERIO_ANY, |
13573 |
+ .extra = SERIO_ANY, |
13574 |
+ }, |
13575 |
+- { 0 } |
13576 |
++ { 0, 0, 0, 0 } |
13577 |
+ }; |
13578 |
+ |
13579 |
+ MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids); |
13580 |
+diff -urNp linux-2.6.24.4/drivers/kvm/kvm_main.c linux-2.6.24.4/drivers/kvm/kvm_main.c |
13581 |
+--- linux-2.6.24.4/drivers/kvm/kvm_main.c 2008-03-24 14:49:18.000000000 -0400 |
13582 |
++++ linux-2.6.24.4/drivers/kvm/kvm_main.c 2008-03-26 17:56:56.000000000 -0400 |
13583 |
+@@ -67,22 +67,22 @@ static struct kvm_stats_debugfs_item { |
13584 |
+ int offset; |
13585 |
+ struct dentry *dentry; |
13586 |
+ } debugfs_entries[] = { |
13587 |
+- { "pf_fixed", STAT_OFFSET(pf_fixed) }, |
13588 |
+- { "pf_guest", STAT_OFFSET(pf_guest) }, |
13589 |
+- { "tlb_flush", STAT_OFFSET(tlb_flush) }, |
13590 |
+- { "invlpg", STAT_OFFSET(invlpg) }, |
13591 |
+- { "exits", STAT_OFFSET(exits) }, |
13592 |
+- { "io_exits", STAT_OFFSET(io_exits) }, |
13593 |
+- { "mmio_exits", STAT_OFFSET(mmio_exits) }, |
13594 |
+- { "signal_exits", STAT_OFFSET(signal_exits) }, |
13595 |
+- { "irq_window", STAT_OFFSET(irq_window_exits) }, |
13596 |
+- { "halt_exits", STAT_OFFSET(halt_exits) }, |
13597 |
+- { "halt_wakeup", STAT_OFFSET(halt_wakeup) }, |
13598 |
+- { "request_irq", STAT_OFFSET(request_irq_exits) }, |
13599 |
+- { "irq_exits", STAT_OFFSET(irq_exits) }, |
13600 |
+- { "light_exits", STAT_OFFSET(light_exits) }, |
13601 |
+- { "efer_reload", STAT_OFFSET(efer_reload) }, |
13602 |
+- { NULL } |
13603 |
++ { "pf_fixed", STAT_OFFSET(pf_fixed), NULL }, |
13604 |
++ { "pf_guest", STAT_OFFSET(pf_guest), NULL }, |
13605 |
++ { "tlb_flush", STAT_OFFSET(tlb_flush), NULL }, |
13606 |
++ { "invlpg", STAT_OFFSET(invlpg), NULL }, |
13607 |
++ { "exits", STAT_OFFSET(exits), NULL }, |
13608 |
++ { "io_exits", STAT_OFFSET(io_exits), NULL }, |
13609 |
++ { "mmio_exits", STAT_OFFSET(mmio_exits), NULL }, |
13610 |
++ { "signal_exits", STAT_OFFSET(signal_exits), NULL }, |
13611 |
++ { "irq_window", STAT_OFFSET(irq_window_exits), NULL }, |
13612 |
++ { "halt_exits", STAT_OFFSET(halt_exits), NULL }, |
13613 |
++ { "halt_wakeup", STAT_OFFSET(halt_wakeup), NULL }, |
13614 |
++ { "request_irq", STAT_OFFSET(request_irq_exits), NULL }, |
13615 |
++ { "irq_exits", STAT_OFFSET(irq_exits), NULL }, |
13616 |
++ { "light_exits", STAT_OFFSET(light_exits), NULL }, |
13617 |
++ { "efer_reload", STAT_OFFSET(efer_reload), NULL }, |
13618 |
++ { NULL, 0, NULL } |
13619 |
+ }; |
13620 |
+ |
13621 |
+ static struct dentry *debugfs_dir; |
13622 |
+@@ -2505,7 +2505,7 @@ static int kvm_vcpu_ioctl_translate(stru |
13623 |
+ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, |
13624 |
+ struct kvm_interrupt *irq) |
13625 |
+ { |
13626 |
+- if (irq->irq < 0 || irq->irq >= 256) |
13627 |
++ if (irq->irq >= 256) |
13628 |
+ return -EINVAL; |
13629 |
+ if (irqchip_in_kernel(vcpu->kvm)) |
13630 |
+ return -ENXIO; |
13631 |
+@@ -3250,6 +3250,9 @@ static struct miscdevice kvm_dev = { |
13632 |
+ KVM_MINOR, |
13633 |
+ "kvm", |
13634 |
+ &kvm_chardev_ops, |
13635 |
++ {NULL, NULL}, |
13636 |
++ NULL, |
13637 |
++ NULL |
13638 |
+ }; |
13639 |
+ |
13640 |
+ /* |
13641 |
+diff -urNp linux-2.6.24.4/drivers/kvm/svm.c linux-2.6.24.4/drivers/kvm/svm.c |
13642 |
+--- linux-2.6.24.4/drivers/kvm/svm.c 2008-03-24 14:49:18.000000000 -0400 |
13643 |
++++ linux-2.6.24.4/drivers/kvm/svm.c 2008-03-26 17:56:56.000000000 -0400 |
13644 |
+@@ -1307,8 +1307,20 @@ static void reload_tss(struct kvm_vcpu * |
13645 |
+ int cpu = raw_smp_processor_id(); |
13646 |
+ |
13647 |
+ struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu); |
13648 |
++ |
13649 |
++#ifdef CONFIG_PAX_KERNEXEC |
13650 |
++ unsigned long cr0; |
13651 |
++ |
13652 |
++ pax_open_kernel(cr0); |
13653 |
++#endif |
13654 |
++ |
13655 |
+ svm_data->tss_desc->type = 9; //available 32/64-bit TSS |
13656 |
+ load_TR_desc(); |
13657 |
++ |
13658 |
++#ifdef CONFIG_PAX_KERNEXEC |
13659 |
++ pax_close_kernel(cr0); |
13660 |
++#endif |
13661 |
++ |
13662 |
+ } |
13663 |
+ |
13664 |
+ static void pre_svm_run(struct vcpu_svm *svm) |
13665 |
+diff -urNp linux-2.6.24.4/drivers/kvm/vmx.c linux-2.6.24.4/drivers/kvm/vmx.c |
13666 |
+--- linux-2.6.24.4/drivers/kvm/vmx.c 2008-03-24 14:49:18.000000000 -0400 |
13667 |
++++ linux-2.6.24.4/drivers/kvm/vmx.c 2008-03-26 17:56:56.000000000 -0400 |
13668 |
+@@ -335,10 +335,24 @@ static void reload_tss(void) |
13669 |
+ struct descriptor_table gdt; |
13670 |
+ struct segment_descriptor *descs; |
13671 |
+ |
13672 |
++#ifdef CONFIG_PAX_KERNEXEC |
13673 |
++ unsigned long cr0; |
13674 |
++#endif |
13675 |
++ |
13676 |
+ get_gdt(&gdt); |
13677 |
+ descs = (void *)gdt.base; |
13678 |
++ |
13679 |
++#ifdef CONFIG_PAX_KERNEXEC |
13680 |
++ pax_open_kernel(cr0); |
13681 |
++#endif |
13682 |
++ |
13683 |
+ descs[GDT_ENTRY_TSS].type = 9; /* available TSS */ |
13684 |
+ load_TR_desc(); |
13685 |
++ |
13686 |
++#ifdef CONFIG_PAX_KERNEXEC |
13687 |
++ pax_close_kernel(cr0); |
13688 |
++#endif |
13689 |
++ |
13690 |
+ #endif |
13691 |
+ } |
13692 |
+ |
13693 |
+@@ -2322,7 +2336,7 @@ static void vmx_vcpu_run(struct kvm_vcpu |
13694 |
+ |
13695 |
+ vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; |
13696 |
+ |
13697 |
+- asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); |
13698 |
++ asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS)); |
13699 |
+ vmx->launched = 1; |
13700 |
+ |
13701 |
+ intr_info = vmcs_read32(VM_EXIT_INTR_INFO); |
13702 |
+diff -urNp linux-2.6.24.4/drivers/md/bitmap.c linux-2.6.24.4/drivers/md/bitmap.c |
13703 |
+--- linux-2.6.24.4/drivers/md/bitmap.c 2008-03-24 14:49:18.000000000 -0400 |
13704 |
++++ linux-2.6.24.4/drivers/md/bitmap.c 2008-03-26 17:56:56.000000000 -0400 |
13705 |
+@@ -57,7 +57,7 @@ |
13706 |
+ # if DEBUG > 0 |
13707 |
+ # define PRINTK(x...) printk(KERN_DEBUG x) |
13708 |
+ # else |
13709 |
+-# define PRINTK(x...) |
13710 |
++# define PRINTK(x...) do {} while (0) |
13711 |
+ # endif |
13712 |
+ #endif |
13713 |
+ |
13714 |
+diff -urNp linux-2.6.24.4/drivers/mtd/devices/doc2000.c linux-2.6.24.4/drivers/mtd/devices/doc2000.c |
13715 |
+--- linux-2.6.24.4/drivers/mtd/devices/doc2000.c 2008-03-24 14:49:18.000000000 -0400 |
13716 |
++++ linux-2.6.24.4/drivers/mtd/devices/doc2000.c 2008-03-26 17:56:56.000000000 -0400 |
13717 |
+@@ -632,7 +632,7 @@ static int doc_read(struct mtd_info *mtd |
13718 |
+ len = ((from | 0x1ff) + 1) - from; |
13719 |
+ |
13720 |
+ /* The ECC will not be calculated correctly if less than 512 is read */ |
13721 |
+- if (len != 0x200 && eccbuf) |
13722 |
++ if (len != 0x200) |
13723 |
+ printk(KERN_WARNING |
13724 |
+ "ECC needs a full sector read (adr: %lx size %lx)\n", |
13725 |
+ (long) from, (long) len); |
13726 |
+diff -urNp linux-2.6.24.4/drivers/mtd/devices/doc2001.c linux-2.6.24.4/drivers/mtd/devices/doc2001.c |
13727 |
+--- linux-2.6.24.4/drivers/mtd/devices/doc2001.c 2008-03-24 14:49:18.000000000 -0400 |
13728 |
++++ linux-2.6.24.4/drivers/mtd/devices/doc2001.c 2008-03-26 17:56:56.000000000 -0400 |
13729 |
+@@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt |
13730 |
+ /* Don't allow read past end of device */ |
13731 |
+ if (from >= this->totlen) |
13732 |
+ return -EINVAL; |
13733 |
++ if (!len) |
13734 |
++ return -EINVAL; |
13735 |
+ |
13736 |
+ /* Don't allow a single read to cross a 512-byte block boundary */ |
13737 |
+ if (from + len > ((from | 0x1ff) + 1)) |
13738 |
+diff -urNp linux-2.6.24.4/drivers/mtd/devices/doc2001plus.c linux-2.6.24.4/drivers/mtd/devices/doc2001plus.c |
13739 |
+--- linux-2.6.24.4/drivers/mtd/devices/doc2001plus.c 2008-03-24 14:49:18.000000000 -0400 |
13740 |
++++ linux-2.6.24.4/drivers/mtd/devices/doc2001plus.c 2008-03-26 17:56:56.000000000 -0400 |
13741 |
+@@ -748,7 +748,7 @@ static int doc_write(struct mtd_info *mt |
13742 |
+ WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd); |
13743 |
+ |
13744 |
+ /* On interleaved devices the flags for 2nd half 512 are before data */ |
13745 |
+- if (eccbuf && before) |
13746 |
++ if (before) |
13747 |
+ fto -= 2; |
13748 |
+ |
13749 |
+ /* issue the Serial Data In command to initial the Page Program process */ |
13750 |
+diff -urNp linux-2.6.24.4/drivers/mtd/devices/slram.c linux-2.6.24.4/drivers/mtd/devices/slram.c |
13751 |
+--- linux-2.6.24.4/drivers/mtd/devices/slram.c 2008-03-24 14:49:18.000000000 -0400 |
13752 |
++++ linux-2.6.24.4/drivers/mtd/devices/slram.c 2008-03-26 17:56:56.000000000 -0400 |
13753 |
+@@ -270,7 +270,7 @@ static int parse_cmdline(char *devname, |
13754 |
+ } |
13755 |
+ T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", |
13756 |
+ devname, devstart, devlength); |
13757 |
+- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) { |
13758 |
++ if (devlength % SLRAM_BLK_SZ != 0) { |
13759 |
+ E("slram: Illegal start / length parameter.\n"); |
13760 |
+ return(-EINVAL); |
13761 |
+ } |
13762 |
+diff -urNp linux-2.6.24.4/drivers/mtd/ubi/build.c linux-2.6.24.4/drivers/mtd/ubi/build.c |
13763 |
+--- linux-2.6.24.4/drivers/mtd/ubi/build.c 2008-03-24 14:49:18.000000000 -0400 |
13764 |
++++ linux-2.6.24.4/drivers/mtd/ubi/build.c 2008-03-26 17:56:56.000000000 -0400 |
13765 |
+@@ -753,7 +753,7 @@ static int __init bytes_str_to_int(const |
13766 |
+ unsigned long result; |
13767 |
+ |
13768 |
+ result = simple_strtoul(str, &endp, 0); |
13769 |
+- if (str == endp || result < 0) { |
13770 |
++ if (str == endp) { |
13771 |
+ printk("UBI error: incorrect bytes count: \"%s\"\n", str); |
13772 |
+ return -EINVAL; |
13773 |
+ } |
13774 |
+diff -urNp linux-2.6.24.4/drivers/net/eepro100.c linux-2.6.24.4/drivers/net/eepro100.c |
13775 |
+--- linux-2.6.24.4/drivers/net/eepro100.c 2008-03-24 14:49:18.000000000 -0400 |
13776 |
++++ linux-2.6.24.4/drivers/net/eepro100.c 2008-03-26 17:56:56.000000000 -0400 |
13777 |
+@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */; |
13778 |
+ # define rx_align(skb) skb_reserve((skb), 2) |
13779 |
+ # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed)) |
13780 |
+ #else |
13781 |
+-# define rx_align(skb) |
13782 |
++# define rx_align(skb) do {} while (0) |
13783 |
+ # define RxFD_ALIGNMENT |
13784 |
+ #endif |
13785 |
+ |
13786 |
+@@ -2340,33 +2340,33 @@ static void __devexit eepro100_remove_on |
13787 |
+ } |
13788 |
+ |
13789 |
+ static struct pci_device_id eepro100_pci_tbl[] = { |
13790 |
+- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, }, |
13791 |
+- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, }, |
13792 |
+- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, }, |
13793 |
+- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, }, |
13794 |
+- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, }, |
13795 |
+- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, }, |
13796 |
+- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, }, |
13797 |
+- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, }, |
13798 |
+- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, }, |
13799 |
+- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, }, |
13800 |
+- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, }, |
13801 |
+- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, }, |
13802 |
+- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, }, |
13803 |
+- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, }, |
13804 |
+- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, }, |
13805 |
+- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, }, |
13806 |
+- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, }, |
13807 |
+- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, }, |
13808 |
+- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, }, |
13809 |
+- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, }, |
13810 |
+- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, }, |
13811 |
+- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, }, |
13812 |
+- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, }, |
13813 |
+- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, }, |
13814 |
+- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, }, |
13815 |
+- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, }, |
13816 |
+- { 0,} |
13817 |
++ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13818 |
++ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13819 |
++ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13820 |
++ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13821 |
++ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13822 |
++ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13823 |
++ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13824 |
++ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13825 |
++ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13826 |
++ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13827 |
++ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13828 |
++ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13829 |
++ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13830 |
++ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13831 |
++ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13832 |
++ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13833 |
++ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13834 |
++ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13835 |
++ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13836 |
++ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13837 |
++ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13838 |
++ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13839 |
++ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13840 |
++ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13841 |
++ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13842 |
++ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13843 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13844 |
+ }; |
13845 |
+ MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl); |
13846 |
+ |
13847 |
+diff -urNp linux-2.6.24.4/drivers/net/irda/vlsi_ir.c linux-2.6.24.4/drivers/net/irda/vlsi_ir.c |
13848 |
+--- linux-2.6.24.4/drivers/net/irda/vlsi_ir.c 2008-03-24 14:49:18.000000000 -0400 |
13849 |
++++ linux-2.6.24.4/drivers/net/irda/vlsi_ir.c 2008-03-26 17:56:56.000000000 -0400 |
13850 |
+@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s |
13851 |
+ /* no race - tx-ring already empty */ |
13852 |
+ vlsi_set_baud(idev, iobase); |
13853 |
+ netif_wake_queue(ndev); |
13854 |
+- } |
13855 |
+- else |
13856 |
+- ; |
13857 |
++ } else { |
13858 |
+ /* keep the speed change pending like it would |
13859 |
+ * for any len>0 packet. tx completion interrupt |
13860 |
+ * will apply it when the tx ring becomes empty. |
13861 |
+ */ |
13862 |
++ } |
13863 |
+ spin_unlock_irqrestore(&idev->lock, flags); |
13864 |
+ dev_kfree_skb_any(skb); |
13865 |
+ return 0; |
13866 |
+diff -urNp linux-2.6.24.4/drivers/net/pcnet32.c linux-2.6.24.4/drivers/net/pcnet32.c |
13867 |
+--- linux-2.6.24.4/drivers/net/pcnet32.c 2008-03-24 14:49:18.000000000 -0400 |
13868 |
++++ linux-2.6.24.4/drivers/net/pcnet32.c 2008-03-26 17:56:56.000000000 -0400 |
13869 |
+@@ -82,7 +82,7 @@ static int cards_found; |
13870 |
+ /* |
13871 |
+ * VLB I/O addresses |
13872 |
+ */ |
13873 |
+-static unsigned int pcnet32_portlist[] __initdata = |
13874 |
++static unsigned int pcnet32_portlist[] __devinitdata = |
13875 |
+ { 0x300, 0x320, 0x340, 0x360, 0 }; |
13876 |
+ |
13877 |
+ static int pcnet32_debug = 0; |
13878 |
+diff -urNp linux-2.6.24.4/drivers/net/tg3.h linux-2.6.24.4/drivers/net/tg3.h |
13879 |
+--- linux-2.6.24.4/drivers/net/tg3.h 2008-03-24 14:49:18.000000000 -0400 |
13880 |
++++ linux-2.6.24.4/drivers/net/tg3.h 2008-03-26 17:56:56.000000000 -0400 |
13881 |
+@@ -102,6 +102,7 @@ |
13882 |
+ #define CHIPREV_ID_5750_A0 0x4000 |
13883 |
+ #define CHIPREV_ID_5750_A1 0x4001 |
13884 |
+ #define CHIPREV_ID_5750_A3 0x4003 |
13885 |
++#define CHIPREV_ID_5750_C1 0x4201 |
13886 |
+ #define CHIPREV_ID_5750_C2 0x4202 |
13887 |
+ #define CHIPREV_ID_5752_A0_HW 0x5000 |
13888 |
+ #define CHIPREV_ID_5752_A0 0x6000 |
13889 |
+diff -urNp linux-2.6.24.4/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.24.4/drivers/pci/hotplug/cpqphp_nvram.c |
13890 |
+--- linux-2.6.24.4/drivers/pci/hotplug/cpqphp_nvram.c 2008-03-24 14:49:18.000000000 -0400 |
13891 |
++++ linux-2.6.24.4/drivers/pci/hotplug/cpqphp_nvram.c 2008-03-26 17:56:56.000000000 -0400 |
13892 |
+@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_ |
13893 |
+ |
13894 |
+ void compaq_nvram_init (void __iomem *rom_start) |
13895 |
+ { |
13896 |
++ |
13897 |
++#ifndef CONFIG_PAX_KERNEXEC |
13898 |
+ if (rom_start) { |
13899 |
+ compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR); |
13900 |
+ } |
13901 |
++#endif |
13902 |
++ |
13903 |
+ dbg("int15 entry = %p\n", compaq_int15_entry_point); |
13904 |
+ |
13905 |
+ /* initialize our int15 lock */ |
13906 |
+diff -urNp linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv.c linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv.c |
13907 |
+--- linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv.c 2008-03-24 14:49:18.000000000 -0400 |
13908 |
++++ linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv.c 2008-03-26 17:56:56.000000000 -0400 |
13909 |
+@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i |
13910 |
+ .port_type = PCIE_RC_PORT, |
13911 |
+ .service_type = PCIE_PORT_SERVICE_AER, |
13912 |
+ }, |
13913 |
+- { /* end: all zeroes */ } |
13914 |
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
13915 |
+ }; |
13916 |
+ |
13917 |
+ static struct pci_error_handlers aer_error_handlers = { |
13918 |
+diff -urNp linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv_core.c |
13919 |
+--- linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv_core.c 2008-03-24 14:49:18.000000000 -0400 |
13920 |
++++ linux-2.6.24.4/drivers/pci/pcie/aer/aerdrv_core.c 2008-03-26 17:56:56.000000000 -0400 |
13921 |
+@@ -661,7 +661,7 @@ static void aer_isr_one_error(struct pci |
13922 |
+ struct aer_err_source *e_src) |
13923 |
+ { |
13924 |
+ struct device *s_device; |
13925 |
+- struct aer_err_info e_info = {0, 0, 0,}; |
13926 |
++ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}}; |
13927 |
+ int i; |
13928 |
+ u16 id; |
13929 |
+ |
13930 |
+diff -urNp linux-2.6.24.4/drivers/pci/pcie/portdrv_pci.c linux-2.6.24.4/drivers/pci/pcie/portdrv_pci.c |
13931 |
+--- linux-2.6.24.4/drivers/pci/pcie/portdrv_pci.c 2008-03-24 14:49:18.000000000 -0400 |
13932 |
++++ linux-2.6.24.4/drivers/pci/pcie/portdrv_pci.c 2008-03-26 17:56:56.000000000 -0400 |
13933 |
+@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru |
13934 |
+ static const struct pci_device_id port_pci_ids[] = { { |
13935 |
+ /* handle any PCI-Express port */ |
13936 |
+ PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0), |
13937 |
+- }, { /* end: all zeroes */ } |
13938 |
++ }, { 0, 0, 0, 0, 0, 0, 0 } |
13939 |
+ }; |
13940 |
+ MODULE_DEVICE_TABLE(pci, port_pci_ids); |
13941 |
+ |
13942 |
+diff -urNp linux-2.6.24.4/drivers/pci/proc.c linux-2.6.24.4/drivers/pci/proc.c |
13943 |
+--- linux-2.6.24.4/drivers/pci/proc.c 2008-03-24 14:49:18.000000000 -0400 |
13944 |
++++ linux-2.6.24.4/drivers/pci/proc.c 2008-03-26 17:56:56.000000000 -0400 |
13945 |
+@@ -467,7 +467,15 @@ static int __init pci_proc_init(void) |
13946 |
+ { |
13947 |
+ struct proc_dir_entry *entry; |
13948 |
+ struct pci_dev *dev = NULL; |
13949 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
13950 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
13951 |
++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus); |
13952 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
13953 |
++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus); |
13954 |
++#endif |
13955 |
++#else |
13956 |
+ proc_bus_pci_dir = proc_mkdir("pci", proc_bus); |
13957 |
++#endif |
13958 |
+ entry = create_proc_entry("devices", 0, proc_bus_pci_dir); |
13959 |
+ if (entry) |
13960 |
+ entry->proc_fops = &proc_bus_pci_dev_operations; |
13961 |
+diff -urNp linux-2.6.24.4/drivers/pcmcia/ti113x.h linux-2.6.24.4/drivers/pcmcia/ti113x.h |
13962 |
+--- linux-2.6.24.4/drivers/pcmcia/ti113x.h 2008-03-24 14:49:18.000000000 -0400 |
13963 |
++++ linux-2.6.24.4/drivers/pcmcia/ti113x.h 2008-03-26 17:56:56.000000000 -0400 |
13964 |
+@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl |
13965 |
+ DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID, |
13966 |
+ ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE), |
13967 |
+ |
13968 |
+- {} |
13969 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13970 |
+ }; |
13971 |
+ |
13972 |
+ static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus) |
13973 |
+diff -urNp linux-2.6.24.4/drivers/pcmcia/yenta_socket.c linux-2.6.24.4/drivers/pcmcia/yenta_socket.c |
13974 |
+--- linux-2.6.24.4/drivers/pcmcia/yenta_socket.c 2008-03-24 14:49:18.000000000 -0400 |
13975 |
++++ linux-2.6.24.4/drivers/pcmcia/yenta_socket.c 2008-03-26 17:56:56.000000000 -0400 |
13976 |
+@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table |
13977 |
+ |
13978 |
+ /* match any cardbus bridge */ |
13979 |
+ CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), |
13980 |
+- { /* all zeroes */ } |
13981 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13982 |
+ }; |
13983 |
+ MODULE_DEVICE_TABLE(pci, yenta_table); |
13984 |
+ |
13985 |
+diff -urNp linux-2.6.24.4/drivers/pnp/pnpbios/bioscalls.c linux-2.6.24.4/drivers/pnp/pnpbios/bioscalls.c |
13986 |
+--- linux-2.6.24.4/drivers/pnp/pnpbios/bioscalls.c 2008-03-24 14:49:18.000000000 -0400 |
13987 |
++++ linux-2.6.24.4/drivers/pnp/pnpbios/bioscalls.c 2008-03-26 17:56:56.000000000 -0400 |
13988 |
+@@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr |
13989 |
+ set_limit(gdt[(selname) >> 3], size); \ |
13990 |
+ } while(0) |
13991 |
+ |
13992 |
+-static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; |
13993 |
++static struct desc_struct bad_bios_desc __read_only = { 0, 0x00409300 }; |
13994 |
+ |
13995 |
+ /* |
13996 |
+ * At some point we want to use this stack frame pointer to unwind |
13997 |
+@@ -88,6 +88,10 @@ static inline u16 call_pnp_bios(u16 func |
13998 |
+ struct desc_struct save_desc_40; |
13999 |
+ int cpu; |
14000 |
+ |
14001 |
++#ifdef CONFIG_PAX_KERNEXEC |
14002 |
++ unsigned long cr0; |
14003 |
++#endif |
14004 |
++ |
14005 |
+ /* |
14006 |
+ * PnP BIOSes are generally not terribly re-entrant. |
14007 |
+ * Also, don't rely on them to save everything correctly. |
14008 |
+@@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func |
14009 |
+ |
14010 |
+ cpu = get_cpu(); |
14011 |
+ save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8]; |
14012 |
++ |
14013 |
++#ifdef CONFIG_PAX_KERNEXEC |
14014 |
++ pax_open_kernel(cr0); |
14015 |
++#endif |
14016 |
++ |
14017 |
+ get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc; |
14018 |
+ |
14019 |
++#ifdef CONFIG_PAX_KERNEXEC |
14020 |
++ pax_close_kernel(cr0); |
14021 |
++#endif |
14022 |
++ |
14023 |
+ /* On some boxes IRQ's during PnP BIOS calls are deadly. */ |
14024 |
+ spin_lock_irqsave(&pnp_bios_lock, flags); |
14025 |
+ |
14026 |
+@@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func |
14027 |
+ :"memory"); |
14028 |
+ spin_unlock_irqrestore(&pnp_bios_lock, flags); |
14029 |
+ |
14030 |
++#ifdef CONFIG_PAX_KERNEXEC |
14031 |
++ pax_open_kernel(cr0); |
14032 |
++#endif |
14033 |
++ |
14034 |
+ get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40; |
14035 |
++ |
14036 |
++#ifdef CONFIG_PAX_KERNEXEC |
14037 |
++ pax_close_kernel(cr0); |
14038 |
++#endif |
14039 |
++ |
14040 |
+ put_cpu(); |
14041 |
+ |
14042 |
+ /* If we get here and this is set then the PnP BIOS faulted on us. */ |
14043 |
+@@ -469,16 +491,25 @@ int pnp_bios_read_escd(char *data, u32 n |
14044 |
+ return status; |
14045 |
+ } |
14046 |
+ |
14047 |
+-void pnpbios_calls_init(union pnp_bios_install_struct *header) |
14048 |
++void __init pnpbios_calls_init(union pnp_bios_install_struct *header) |
14049 |
+ { |
14050 |
+ int i; |
14051 |
+ |
14052 |
++#ifdef CONFIG_PAX_KERNEXEC |
14053 |
++ unsigned long cr0; |
14054 |
++#endif |
14055 |
++ |
14056 |
+ spin_lock_init(&pnp_bios_lock); |
14057 |
+ pnp_bios_callpoint.offset = header->fields.pm16offset; |
14058 |
+ pnp_bios_callpoint.segment = PNP_CS16; |
14059 |
+ |
14060 |
+ set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); |
14061 |
+ _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); |
14062 |
++ |
14063 |
++#ifdef CONFIG_PAX_KERNEXEC |
14064 |
++ pax_open_kernel(cr0); |
14065 |
++#endif |
14066 |
++ |
14067 |
+ for (i = 0; i < NR_CPUS; i++) { |
14068 |
+ struct desc_struct *gdt = get_cpu_gdt_table(i); |
14069 |
+ if (!gdt) |
14070 |
+@@ -489,4 +520,9 @@ void pnpbios_calls_init(union pnp_bios_i |
14071 |
+ set_base(gdt[GDT_ENTRY_PNPBIOS_DS], |
14072 |
+ __va(header->fields.pm16dseg)); |
14073 |
+ } |
14074 |
++ |
14075 |
++#ifdef CONFIG_PAX_KERNEXEC |
14076 |
++ pax_close_kernel(cr0); |
14077 |
++#endif |
14078 |
++ |
14079 |
+ } |
14080 |
+diff -urNp linux-2.6.24.4/drivers/pnp/quirks.c linux-2.6.24.4/drivers/pnp/quirks.c |
14081 |
+--- linux-2.6.24.4/drivers/pnp/quirks.c 2008-03-24 14:49:18.000000000 -0400 |
14082 |
++++ linux-2.6.24.4/drivers/pnp/quirks.c 2008-03-26 17:56:56.000000000 -0400 |
14083 |
+@@ -128,7 +128,7 @@ static struct pnp_fixup pnp_fixups[] = { |
14084 |
+ {"CTL0043", quirk_sb16audio_resources}, |
14085 |
+ {"CTL0044", quirk_sb16audio_resources}, |
14086 |
+ {"CTL0045", quirk_sb16audio_resources}, |
14087 |
+- {""} |
14088 |
++ {"", NULL} |
14089 |
+ }; |
14090 |
+ |
14091 |
+ void pnp_fixup_device(struct pnp_dev *dev) |
14092 |
+diff -urNp linux-2.6.24.4/drivers/pnp/resource.c linux-2.6.24.4/drivers/pnp/resource.c |
14093 |
+--- linux-2.6.24.4/drivers/pnp/resource.c 2008-03-24 14:49:18.000000000 -0400 |
14094 |
++++ linux-2.6.24.4/drivers/pnp/resource.c 2008-03-26 17:56:56.000000000 -0400 |
14095 |
+@@ -345,7 +345,7 @@ int pnp_check_irq(struct pnp_dev *dev, i |
14096 |
+ return 1; |
14097 |
+ |
14098 |
+ /* check if the resource is valid */ |
14099 |
+- if (*irq < 0 || *irq > 15) |
14100 |
++ if (*irq > 15) |
14101 |
+ return 0; |
14102 |
+ |
14103 |
+ /* check if the resource is reserved */ |
14104 |
+@@ -414,7 +414,7 @@ int pnp_check_dma(struct pnp_dev *dev, i |
14105 |
+ return 1; |
14106 |
+ |
14107 |
+ /* check if the resource is valid */ |
14108 |
+- if (*dma < 0 || *dma == 4 || *dma > 7) |
14109 |
++ if (*dma == 4 || *dma > 7) |
14110 |
+ return 0; |
14111 |
+ |
14112 |
+ /* check if the resource is reserved */ |
14113 |
+diff -urNp linux-2.6.24.4/drivers/scsi/scsi_logging.h linux-2.6.24.4/drivers/scsi/scsi_logging.h |
14114 |
+--- linux-2.6.24.4/drivers/scsi/scsi_logging.h 2008-03-24 14:49:18.000000000 -0400 |
14115 |
++++ linux-2.6.24.4/drivers/scsi/scsi_logging.h 2008-03-26 17:56:56.000000000 -0400 |
14116 |
+@@ -51,7 +51,7 @@ do { \ |
14117 |
+ } while (0); \ |
14118 |
+ } while (0) |
14119 |
+ #else |
14120 |
+-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) |
14121 |
++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0) |
14122 |
+ #endif /* CONFIG_SCSI_LOGGING */ |
14123 |
+ |
14124 |
+ /* |
14125 |
+diff -urNp linux-2.6.24.4/drivers/serial/8250_pci.c linux-2.6.24.4/drivers/serial/8250_pci.c |
14126 |
+--- linux-2.6.24.4/drivers/serial/8250_pci.c 2008-03-24 14:49:18.000000000 -0400 |
14127 |
++++ linux-2.6.24.4/drivers/serial/8250_pci.c 2008-03-26 17:56:56.000000000 -0400 |
14128 |
+@@ -2712,7 +2712,7 @@ static struct pci_device_id serial_pci_t |
14129 |
+ PCI_ANY_ID, PCI_ANY_ID, |
14130 |
+ PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, |
14131 |
+ 0xffff00, pbn_default }, |
14132 |
+- { 0, } |
14133 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
14134 |
+ }; |
14135 |
+ |
14136 |
+ static struct pci_driver serial_pci_driver = { |
14137 |
+diff -urNp linux-2.6.24.4/drivers/usb/class/cdc-acm.c linux-2.6.24.4/drivers/usb/class/cdc-acm.c |
14138 |
+--- linux-2.6.24.4/drivers/usb/class/cdc-acm.c 2008-03-24 14:49:18.000000000 -0400 |
14139 |
++++ linux-2.6.24.4/drivers/usb/class/cdc-acm.c 2008-03-26 17:56:56.000000000 -0400 |
14140 |
+@@ -1199,7 +1199,7 @@ static struct usb_device_id acm_ids[] = |
14141 |
+ USB_CDC_ACM_PROTO_AT_CDMA) }, |
14142 |
+ |
14143 |
+ /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */ |
14144 |
+- { } |
14145 |
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
14146 |
+ }; |
14147 |
+ |
14148 |
+ MODULE_DEVICE_TABLE (usb, acm_ids); |
14149 |
+diff -urNp linux-2.6.24.4/drivers/usb/class/usblp.c linux-2.6.24.4/drivers/usb/class/usblp.c |
14150 |
+--- linux-2.6.24.4/drivers/usb/class/usblp.c 2008-03-24 14:49:18.000000000 -0400 |
14151 |
++++ linux-2.6.24.4/drivers/usb/class/usblp.c 2008-03-26 17:56:56.000000000 -0400 |
14152 |
+@@ -227,7 +227,7 @@ static const struct quirk_printer_struct |
14153 |
+ { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */ |
14154 |
+ { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */ |
14155 |
+ { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */ |
14156 |
+- { 0, 0 } |
14157 |
++ { 0, 0, 0 } |
14158 |
+ }; |
14159 |
+ |
14160 |
+ static int usblp_wwait(struct usblp *usblp, int nonblock); |
14161 |
+@@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids [] |
14162 |
+ { USB_INTERFACE_INFO(7, 1, 2) }, |
14163 |
+ { USB_INTERFACE_INFO(7, 1, 3) }, |
14164 |
+ { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */ |
14165 |
+- { } /* Terminating entry */ |
14166 |
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */ |
14167 |
+ }; |
14168 |
+ |
14169 |
+ MODULE_DEVICE_TABLE (usb, usblp_ids); |
14170 |
+diff -urNp linux-2.6.24.4/drivers/usb/core/hub.c linux-2.6.24.4/drivers/usb/core/hub.c |
14171 |
+--- linux-2.6.24.4/drivers/usb/core/hub.c 2008-03-24 14:49:18.000000000 -0400 |
14172 |
++++ linux-2.6.24.4/drivers/usb/core/hub.c 2008-03-26 17:56:56.000000000 -0400 |
14173 |
+@@ -2884,7 +2884,7 @@ static struct usb_device_id hub_id_table |
14174 |
+ .bDeviceClass = USB_CLASS_HUB}, |
14175 |
+ { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, |
14176 |
+ .bInterfaceClass = USB_CLASS_HUB}, |
14177 |
+- { } /* Terminating entry */ |
14178 |
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */ |
14179 |
+ }; |
14180 |
+ |
14181 |
+ MODULE_DEVICE_TABLE (usb, hub_id_table); |
14182 |
+diff -urNp linux-2.6.24.4/drivers/usb/host/ehci-pci.c linux-2.6.24.4/drivers/usb/host/ehci-pci.c |
14183 |
+--- linux-2.6.24.4/drivers/usb/host/ehci-pci.c 2008-03-24 14:49:18.000000000 -0400 |
14184 |
++++ linux-2.6.24.4/drivers/usb/host/ehci-pci.c 2008-03-26 17:56:56.000000000 -0400 |
14185 |
+@@ -374,7 +374,7 @@ static const struct pci_device_id pci_id |
14186 |
+ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0), |
14187 |
+ .driver_data = (unsigned long) &ehci_pci_hc_driver, |
14188 |
+ }, |
14189 |
+- { /* end: all zeroes */ } |
14190 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
14191 |
+ }; |
14192 |
+ MODULE_DEVICE_TABLE(pci, pci_ids); |
14193 |
+ |
14194 |
+diff -urNp linux-2.6.24.4/drivers/usb/host/uhci-hcd.c linux-2.6.24.4/drivers/usb/host/uhci-hcd.c |
14195 |
+--- linux-2.6.24.4/drivers/usb/host/uhci-hcd.c 2008-03-24 14:49:18.000000000 -0400 |
14196 |
++++ linux-2.6.24.4/drivers/usb/host/uhci-hcd.c 2008-03-26 17:56:56.000000000 -0400 |
14197 |
+@@ -893,7 +893,7 @@ static const struct pci_device_id uhci_p |
14198 |
+ /* handle any USB UHCI controller */ |
14199 |
+ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0), |
14200 |
+ .driver_data = (unsigned long) &uhci_driver, |
14201 |
+- }, { /* end: all zeroes */ } |
14202 |
++ }, { 0, 0, 0, 0, 0, 0, 0 } |
14203 |
+ }; |
14204 |
+ |
14205 |
+ MODULE_DEVICE_TABLE(pci, uhci_pci_ids); |
14206 |
+diff -urNp linux-2.6.24.4/drivers/usb/storage/debug.h linux-2.6.24.4/drivers/usb/storage/debug.h |
14207 |
+--- linux-2.6.24.4/drivers/usb/storage/debug.h 2008-03-24 14:49:18.000000000 -0400 |
14208 |
++++ linux-2.6.24.4/drivers/usb/storage/debug.h 2008-03-26 17:56:56.000000000 -0400 |
14209 |
+@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char |
14210 |
+ #define US_DEBUGPX(x...) printk( x ) |
14211 |
+ #define US_DEBUG(x) x |
14212 |
+ #else |
14213 |
+-#define US_DEBUGP(x...) |
14214 |
+-#define US_DEBUGPX(x...) |
14215 |
+-#define US_DEBUG(x) |
14216 |
++#define US_DEBUGP(x...) do {} while (0) |
14217 |
++#define US_DEBUGPX(x...) do {} while (0) |
14218 |
++#define US_DEBUG(x) do {} while (0) |
14219 |
+ #endif |
14220 |
+ |
14221 |
+ #endif |
14222 |
+diff -urNp linux-2.6.24.4/drivers/usb/storage/usb.c linux-2.6.24.4/drivers/usb/storage/usb.c |
14223 |
+--- linux-2.6.24.4/drivers/usb/storage/usb.c 2008-03-24 14:49:18.000000000 -0400 |
14224 |
++++ linux-2.6.24.4/drivers/usb/storage/usb.c 2008-03-26 17:56:56.000000000 -0400 |
14225 |
+@@ -134,7 +134,7 @@ static struct usb_device_id storage_usb_ |
14226 |
+ #undef UNUSUAL_DEV |
14227 |
+ #undef USUAL_DEV |
14228 |
+ /* Terminating entry */ |
14229 |
+- { } |
14230 |
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
14231 |
+ }; |
14232 |
+ |
14233 |
+ MODULE_DEVICE_TABLE (usb, storage_usb_ids); |
14234 |
+@@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_ |
14235 |
+ # undef USUAL_DEV |
14236 |
+ |
14237 |
+ /* Terminating entry */ |
14238 |
+- { NULL } |
14239 |
++ { NULL, NULL, 0, 0, NULL } |
14240 |
+ }; |
14241 |
+ |
14242 |
+ |
14243 |
+diff -urNp linux-2.6.24.4/drivers/video/fbcmap.c linux-2.6.24.4/drivers/video/fbcmap.c |
14244 |
+--- linux-2.6.24.4/drivers/video/fbcmap.c 2008-03-24 14:49:18.000000000 -0400 |
14245 |
++++ linux-2.6.24.4/drivers/video/fbcmap.c 2008-03-26 17:56:56.000000000 -0400 |
14246 |
+@@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user |
14247 |
+ int rc, size = cmap->len * sizeof(u16); |
14248 |
+ struct fb_cmap umap; |
14249 |
+ |
14250 |
+- if (cmap->start < 0 || (!info->fbops->fb_setcolreg && |
14251 |
+- !info->fbops->fb_setcmap)) |
14252 |
++ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap) |
14253 |
+ return -EINVAL; |
14254 |
+ |
14255 |
+ memset(&umap, 0, sizeof(struct fb_cmap)); |
14256 |
+diff -urNp linux-2.6.24.4/drivers/video/fbmem.c linux-2.6.24.4/drivers/video/fbmem.c |
14257 |
+--- linux-2.6.24.4/drivers/video/fbmem.c 2008-03-24 14:49:18.000000000 -0400 |
14258 |
++++ linux-2.6.24.4/drivers/video/fbmem.c 2008-03-26 17:56:56.000000000 -0400 |
14259 |
+@@ -394,7 +394,7 @@ static void fb_do_show_logo(struct fb_in |
14260 |
+ image->dx += image->width + 8; |
14261 |
+ } |
14262 |
+ } else if (rotate == FB_ROTATE_UD) { |
14263 |
+- for (x = 0; x < num && image->dx >= 0; x++) { |
14264 |
++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) { |
14265 |
+ info->fbops->fb_imageblit(info, image); |
14266 |
+ image->dx -= image->width + 8; |
14267 |
+ } |
14268 |
+@@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in |
14269 |
+ image->dy += image->height + 8; |
14270 |
+ } |
14271 |
+ } else if (rotate == FB_ROTATE_CCW) { |
14272 |
+- for (x = 0; x < num && image->dy >= 0; x++) { |
14273 |
++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) { |
14274 |
+ info->fbops->fb_imageblit(info, image); |
14275 |
+ image->dy -= image->height + 8; |
14276 |
+ } |
14277 |
+@@ -1057,9 +1057,9 @@ fb_ioctl(struct inode *inode, struct fil |
14278 |
+ case FBIOPUT_CON2FBMAP: |
14279 |
+ if (copy_from_user(&con2fb, argp, sizeof(con2fb))) |
14280 |
+ return - EFAULT; |
14281 |
+- if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES) |
14282 |
++ if (con2fb.console > MAX_NR_CONSOLES) |
14283 |
+ return -EINVAL; |
14284 |
+- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) |
14285 |
++ if (con2fb.framebuffer >= FB_MAX) |
14286 |
+ return -EINVAL; |
14287 |
+ #ifdef CONFIG_KMOD |
14288 |
+ if (!registered_fb[con2fb.framebuffer]) |
14289 |
+diff -urNp linux-2.6.24.4/drivers/video/fbmon.c linux-2.6.24.4/drivers/video/fbmon.c |
14290 |
+--- linux-2.6.24.4/drivers/video/fbmon.c 2008-03-24 14:49:18.000000000 -0400 |
14291 |
++++ linux-2.6.24.4/drivers/video/fbmon.c 2008-03-26 17:56:56.000000000 -0400 |
14292 |
+@@ -45,7 +45,7 @@ |
14293 |
+ #ifdef DEBUG |
14294 |
+ #define DPRINTK(fmt, args...) printk(fmt,## args) |
14295 |
+ #else |
14296 |
+-#define DPRINTK(fmt, args...) |
14297 |
++#define DPRINTK(fmt, args...) do {} while (0) |
14298 |
+ #endif |
14299 |
+ |
14300 |
+ #define FBMON_FIX_HEADER 1 |
14301 |
+diff -urNp linux-2.6.24.4/drivers/video/i810/i810_accel.c linux-2.6.24.4/drivers/video/i810/i810_accel.c |
14302 |
+--- linux-2.6.24.4/drivers/video/i810/i810_accel.c 2008-03-24 14:49:18.000000000 -0400 |
14303 |
++++ linux-2.6.24.4/drivers/video/i810/i810_accel.c 2008-03-26 17:56:56.000000000 -0400 |
14304 |
+@@ -73,6 +73,7 @@ static inline int wait_for_space(struct |
14305 |
+ } |
14306 |
+ } |
14307 |
+ printk("ringbuffer lockup!!!\n"); |
14308 |
++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space); |
14309 |
+ i810_report_error(mmio); |
14310 |
+ par->dev_flags |= LOCKUP; |
14311 |
+ info->pixmap.scan_align = 1; |
14312 |
+diff -urNp linux-2.6.24.4/drivers/video/i810/i810_main.c linux-2.6.24.4/drivers/video/i810/i810_main.c |
14313 |
+--- linux-2.6.24.4/drivers/video/i810/i810_main.c 2008-03-24 14:49:18.000000000 -0400 |
14314 |
++++ linux-2.6.24.4/drivers/video/i810/i810_main.c 2008-03-26 17:56:56.000000000 -0400 |
14315 |
+@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t |
14316 |
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, |
14317 |
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC, |
14318 |
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, |
14319 |
+- { 0 }, |
14320 |
++ { 0, 0, 0, 0, 0, 0, 0 }, |
14321 |
+ }; |
14322 |
+ |
14323 |
+ static struct pci_driver i810fb_driver = { |
14324 |
+@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info |
14325 |
+ int size = ((cursor->image.width + 7) >> 3) * |
14326 |
+ cursor->image.height; |
14327 |
+ int i; |
14328 |
+- u8 *data = kmalloc(64 * 8, GFP_ATOMIC); |
14329 |
++ u8 *data = kmalloc(64 * 8, GFP_KERNEL); |
14330 |
+ |
14331 |
+ if (data == NULL) |
14332 |
+ return -ENOMEM; |
14333 |
+diff -urNp linux-2.6.24.4/drivers/video/modedb.c linux-2.6.24.4/drivers/video/modedb.c |
14334 |
+--- linux-2.6.24.4/drivers/video/modedb.c 2008-03-24 14:49:18.000000000 -0400 |
14335 |
++++ linux-2.6.24.4/drivers/video/modedb.c 2008-03-26 17:56:56.000000000 -0400 |
14336 |
+@@ -37,232 +37,232 @@ static const struct fb_videomode modedb[ |
14337 |
+ { |
14338 |
+ /* 640x400 @ 70 Hz, 31.5 kHz hsync */ |
14339 |
+ NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, |
14340 |
+- 0, FB_VMODE_NONINTERLACED |
14341 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14342 |
+ }, { |
14343 |
+ /* 640x480 @ 60 Hz, 31.5 kHz hsync */ |
14344 |
+ NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, |
14345 |
+- 0, FB_VMODE_NONINTERLACED |
14346 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14347 |
+ }, { |
14348 |
+ /* 800x600 @ 56 Hz, 35.15 kHz hsync */ |
14349 |
+ NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, |
14350 |
+- 0, FB_VMODE_NONINTERLACED |
14351 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14352 |
+ }, { |
14353 |
+ /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */ |
14354 |
+ NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, |
14355 |
+- 0, FB_VMODE_INTERLACED |
14356 |
++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN |
14357 |
+ }, { |
14358 |
+ /* 640x400 @ 85 Hz, 37.86 kHz hsync */ |
14359 |
+ NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, |
14360 |
+- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14361 |
++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14362 |
+ }, { |
14363 |
+ /* 640x480 @ 72 Hz, 36.5 kHz hsync */ |
14364 |
+ NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, |
14365 |
+- 0, FB_VMODE_NONINTERLACED |
14366 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14367 |
+ }, { |
14368 |
+ /* 640x480 @ 75 Hz, 37.50 kHz hsync */ |
14369 |
+ NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, |
14370 |
+- 0, FB_VMODE_NONINTERLACED |
14371 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14372 |
+ }, { |
14373 |
+ /* 800x600 @ 60 Hz, 37.8 kHz hsync */ |
14374 |
+ NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, |
14375 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14376 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14377 |
+ }, { |
14378 |
+ /* 640x480 @ 85 Hz, 43.27 kHz hsync */ |
14379 |
+ NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, |
14380 |
+- 0, FB_VMODE_NONINTERLACED |
14381 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14382 |
+ }, { |
14383 |
+ /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ |
14384 |
+ NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, |
14385 |
+- 0, FB_VMODE_INTERLACED |
14386 |
++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN |
14387 |
+ }, { |
14388 |
+ /* 800x600 @ 72 Hz, 48.0 kHz hsync */ |
14389 |
+ NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, |
14390 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14391 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14392 |
+ }, { |
14393 |
+ /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ |
14394 |
+ NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, |
14395 |
+- 0, FB_VMODE_NONINTERLACED |
14396 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14397 |
+ }, { |
14398 |
+ /* 640x480 @ 100 Hz, 53.01 kHz hsync */ |
14399 |
+ NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, |
14400 |
+- 0, FB_VMODE_NONINTERLACED |
14401 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14402 |
+ }, { |
14403 |
+ /* 1152x864 @ 60 Hz, 53.5 kHz hsync */ |
14404 |
+ NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, |
14405 |
+- 0, FB_VMODE_NONINTERLACED |
14406 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14407 |
+ }, { |
14408 |
+ /* 800x600 @ 85 Hz, 55.84 kHz hsync */ |
14409 |
+ NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, |
14410 |
+- 0, FB_VMODE_NONINTERLACED |
14411 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14412 |
+ }, { |
14413 |
+ /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ |
14414 |
+ NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, |
14415 |
+- 0, FB_VMODE_NONINTERLACED |
14416 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14417 |
+ }, { |
14418 |
+ /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ |
14419 |
+ NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, |
14420 |
+- 0, FB_VMODE_INTERLACED |
14421 |
++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN |
14422 |
+ }, { |
14423 |
+ /* 800x600 @ 100 Hz, 64.02 kHz hsync */ |
14424 |
+ NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, |
14425 |
+- 0, FB_VMODE_NONINTERLACED |
14426 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14427 |
+ }, { |
14428 |
+ /* 1024x768 @ 76 Hz, 62.5 kHz hsync */ |
14429 |
+ NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, |
14430 |
+- 0, FB_VMODE_NONINTERLACED |
14431 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14432 |
+ }, { |
14433 |
+ /* 1152x864 @ 70 Hz, 62.4 kHz hsync */ |
14434 |
+ NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, |
14435 |
+- 0, FB_VMODE_NONINTERLACED |
14436 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14437 |
+ }, { |
14438 |
+ /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */ |
14439 |
+ NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, |
14440 |
+- 0, FB_VMODE_NONINTERLACED |
14441 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14442 |
+ }, { |
14443 |
+ /* 1400x1050 @ 60Hz, 63.9 kHz hsync */ |
14444 |
+ NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, |
14445 |
+- 0, FB_VMODE_NONINTERLACED |
14446 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14447 |
+ }, { |
14448 |
+ /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ |
14449 |
+ NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13, |
14450 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14451 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14452 |
+ }, { |
14453 |
+ /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ |
14454 |
+ NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3, |
14455 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14456 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14457 |
+ }, { |
14458 |
+ /* 1024x768 @ 85 Hz, 70.24 kHz hsync */ |
14459 |
+ NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, |
14460 |
+- 0, FB_VMODE_NONINTERLACED |
14461 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14462 |
+ }, { |
14463 |
+ /* 1152x864 @ 78 Hz, 70.8 kHz hsync */ |
14464 |
+ NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, |
14465 |
+- 0, FB_VMODE_NONINTERLACED |
14466 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14467 |
+ }, { |
14468 |
+ /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */ |
14469 |
+ NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, |
14470 |
+- 0, FB_VMODE_NONINTERLACED |
14471 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14472 |
+ }, { |
14473 |
+ /* 1600x1200 @ 60Hz, 75.00 kHz hsync */ |
14474 |
+ NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, |
14475 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14476 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14477 |
+ }, { |
14478 |
+ /* 1152x864 @ 84 Hz, 76.0 kHz hsync */ |
14479 |
+ NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, |
14480 |
+- 0, FB_VMODE_NONINTERLACED |
14481 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14482 |
+ }, { |
14483 |
+ /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */ |
14484 |
+ NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, |
14485 |
+- 0, FB_VMODE_NONINTERLACED |
14486 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14487 |
+ }, { |
14488 |
+ /* 1024x768 @ 100Hz, 80.21 kHz hsync */ |
14489 |
+ NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, |
14490 |
+- 0, FB_VMODE_NONINTERLACED |
14491 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14492 |
+ }, { |
14493 |
+ /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */ |
14494 |
+ NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, |
14495 |
+- 0, FB_VMODE_NONINTERLACED |
14496 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14497 |
+ }, { |
14498 |
+ /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */ |
14499 |
+ NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, |
14500 |
+- 0, FB_VMODE_NONINTERLACED |
14501 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14502 |
+ }, { |
14503 |
+ /* 1152x864 @ 100 Hz, 89.62 kHz hsync */ |
14504 |
+ NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, |
14505 |
+- 0, FB_VMODE_NONINTERLACED |
14506 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14507 |
+ }, { |
14508 |
+ /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */ |
14509 |
+ NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, |
14510 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14511 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14512 |
+ }, { |
14513 |
+ /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */ |
14514 |
+ NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, |
14515 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14516 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14517 |
+ }, { |
14518 |
+ /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */ |
14519 |
+ NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6, |
14520 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14521 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14522 |
+ }, { |
14523 |
+ /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */ |
14524 |
+ NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3, |
14525 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14526 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14527 |
+ }, { |
14528 |
+ /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */ |
14529 |
+ NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, |
14530 |
+- 0, FB_VMODE_NONINTERLACED |
14531 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14532 |
+ }, { |
14533 |
+ /* 1800x1440 @ 64Hz, 96.15 kHz hsync */ |
14534 |
+ NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3, |
14535 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14536 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14537 |
+ }, { |
14538 |
+ /* 1800x1440 @ 70Hz, 104.52 kHz hsync */ |
14539 |
+ NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3, |
14540 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14541 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14542 |
+ }, { |
14543 |
+ /* 512x384 @ 78 Hz, 31.50 kHz hsync */ |
14544 |
+ NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, |
14545 |
+- 0, FB_VMODE_NONINTERLACED |
14546 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14547 |
+ }, { |
14548 |
+ /* 512x384 @ 85 Hz, 34.38 kHz hsync */ |
14549 |
+ NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, |
14550 |
+- 0, FB_VMODE_NONINTERLACED |
14551 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14552 |
+ }, { |
14553 |
+ /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */ |
14554 |
+ NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, |
14555 |
+- 0, FB_VMODE_DOUBLE |
14556 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14557 |
+ }, { |
14558 |
+ /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */ |
14559 |
+ NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, |
14560 |
+- 0, FB_VMODE_DOUBLE |
14561 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14562 |
+ }, { |
14563 |
+ /* 320x240 @ 72 Hz, 36.5 kHz hsync */ |
14564 |
+ NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, |
14565 |
+- 0, FB_VMODE_DOUBLE |
14566 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14567 |
+ }, { |
14568 |
+ /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */ |
14569 |
+ NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, |
14570 |
+- 0, FB_VMODE_DOUBLE |
14571 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14572 |
+ }, { |
14573 |
+ /* 400x300 @ 60 Hz, 37.8 kHz hsync */ |
14574 |
+ NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, |
14575 |
+- 0, FB_VMODE_DOUBLE |
14576 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14577 |
+ }, { |
14578 |
+ /* 400x300 @ 72 Hz, 48.0 kHz hsync */ |
14579 |
+ NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, |
14580 |
+- 0, FB_VMODE_DOUBLE |
14581 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14582 |
+ }, { |
14583 |
+ /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */ |
14584 |
+ NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, |
14585 |
+- 0, FB_VMODE_DOUBLE |
14586 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14587 |
+ }, { |
14588 |
+ /* 480x300 @ 60 Hz, 37.8 kHz hsync */ |
14589 |
+ NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, |
14590 |
+- 0, FB_VMODE_DOUBLE |
14591 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14592 |
+ }, { |
14593 |
+ /* 480x300 @ 63 Hz, 39.6 kHz hsync */ |
14594 |
+ NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, |
14595 |
+- 0, FB_VMODE_DOUBLE |
14596 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14597 |
+ }, { |
14598 |
+ /* 480x300 @ 72 Hz, 48.0 kHz hsync */ |
14599 |
+ NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, |
14600 |
+- 0, FB_VMODE_DOUBLE |
14601 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14602 |
+ }, { |
14603 |
+ /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */ |
14604 |
+ NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, |
14605 |
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
14606 |
+- FB_VMODE_NONINTERLACED |
14607 |
++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14608 |
+ }, { |
14609 |
+ /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */ |
14610 |
+ NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6, |
14611 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14612 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14613 |
+ }, { |
14614 |
+ /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */ |
14615 |
+ NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, |
14616 |
+- 0, FB_VMODE_NONINTERLACED |
14617 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14618 |
+ }, { |
14619 |
+ /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */ |
14620 |
+ NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, |
14621 |
+- 0, FB_VMODE_NONINTERLACED |
14622 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14623 |
+ }, |
14624 |
+ }; |
14625 |
+ |
14626 |
+diff -urNp linux-2.6.24.4/drivers/video/uvesafb.c linux-2.6.24.4/drivers/video/uvesafb.c |
14627 |
+--- linux-2.6.24.4/drivers/video/uvesafb.c 2008-03-24 14:49:18.000000000 -0400 |
14628 |
++++ linux-2.6.24.4/drivers/video/uvesafb.c 2008-03-26 17:56:56.000000000 -0400 |
14629 |
+@@ -117,7 +117,7 @@ static int uvesafb_helper_start(void) |
14630 |
+ NULL, |
14631 |
+ }; |
14632 |
+ |
14633 |
+- return call_usermodehelper(v86d_path, argv, envp, 1); |
14634 |
++ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC); |
14635 |
+ } |
14636 |
+ |
14637 |
+ /* |
14638 |
+diff -urNp linux-2.6.24.4/drivers/video/vesafb.c linux-2.6.24.4/drivers/video/vesafb.c |
14639 |
+--- linux-2.6.24.4/drivers/video/vesafb.c 2008-03-24 14:49:18.000000000 -0400 |
14640 |
++++ linux-2.6.24.4/drivers/video/vesafb.c 2008-03-26 17:56:56.000000000 -0400 |
14641 |
+@@ -9,6 +9,7 @@ |
14642 |
+ */ |
14643 |
+ |
14644 |
+ #include <linux/module.h> |
14645 |
++#include <linux/moduleloader.h> |
14646 |
+ #include <linux/kernel.h> |
14647 |
+ #include <linux/errno.h> |
14648 |
+ #include <linux/string.h> |
14649 |
+@@ -53,8 +54,8 @@ static int vram_remap __initdata; /* |
14650 |
+ static int vram_total __initdata; /* Set total amount of memory */ |
14651 |
+ static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ |
14652 |
+ static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ |
14653 |
+-static void (*pmi_start)(void) __read_mostly; |
14654 |
+-static void (*pmi_pal) (void) __read_mostly; |
14655 |
++static void (*pmi_start)(void) __read_only; |
14656 |
++static void (*pmi_pal) (void) __read_only; |
14657 |
+ static int depth __read_mostly; |
14658 |
+ static int vga_compat __read_mostly; |
14659 |
+ /* --------------------------------------------------------------------- */ |
14660 |
+@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl |
14661 |
+ unsigned int size_vmode; |
14662 |
+ unsigned int size_remap; |
14663 |
+ unsigned int size_total; |
14664 |
++ void *pmi_code = NULL; |
14665 |
+ |
14666 |
+ if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) |
14667 |
+ return -ENODEV; |
14668 |
+@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl |
14669 |
+ size_remap = size_total; |
14670 |
+ vesafb_fix.smem_len = size_remap; |
14671 |
+ |
14672 |
+-#ifndef __i386__ |
14673 |
+- screen_info.vesapm_seg = 0; |
14674 |
+-#endif |
14675 |
+- |
14676 |
+ if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) { |
14677 |
+ printk(KERN_WARNING |
14678 |
+ "vesafb: cannot reserve video memory at 0x%lx\n", |
14679 |
+@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl |
14680 |
+ printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", |
14681 |
+ vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages); |
14682 |
+ |
14683 |
++#ifdef __i386__ |
14684 |
++ |
14685 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
14686 |
++ pmi_code = module_alloc_exec(screen_info.vesapm_size); |
14687 |
++ if (!pmi_code) |
14688 |
++#elif !defined(CONFIG_PAX_KERNEXEC) |
14689 |
++ if (0) |
14690 |
++#endif |
14691 |
++ |
14692 |
++#endif |
14693 |
++ screen_info.vesapm_seg = 0; |
14694 |
++ |
14695 |
+ if (screen_info.vesapm_seg) { |
14696 |
+- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n", |
14697 |
+- screen_info.vesapm_seg,screen_info.vesapm_off); |
14698 |
++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n", |
14699 |
++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size); |
14700 |
+ } |
14701 |
+ |
14702 |
+ if (screen_info.vesapm_seg < 0xc000) |
14703 |
+@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl |
14704 |
+ |
14705 |
+ if (ypan || pmi_setpal) { |
14706 |
+ unsigned short *pmi_base; |
14707 |
+- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); |
14708 |
+- pmi_start = (void*)((char*)pmi_base + pmi_base[1]); |
14709 |
+- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]); |
14710 |
++ |
14711 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
14712 |
++ unsigned long cr0; |
14713 |
++#endif |
14714 |
++ |
14715 |
++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); |
14716 |
++ |
14717 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
14718 |
++ pax_open_kernel(cr0); |
14719 |
++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size); |
14720 |
++#else |
14721 |
++ pmi_code = pmi_base; |
14722 |
++#endif |
14723 |
++ |
14724 |
++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]); |
14725 |
++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]); |
14726 |
++ |
14727 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
14728 |
++ pmi_start = ktva_ktla(pmi_start); |
14729 |
++ pmi_pal = ktva_ktla(pmi_pal); |
14730 |
++ pax_close_kernel(cr0); |
14731 |
++#endif |
14732 |
++ |
14733 |
+ printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal); |
14734 |
+ if (pmi_base[3]) { |
14735 |
+ printk(KERN_INFO "vesafb: pmi: ports = "); |
14736 |
+@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl |
14737 |
+ info->node, info->fix.id); |
14738 |
+ return 0; |
14739 |
+ err: |
14740 |
++ |
14741 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
14742 |
++ module_free_exec(NULL, pmi_code); |
14743 |
++#endif |
14744 |
++ |
14745 |
+ if (info->screen_base) |
14746 |
+ iounmap(info->screen_base); |
14747 |
+ framebuffer_release(info); |
14748 |
+diff -urNp linux-2.6.24.4/fs/9p/vfs_inode.c linux-2.6.24.4/fs/9p/vfs_inode.c |
14749 |
+--- linux-2.6.24.4/fs/9p/vfs_inode.c 2008-03-24 14:49:18.000000000 -0400 |
14750 |
++++ linux-2.6.24.4/fs/9p/vfs_inode.c 2008-03-26 17:56:56.000000000 -0400 |
14751 |
+@@ -996,7 +996,7 @@ static void *v9fs_vfs_follow_link(struct |
14752 |
+ |
14753 |
+ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) |
14754 |
+ { |
14755 |
+- char *s = nd_get_link(nd); |
14756 |
++ const char *s = nd_get_link(nd); |
14757 |
+ |
14758 |
+ P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s); |
14759 |
+ if (!IS_ERR(s)) |
14760 |
+diff -urNp linux-2.6.24.4/fs/aio.c linux-2.6.24.4/fs/aio.c |
14761 |
+--- linux-2.6.24.4/fs/aio.c 2008-03-24 14:49:18.000000000 -0400 |
14762 |
++++ linux-2.6.24.4/fs/aio.c 2008-03-26 17:56:56.000000000 -0400 |
14763 |
+@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx |
14764 |
+ size += sizeof(struct io_event) * nr_events; |
14765 |
+ nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT; |
14766 |
+ |
14767 |
+- if (nr_pages < 0) |
14768 |
++ if (nr_pages <= 0) |
14769 |
+ return -EINVAL; |
14770 |
+ |
14771 |
+ nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event); |
14772 |
+diff -urNp linux-2.6.24.4/fs/autofs4/symlink.c linux-2.6.24.4/fs/autofs4/symlink.c |
14773 |
+--- linux-2.6.24.4/fs/autofs4/symlink.c 2008-03-24 14:49:18.000000000 -0400 |
14774 |
++++ linux-2.6.24.4/fs/autofs4/symlink.c 2008-03-26 17:56:56.000000000 -0400 |
14775 |
+@@ -15,7 +15,7 @@ |
14776 |
+ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) |
14777 |
+ { |
14778 |
+ struct autofs_info *ino = autofs4_dentry_ino(dentry); |
14779 |
+- nd_set_link(nd, (char *)ino->u.symlink); |
14780 |
++ nd_set_link(nd, ino->u.symlink); |
14781 |
+ return NULL; |
14782 |
+ } |
14783 |
+ |
14784 |
+diff -urNp linux-2.6.24.4/fs/befs/linuxvfs.c linux-2.6.24.4/fs/befs/linuxvfs.c |
14785 |
+--- linux-2.6.24.4/fs/befs/linuxvfs.c 2008-03-24 14:49:18.000000000 -0400 |
14786 |
++++ linux-2.6.24.4/fs/befs/linuxvfs.c 2008-03-26 17:56:56.000000000 -0400 |
14787 |
+@@ -482,7 +482,7 @@ static void befs_put_link(struct dentry |
14788 |
+ { |
14789 |
+ befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); |
14790 |
+ if (befs_ino->i_flags & BEFS_LONG_SYMLINK) { |
14791 |
+- char *p = nd_get_link(nd); |
14792 |
++ const char *p = nd_get_link(nd); |
14793 |
+ if (!IS_ERR(p)) |
14794 |
+ kfree(p); |
14795 |
+ } |
14796 |
+diff -urNp linux-2.6.24.4/fs/binfmt_aout.c linux-2.6.24.4/fs/binfmt_aout.c |
14797 |
+--- linux-2.6.24.4/fs/binfmt_aout.c 2008-03-24 14:49:18.000000000 -0400 |
14798 |
++++ linux-2.6.24.4/fs/binfmt_aout.c 2008-03-26 17:56:56.000000000 -0400 |
14799 |
+@@ -24,6 +24,7 @@ |
14800 |
+ #include <linux/binfmts.h> |
14801 |
+ #include <linux/personality.h> |
14802 |
+ #include <linux/init.h> |
14803 |
++#include <linux/grsecurity.h> |
14804 |
+ |
14805 |
+ #include <asm/system.h> |
14806 |
+ #include <asm/uaccess.h> |
14807 |
+@@ -123,18 +124,22 @@ static int aout_core_dump(long signr, st |
14808 |
+ /* If the size of the dump file exceeds the rlimit, then see what would happen |
14809 |
+ if we wrote the stack, but not the data area. */ |
14810 |
+ #ifdef __sparc__ |
14811 |
++ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1); |
14812 |
+ if ((dump.u_dsize + dump.u_ssize) > limit) |
14813 |
+ dump.u_dsize = 0; |
14814 |
+ #else |
14815 |
++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1); |
14816 |
+ if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit) |
14817 |
+ dump.u_dsize = 0; |
14818 |
+ #endif |
14819 |
+ |
14820 |
+ /* Make sure we have enough room to write the stack and data areas. */ |
14821 |
+ #ifdef __sparc__ |
14822 |
++ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1); |
14823 |
+ if (dump.u_ssize > limit) |
14824 |
+ dump.u_ssize = 0; |
14825 |
+ #else |
14826 |
++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1); |
14827 |
+ if ((dump.u_ssize + 1) * PAGE_SIZE > limit) |
14828 |
+ dump.u_ssize = 0; |
14829 |
+ #endif |
14830 |
+@@ -290,6 +295,8 @@ static int load_aout_binary(struct linux |
14831 |
+ rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; |
14832 |
+ if (rlim >= RLIM_INFINITY) |
14833 |
+ rlim = ~0; |
14834 |
++ |
14835 |
++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1); |
14836 |
+ if (ex.a_data + ex.a_bss > rlim) |
14837 |
+ return -ENOMEM; |
14838 |
+ |
14839 |
+@@ -321,6 +328,28 @@ static int load_aout_binary(struct linux |
14840 |
+ |
14841 |
+ compute_creds(bprm); |
14842 |
+ current->flags &= ~PF_FORKNOEXEC; |
14843 |
++ |
14844 |
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
14845 |
++ current->mm->pax_flags = 0UL; |
14846 |
++#endif |
14847 |
++ |
14848 |
++#ifdef CONFIG_PAX_PAGEEXEC |
14849 |
++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) { |
14850 |
++ current->mm->pax_flags |= MF_PAX_PAGEEXEC; |
14851 |
++ |
14852 |
++#ifdef CONFIG_PAX_EMUTRAMP |
14853 |
++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP) |
14854 |
++ current->mm->pax_flags |= MF_PAX_EMUTRAMP; |
14855 |
++#endif |
14856 |
++ |
14857 |
++#ifdef CONFIG_PAX_MPROTECT |
14858 |
++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT)) |
14859 |
++ current->mm->pax_flags |= MF_PAX_MPROTECT; |
14860 |
++#endif |
14861 |
++ |
14862 |
++ } |
14863 |
++#endif |
14864 |
++ |
14865 |
+ #ifdef __sparc__ |
14866 |
+ if (N_MAGIC(ex) == NMAGIC) { |
14867 |
+ loff_t pos = fd_offset; |
14868 |
+@@ -416,7 +445,7 @@ static int load_aout_binary(struct linux |
14869 |
+ |
14870 |
+ down_write(¤t->mm->mmap_sem); |
14871 |
+ error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, |
14872 |
+- PROT_READ | PROT_WRITE | PROT_EXEC, |
14873 |
++ PROT_READ | PROT_WRITE, |
14874 |
+ MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, |
14875 |
+ fd_offset + ex.a_text); |
14876 |
+ up_write(¤t->mm->mmap_sem); |
14877 |
+diff -urNp linux-2.6.24.4/fs/binfmt_elf.c linux-2.6.24.4/fs/binfmt_elf.c |
14878 |
+--- linux-2.6.24.4/fs/binfmt_elf.c 2008-03-24 14:49:18.000000000 -0400 |
14879 |
++++ linux-2.6.24.4/fs/binfmt_elf.c 2008-03-26 17:56:56.000000000 -0400 |
14880 |
+@@ -39,10 +39,16 @@ |
14881 |
+ #include <linux/random.h> |
14882 |
+ #include <linux/elf.h> |
14883 |
+ #include <linux/utsname.h> |
14884 |
++#include <linux/grsecurity.h> |
14885 |
++ |
14886 |
+ #include <asm/uaccess.h> |
14887 |
+ #include <asm/param.h> |
14888 |
+ #include <asm/page.h> |
14889 |
+ |
14890 |
++#ifdef CONFIG_PAX_SEGMEXEC |
14891 |
++#include <asm/desc.h> |
14892 |
++#endif |
14893 |
++ |
14894 |
+ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); |
14895 |
+ static int load_elf_library(struct file *); |
14896 |
+ static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); |
14897 |
+@@ -84,6 +90,8 @@ static struct linux_binfmt elf_format = |
14898 |
+ |
14899 |
+ static int set_brk(unsigned long start, unsigned long end) |
14900 |
+ { |
14901 |
++ unsigned long e = end; |
14902 |
++ |
14903 |
+ start = ELF_PAGEALIGN(start); |
14904 |
+ end = ELF_PAGEALIGN(end); |
14905 |
+ if (end > start) { |
14906 |
+@@ -94,7 +102,7 @@ static int set_brk(unsigned long start, |
14907 |
+ if (BAD_ADDR(addr)) |
14908 |
+ return addr; |
14909 |
+ } |
14910 |
+- current->mm->start_brk = current->mm->brk = end; |
14911 |
++ current->mm->start_brk = current->mm->brk = e; |
14912 |
+ return 0; |
14913 |
+ } |
14914 |
+ |
14915 |
+@@ -328,10 +336,9 @@ static unsigned long load_elf_interp(str |
14916 |
+ { |
14917 |
+ struct elf_phdr *elf_phdata; |
14918 |
+ struct elf_phdr *eppnt; |
14919 |
+- unsigned long load_addr = 0; |
14920 |
+- int load_addr_set = 0; |
14921 |
++ unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE; |
14922 |
+ unsigned long last_bss = 0, elf_bss = 0; |
14923 |
+- unsigned long error = ~0UL; |
14924 |
++ unsigned long error = -EINVAL; |
14925 |
+ int retval, i, size; |
14926 |
+ |
14927 |
+ /* First of all, some simple consistency checks */ |
14928 |
+@@ -370,66 +377,86 @@ static unsigned long load_elf_interp(str |
14929 |
+ goto out_close; |
14930 |
+ } |
14931 |
+ |
14932 |
++#ifdef CONFIG_PAX_SEGMEXEC |
14933 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) |
14934 |
++ task_size = SEGMEXEC_TASK_SIZE; |
14935 |
++#endif |
14936 |
++ |
14937 |
+ eppnt = elf_phdata; |
14938 |
++ min_addr = task_size; |
14939 |
++ max_addr = 0; |
14940 |
++ error = -ENOMEM; |
14941 |
++ |
14942 |
+ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { |
14943 |
+- if (eppnt->p_type == PT_LOAD) { |
14944 |
+- int elf_type = MAP_PRIVATE | MAP_DENYWRITE; |
14945 |
+- int elf_prot = 0; |
14946 |
+- unsigned long vaddr = 0; |
14947 |
+- unsigned long k, map_addr; |
14948 |
+- |
14949 |
+- if (eppnt->p_flags & PF_R) |
14950 |
+- elf_prot = PROT_READ; |
14951 |
+- if (eppnt->p_flags & PF_W) |
14952 |
+- elf_prot |= PROT_WRITE; |
14953 |
+- if (eppnt->p_flags & PF_X) |
14954 |
+- elf_prot |= PROT_EXEC; |
14955 |
+- vaddr = eppnt->p_vaddr; |
14956 |
+- if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) |
14957 |
+- elf_type |= MAP_FIXED; |
14958 |
+- |
14959 |
+- map_addr = elf_map(interpreter, load_addr + vaddr, |
14960 |
+- eppnt, elf_prot, elf_type); |
14961 |
+- error = map_addr; |
14962 |
+- if (BAD_ADDR(map_addr)) |
14963 |
+- goto out_close; |
14964 |
+- |
14965 |
+- if (!load_addr_set && |
14966 |
+- interp_elf_ex->e_type == ET_DYN) { |
14967 |
+- load_addr = map_addr - ELF_PAGESTART(vaddr); |
14968 |
+- load_addr_set = 1; |
14969 |
+- } |
14970 |
++ if (eppnt->p_type != PT_LOAD) |
14971 |
++ continue; |
14972 |
+ |
14973 |
+- /* |
14974 |
+- * Check to see if the section's size will overflow the |
14975 |
+- * allowed task size. Note that p_filesz must always be |
14976 |
+- * <= p_memsize so it's only necessary to check p_memsz. |
14977 |
+- */ |
14978 |
+- k = load_addr + eppnt->p_vaddr; |
14979 |
+- if (BAD_ADDR(k) || |
14980 |
+- eppnt->p_filesz > eppnt->p_memsz || |
14981 |
+- eppnt->p_memsz > TASK_SIZE || |
14982 |
+- TASK_SIZE - eppnt->p_memsz < k) { |
14983 |
+- error = -ENOMEM; |
14984 |
+- goto out_close; |
14985 |
+- } |
14986 |
++ /* |
14987 |
++ * Check to see if the section's size will overflow the |
14988 |
++ * allowed task size. Note that p_filesz must always be |
14989 |
++ * <= p_memsize so it is only necessary to check p_memsz. |
14990 |
++ */ |
14991 |
++ if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz) |
14992 |
++ goto out_close; |
14993 |
+ |
14994 |
+- /* |
14995 |
+- * Find the end of the file mapping for this phdr, and |
14996 |
+- * keep track of the largest address we see for this. |
14997 |
+- */ |
14998 |
+- k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; |
14999 |
+- if (k > elf_bss) |
15000 |
+- elf_bss = k; |
15001 |
++ if (min_addr > ELF_PAGESTART(eppnt->p_vaddr)) |
15002 |
++ min_addr = ELF_PAGESTART(eppnt->p_vaddr); |
15003 |
++ if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz)) |
15004 |
++ max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz); |
15005 |
++ } |
15006 |
++ if (min_addr >= max_addr || max_addr > task_size) |
15007 |
++ goto out_close; |
15008 |
+ |
15009 |
+- /* |
15010 |
+- * Do the same thing for the memory mapping - between |
15011 |
+- * elf_bss and last_bss is the bss section. |
15012 |
+- */ |
15013 |
+- k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; |
15014 |
+- if (k > last_bss) |
15015 |
+- last_bss = k; |
15016 |
+- } |
15017 |
++ if (interp_elf_ex->e_type == ET_DYN) { |
15018 |
++ load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE); |
15019 |
++ |
15020 |
++ if (load_addr >= task_size) |
15021 |
++ goto out_close; |
15022 |
++ |
15023 |
++ load_addr -= min_addr; |
15024 |
++ } |
15025 |
++ |
15026 |
++ eppnt = elf_phdata; |
15027 |
++ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { |
15028 |
++ int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED; |
15029 |
++ int elf_prot = 0; |
15030 |
++ unsigned long vaddr = 0; |
15031 |
++ unsigned long k, map_addr; |
15032 |
++ |
15033 |
++ if (eppnt->p_type != PT_LOAD) |
15034 |
++ continue; |
15035 |
++ |
15036 |
++ if (eppnt->p_flags & PF_R) |
15037 |
++ elf_prot = PROT_READ; |
15038 |
++ if (eppnt->p_flags & PF_W) |
15039 |
++ elf_prot |= PROT_WRITE; |
15040 |
++ if (eppnt->p_flags & PF_X) |
15041 |
++ elf_prot |= PROT_EXEC; |
15042 |
++ vaddr = eppnt->p_vaddr; |
15043 |
++ |
15044 |
++ map_addr = elf_map(interpreter, load_addr + vaddr, |
15045 |
++ eppnt, elf_prot, elf_type); |
15046 |
++ error = map_addr; |
15047 |
++ if (BAD_ADDR(map_addr)) |
15048 |
++ goto out_close; |
15049 |
++ |
15050 |
++ k = load_addr + eppnt->p_vaddr; |
15051 |
++ |
15052 |
++ /* |
15053 |
++ * Find the end of the file mapping for this phdr, and |
15054 |
++ * keep track of the largest address we see for this. |
15055 |
++ */ |
15056 |
++ k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; |
15057 |
++ if (k > elf_bss) |
15058 |
++ elf_bss = k; |
15059 |
++ |
15060 |
++ /* |
15061 |
++ * Do the same thing for the memory mapping - between |
15062 |
++ * elf_bss and last_bss is the bss section. |
15063 |
++ */ |
15064 |
++ k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; |
15065 |
++ if (k > last_bss) |
15066 |
++ last_bss = k; |
15067 |
+ } |
15068 |
+ |
15069 |
+ /* |
15070 |
+@@ -457,6 +484,8 @@ static unsigned long load_elf_interp(str |
15071 |
+ |
15072 |
+ *interp_load_addr = load_addr; |
15073 |
+ error = ((unsigned long)interp_elf_ex->e_entry) + load_addr; |
15074 |
++ if (BAD_ADDR(error)) |
15075 |
++ error = -EFAULT; |
15076 |
+ |
15077 |
+ out_close: |
15078 |
+ kfree(elf_phdata); |
15079 |
+@@ -467,7 +496,7 @@ out: |
15080 |
+ static unsigned long load_aout_interp(struct exec *interp_ex, |
15081 |
+ struct file *interpreter) |
15082 |
+ { |
15083 |
+- unsigned long text_data, elf_entry = ~0UL; |
15084 |
++ unsigned long text_data, elf_entry = -EINVAL; |
15085 |
+ char __user * addr; |
15086 |
+ loff_t offset; |
15087 |
+ |
15088 |
+@@ -510,6 +539,177 @@ out: |
15089 |
+ return elf_entry; |
15090 |
+ } |
15091 |
+ |
15092 |
++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE) |
15093 |
++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata) |
15094 |
++{ |
15095 |
++ unsigned long pax_flags = 0UL; |
15096 |
++ |
15097 |
++#ifdef CONFIG_PAX_PAGEEXEC |
15098 |
++ if (elf_phdata->p_flags & PF_PAGEEXEC) |
15099 |
++ pax_flags |= MF_PAX_PAGEEXEC; |
15100 |
++#endif |
15101 |
++ |
15102 |
++#ifdef CONFIG_PAX_SEGMEXEC |
15103 |
++ if (elf_phdata->p_flags & PF_SEGMEXEC) |
15104 |
++ pax_flags |= MF_PAX_SEGMEXEC; |
15105 |
++#endif |
15106 |
++ |
15107 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC) |
15108 |
++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
15109 |
++ if (nx_enabled) |
15110 |
++ pax_flags &= ~MF_PAX_SEGMEXEC; |
15111 |
++ else |
15112 |
++ pax_flags &= ~MF_PAX_PAGEEXEC; |
15113 |
++ } |
15114 |
++#endif |
15115 |
++ |
15116 |
++#ifdef CONFIG_PAX_EMUTRAMP |
15117 |
++ if (elf_phdata->p_flags & PF_EMUTRAMP) |
15118 |
++ pax_flags |= MF_PAX_EMUTRAMP; |
15119 |
++#endif |
15120 |
++ |
15121 |
++#ifdef CONFIG_PAX_MPROTECT |
15122 |
++ if (elf_phdata->p_flags & PF_MPROTECT) |
15123 |
++ pax_flags |= MF_PAX_MPROTECT; |
15124 |
++#endif |
15125 |
++ |
15126 |
++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) |
15127 |
++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP)) |
15128 |
++ pax_flags |= MF_PAX_RANDMMAP; |
15129 |
++#endif |
15130 |
++ |
15131 |
++ return pax_flags; |
15132 |
++} |
15133 |
++#endif |
15134 |
++ |
15135 |
++#ifdef CONFIG_PAX_PT_PAX_FLAGS |
15136 |
++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata) |
15137 |
++{ |
15138 |
++ unsigned long pax_flags = 0UL; |
15139 |
++ |
15140 |
++#ifdef CONFIG_PAX_PAGEEXEC |
15141 |
++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC)) |
15142 |
++ pax_flags |= MF_PAX_PAGEEXEC; |
15143 |
++#endif |
15144 |
++ |
15145 |
++#ifdef CONFIG_PAX_SEGMEXEC |
15146 |
++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC)) |
15147 |
++ pax_flags |= MF_PAX_SEGMEXEC; |
15148 |
++#endif |
15149 |
++ |
15150 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC) |
15151 |
++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
15152 |
++ if (nx_enabled) |
15153 |
++ pax_flags &= ~MF_PAX_SEGMEXEC; |
15154 |
++ else |
15155 |
++ pax_flags &= ~MF_PAX_PAGEEXEC; |
15156 |
++ } |
15157 |
++#endif |
15158 |
++ |
15159 |
++#ifdef CONFIG_PAX_EMUTRAMP |
15160 |
++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP)) |
15161 |
++ pax_flags |= MF_PAX_EMUTRAMP; |
15162 |
++#endif |
15163 |
++ |
15164 |
++#ifdef CONFIG_PAX_MPROTECT |
15165 |
++ if (!(elf_phdata->p_flags & PF_NOMPROTECT)) |
15166 |
++ pax_flags |= MF_PAX_MPROTECT; |
15167 |
++#endif |
15168 |
++ |
15169 |
++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) |
15170 |
++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP)) |
15171 |
++ pax_flags |= MF_PAX_RANDMMAP; |
15172 |
++#endif |
15173 |
++ |
15174 |
++ return pax_flags; |
15175 |
++} |
15176 |
++#endif |
15177 |
++ |
15178 |
++#ifdef CONFIG_PAX_EI_PAX |
15179 |
++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex) |
15180 |
++{ |
15181 |
++ unsigned long pax_flags = 0UL; |
15182 |
++ |
15183 |
++#ifdef CONFIG_PAX_PAGEEXEC |
15184 |
++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC)) |
15185 |
++ pax_flags |= MF_PAX_PAGEEXEC; |
15186 |
++#endif |
15187 |
++ |
15188 |
++#ifdef CONFIG_PAX_SEGMEXEC |
15189 |
++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) |
15190 |
++ pax_flags |= MF_PAX_SEGMEXEC; |
15191 |
++#endif |
15192 |
++ |
15193 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC) |
15194 |
++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
15195 |
++ if (nx_enabled) |
15196 |
++ pax_flags &= ~MF_PAX_SEGMEXEC; |
15197 |
++ else |
15198 |
++ pax_flags &= ~MF_PAX_PAGEEXEC; |
15199 |
++ } |
15200 |
++#endif |
15201 |
++ |
15202 |
++#ifdef CONFIG_PAX_EMUTRAMP |
15203 |
++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP)) |
15204 |
++ pax_flags |= MF_PAX_EMUTRAMP; |
15205 |
++#endif |
15206 |
++ |
15207 |
++#ifdef CONFIG_PAX_MPROTECT |
15208 |
++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT)) |
15209 |
++ pax_flags |= MF_PAX_MPROTECT; |
15210 |
++#endif |
15211 |
++ |
15212 |
++#ifdef CONFIG_PAX_ASLR |
15213 |
++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP)) |
15214 |
++ pax_flags |= MF_PAX_RANDMMAP; |
15215 |
++#endif |
15216 |
++ |
15217 |
++ return pax_flags; |
15218 |
++} |
15219 |
++#endif |
15220 |
++ |
15221 |
++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) |
15222 |
++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata) |
15223 |
++{ |
15224 |
++ unsigned long pax_flags = 0UL; |
15225 |
++ |
15226 |
++#ifdef CONFIG_PAX_PT_PAX_FLAGS |
15227 |
++ unsigned long i; |
15228 |
++#endif |
15229 |
++ |
15230 |
++#ifdef CONFIG_PAX_EI_PAX |
15231 |
++ pax_flags = pax_parse_ei_pax(elf_ex); |
15232 |
++#endif |
15233 |
++ |
15234 |
++#ifdef CONFIG_PAX_PT_PAX_FLAGS |
15235 |
++ for (i = 0UL; i < elf_ex->e_phnum; i++) |
15236 |
++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) { |
15237 |
++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) || |
15238 |
++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) || |
15239 |
++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) || |
15240 |
++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) || |
15241 |
++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP))) |
15242 |
++ return -EINVAL; |
15243 |
++ |
15244 |
++#ifdef CONFIG_PAX_SOFTMODE |
15245 |
++ if (pax_softmode) |
15246 |
++ pax_flags = pax_parse_softmode(&elf_phdata[i]); |
15247 |
++ else |
15248 |
++#endif |
15249 |
++ |
15250 |
++ pax_flags = pax_parse_hardmode(&elf_phdata[i]); |
15251 |
++ break; |
15252 |
++ } |
15253 |
++#endif |
15254 |
++ |
15255 |
++ if (0 > pax_check_flags(&pax_flags)) |
15256 |
++ return -EINVAL; |
15257 |
++ |
15258 |
++ current->mm->pax_flags = pax_flags; |
15259 |
++ return 0; |
15260 |
++} |
15261 |
++#endif |
15262 |
++ |
15263 |
+ /* |
15264 |
+ * These are the functions used to load ELF style executables and shared |
15265 |
+ * libraries. There is no binary dependent code anywhere else. |
15266 |
+@@ -547,7 +747,7 @@ static int load_elf_binary(struct linux_ |
15267 |
+ char * elf_interpreter = NULL; |
15268 |
+ unsigned int interpreter_type = INTERPRETER_NONE; |
15269 |
+ unsigned char ibcs2_interpreter = 0; |
15270 |
+- unsigned long error; |
15271 |
++ unsigned long error = 0; |
15272 |
+ struct elf_phdr *elf_ppnt, *elf_phdata; |
15273 |
+ unsigned long elf_bss, elf_brk; |
15274 |
+ int elf_exec_fileno; |
15275 |
+@@ -559,12 +759,12 @@ static int load_elf_binary(struct linux_ |
15276 |
+ char passed_fileno[6]; |
15277 |
+ struct files_struct *files; |
15278 |
+ int executable_stack = EXSTACK_DEFAULT; |
15279 |
+- unsigned long def_flags = 0; |
15280 |
+ struct { |
15281 |
+ struct elfhdr elf_ex; |
15282 |
+ struct elfhdr interp_elf_ex; |
15283 |
+ struct exec interp_ex; |
15284 |
+ } *loc; |
15285 |
++ unsigned long task_size = TASK_SIZE; |
15286 |
+ |
15287 |
+ loc = kmalloc(sizeof(*loc), GFP_KERNEL); |
15288 |
+ if (!loc) { |
15289 |
+@@ -799,14 +999,89 @@ static int load_elf_binary(struct linux_ |
15290 |
+ |
15291 |
+ /* OK, This is the point of no return */ |
15292 |
+ current->flags &= ~PF_FORKNOEXEC; |
15293 |
+- current->mm->def_flags = def_flags; |
15294 |
++ |
15295 |
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
15296 |
++ current->mm->pax_flags = 0UL; |
15297 |
++#endif |
15298 |
++ |
15299 |
++#ifdef CONFIG_PAX_DLRESOLVE |
15300 |
++ current->mm->call_dl_resolve = 0UL; |
15301 |
++#endif |
15302 |
++ |
15303 |
++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT) |
15304 |
++ current->mm->call_syscall = 0UL; |
15305 |
++#endif |
15306 |
++ |
15307 |
++#ifdef CONFIG_PAX_ASLR |
15308 |
++ current->mm->delta_mmap = 0UL; |
15309 |
++ current->mm->delta_stack = 0UL; |
15310 |
++#endif |
15311 |
++ |
15312 |
++ current->mm->def_flags = 0; |
15313 |
++ |
15314 |
++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) |
15315 |
++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) { |
15316 |
++ send_sig(SIGKILL, current, 0); |
15317 |
++ goto out_free_dentry; |
15318 |
++ } |
15319 |
++#endif |
15320 |
++ |
15321 |
++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS |
15322 |
++ pax_set_initial_flags(bprm); |
15323 |
++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS) |
15324 |
++ if (pax_set_initial_flags_func) |
15325 |
++ (pax_set_initial_flags_func)(bprm); |
15326 |
++#endif |
15327 |
++ |
15328 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
15329 |
++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) { |
15330 |
++ current->mm->context.user_cs_limit = PAGE_SIZE; |
15331 |
++ current->mm->def_flags |= VM_PAGEEXEC; |
15332 |
++ } |
15333 |
++#endif |
15334 |
++ |
15335 |
++#ifdef CONFIG_PAX_SEGMEXEC |
15336 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { |
15337 |
++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE; |
15338 |
++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE; |
15339 |
++ task_size = SEGMEXEC_TASK_SIZE; |
15340 |
++ } |
15341 |
++#endif |
15342 |
++ |
15343 |
++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC) |
15344 |
++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
15345 |
++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu()); |
15346 |
++ put_cpu_no_resched(); |
15347 |
++ } |
15348 |
++#endif |
15349 |
++ |
15350 |
++#ifdef CONFIG_PAX_ASLR |
15351 |
++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) { |
15352 |
++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT; |
15353 |
++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT; |
15354 |
++ } |
15355 |
++#endif |
15356 |
++ |
15357 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
15358 |
++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) |
15359 |
++ executable_stack = EXSTACK_DEFAULT; |
15360 |
++#endif |
15361 |
+ |
15362 |
+ /* Do this immediately, since STACK_TOP as used in setup_arg_pages |
15363 |
+ may depend on the personality. */ |
15364 |
+ SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter); |
15365 |
++ |
15366 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
15367 |
++ if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))) |
15368 |
++#endif |
15369 |
++ |
15370 |
+ if (elf_read_implies_exec(loc->elf_ex, executable_stack)) |
15371 |
+ current->personality |= READ_IMPLIES_EXEC; |
15372 |
+ |
15373 |
++#ifdef CONFIG_PAX_ASLR |
15374 |
++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP)) |
15375 |
++#endif |
15376 |
++ |
15377 |
+ if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) |
15378 |
+ current->flags |= PF_RANDOMIZE; |
15379 |
+ arch_pick_mmap_layout(current->mm); |
15380 |
+@@ -882,6 +1157,20 @@ static int load_elf_binary(struct linux_ |
15381 |
+ * might try to exec. This is because the brk will |
15382 |
+ * follow the loader, and is not movable. */ |
15383 |
+ load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); |
15384 |
++ |
15385 |
++#ifdef CONFIG_PAX_RANDMMAP |
15386 |
++ /* PaX: randomize base address at the default exe base if requested */ |
15387 |
++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) { |
15388 |
++#ifdef CONFIG_SPARC64 |
15389 |
++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1); |
15390 |
++#else |
15391 |
++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT; |
15392 |
++#endif |
15393 |
++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias); |
15394 |
++ elf_flags |= MAP_FIXED; |
15395 |
++ } |
15396 |
++#endif |
15397 |
++ |
15398 |
+ } |
15399 |
+ |
15400 |
+ error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, |
15401 |
+@@ -914,9 +1203,9 @@ static int load_elf_binary(struct linux_ |
15402 |
+ * allowed task size. Note that p_filesz must always be |
15403 |
+ * <= p_memsz so it is only necessary to check p_memsz. |
15404 |
+ */ |
15405 |
+- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz || |
15406 |
+- elf_ppnt->p_memsz > TASK_SIZE || |
15407 |
+- TASK_SIZE - elf_ppnt->p_memsz < k) { |
15408 |
++ if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz || |
15409 |
++ elf_ppnt->p_memsz > task_size || |
15410 |
++ task_size - elf_ppnt->p_memsz < k) { |
15411 |
+ /* set_brk can never work. Avoid overflows. */ |
15412 |
+ send_sig(SIGKILL, current, 0); |
15413 |
+ retval = -EINVAL; |
15414 |
+@@ -944,6 +1233,11 @@ static int load_elf_binary(struct linux_ |
15415 |
+ start_data += load_bias; |
15416 |
+ end_data += load_bias; |
15417 |
+ |
15418 |
++#ifdef CONFIG_PAX_RANDMMAP |
15419 |
++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) |
15420 |
++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4); |
15421 |
++#endif |
15422 |
++ |
15423 |
+ /* Calling set_brk effectively mmaps the pages that we need |
15424 |
+ * for the bss and break sections. We must do this before |
15425 |
+ * mapping in the interpreter, to make sure it doesn't wind |
15426 |
+@@ -955,9 +1249,11 @@ static int load_elf_binary(struct linux_ |
15427 |
+ goto out_free_dentry; |
15428 |
+ } |
15429 |
+ if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { |
15430 |
+- send_sig(SIGSEGV, current, 0); |
15431 |
+- retval = -EFAULT; /* Nobody gets to see this, but.. */ |
15432 |
+- goto out_free_dentry; |
15433 |
++ /* |
15434 |
++ * This bss-zeroing can fail if the ELF |
15435 |
++ * file specifies odd protections. So |
15436 |
++ * we don't check the return value |
15437 |
++ */ |
15438 |
+ } |
15439 |
+ |
15440 |
+ if (elf_interpreter) { |
15441 |
+@@ -1194,8 +1490,10 @@ static int dump_seek(struct file *file, |
15442 |
+ unsigned long n = off; |
15443 |
+ if (n > PAGE_SIZE) |
15444 |
+ n = PAGE_SIZE; |
15445 |
+- if (!dump_write(file, buf, n)) |
15446 |
++ if (!dump_write(file, buf, n)) { |
15447 |
++ free_page((unsigned long)buf); |
15448 |
+ return 0; |
15449 |
++ } |
15450 |
+ off -= n; |
15451 |
+ } |
15452 |
+ free_page((unsigned long)buf); |
15453 |
+@@ -1207,7 +1505,7 @@ static int dump_seek(struct file *file, |
15454 |
+ * Decide what to dump of a segment, part, all or none. |
15455 |
+ */ |
15456 |
+ static unsigned long vma_dump_size(struct vm_area_struct *vma, |
15457 |
+- unsigned long mm_flags) |
15458 |
++ unsigned long mm_flags, long signr) |
15459 |
+ { |
15460 |
+ /* The vma can be set up to tell us the answer directly. */ |
15461 |
+ if (vma->vm_flags & VM_ALWAYSDUMP) |
15462 |
+@@ -1233,7 +1531,7 @@ static unsigned long vma_dump_size(struc |
15463 |
+ if (vma->vm_file == NULL) |
15464 |
+ return 0; |
15465 |
+ |
15466 |
+- if (FILTER(MAPPED_PRIVATE)) |
15467 |
++ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE)) |
15468 |
+ goto whole; |
15469 |
+ |
15470 |
+ /* |
15471 |
+@@ -1319,8 +1617,11 @@ static int writenote(struct memelfnote * |
15472 |
+ #undef DUMP_WRITE |
15473 |
+ |
15474 |
+ #define DUMP_WRITE(addr, nr) \ |
15475 |
++ do { \ |
15476 |
++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \ |
15477 |
+ if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ |
15478 |
+- goto end_coredump; |
15479 |
++ goto end_coredump; \ |
15480 |
++ } while (0); |
15481 |
+ #define DUMP_SEEK(off) \ |
15482 |
+ if (!dump_seek(file, (off))) \ |
15483 |
+ goto end_coredump; |
15484 |
+@@ -1710,7 +2011,7 @@ static int elf_core_dump(long signr, str |
15485 |
+ phdr.p_offset = offset; |
15486 |
+ phdr.p_vaddr = vma->vm_start; |
15487 |
+ phdr.p_paddr = 0; |
15488 |
+- phdr.p_filesz = vma_dump_size(vma, mm_flags); |
15489 |
++ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr); |
15490 |
+ phdr.p_memsz = vma->vm_end - vma->vm_start; |
15491 |
+ offset += phdr.p_filesz; |
15492 |
+ phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; |
15493 |
+@@ -1753,7 +2054,7 @@ static int elf_core_dump(long signr, str |
15494 |
+ unsigned long addr; |
15495 |
+ unsigned long end; |
15496 |
+ |
15497 |
+- end = vma->vm_start + vma_dump_size(vma, mm_flags); |
15498 |
++ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr); |
15499 |
+ |
15500 |
+ for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { |
15501 |
+ struct page *page; |
15502 |
+@@ -1773,6 +2074,7 @@ static int elf_core_dump(long signr, str |
15503 |
+ flush_cache_page(vma, addr, |
15504 |
+ page_to_pfn(page)); |
15505 |
+ kaddr = kmap(page); |
15506 |
++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1); |
15507 |
+ if ((size += PAGE_SIZE) > limit || |
15508 |
+ !dump_write(file, kaddr, |
15509 |
+ PAGE_SIZE)) { |
15510 |
+diff -urNp linux-2.6.24.4/fs/binfmt_flat.c linux-2.6.24.4/fs/binfmt_flat.c |
15511 |
+--- linux-2.6.24.4/fs/binfmt_flat.c 2008-03-24 14:49:18.000000000 -0400 |
15512 |
++++ linux-2.6.24.4/fs/binfmt_flat.c 2008-03-26 17:56:56.000000000 -0400 |
15513 |
+@@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b |
15514 |
+ realdatastart = (unsigned long) -ENOMEM; |
15515 |
+ printk("Unable to allocate RAM for process data, errno %d\n", |
15516 |
+ (int)-realdatastart); |
15517 |
++ down_write(¤t->mm->mmap_sem); |
15518 |
+ do_munmap(current->mm, textpos, text_len); |
15519 |
++ up_write(¤t->mm->mmap_sem); |
15520 |
+ ret = realdatastart; |
15521 |
+ goto err; |
15522 |
+ } |
15523 |
+@@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b |
15524 |
+ } |
15525 |
+ if (result >= (unsigned long)-4096) { |
15526 |
+ printk("Unable to read data+bss, errno %d\n", (int)-result); |
15527 |
++ down_write(¤t->mm->mmap_sem); |
15528 |
+ do_munmap(current->mm, textpos, text_len); |
15529 |
+ do_munmap(current->mm, realdatastart, data_len + extra); |
15530 |
++ up_write(¤t->mm->mmap_sem); |
15531 |
+ ret = result; |
15532 |
+ goto err; |
15533 |
+ } |
15534 |
+@@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b |
15535 |
+ } |
15536 |
+ if (result >= (unsigned long)-4096) { |
15537 |
+ printk("Unable to read code+data+bss, errno %d\n",(int)-result); |
15538 |
++ down_write(¤t->mm->mmap_sem); |
15539 |
+ do_munmap(current->mm, textpos, text_len + data_len + extra + |
15540 |
+ MAX_SHARED_LIBS * sizeof(unsigned long)); |
15541 |
++ up_write(¤t->mm->mmap_sem); |
15542 |
+ ret = result; |
15543 |
+ goto err; |
15544 |
+ } |
15545 |
+diff -urNp linux-2.6.24.4/fs/binfmt_misc.c linux-2.6.24.4/fs/binfmt_misc.c |
15546 |
+--- linux-2.6.24.4/fs/binfmt_misc.c 2008-03-24 14:49:18.000000000 -0400 |
15547 |
++++ linux-2.6.24.4/fs/binfmt_misc.c 2008-03-26 17:56:56.000000000 -0400 |
15548 |
+@@ -113,9 +113,11 @@ static int load_misc_binary(struct linux |
15549 |
+ struct files_struct *files = NULL; |
15550 |
+ |
15551 |
+ retval = -ENOEXEC; |
15552 |
+- if (!enabled) |
15553 |
++ if (!enabled || bprm->misc) |
15554 |
+ goto _ret; |
15555 |
+ |
15556 |
++ bprm->misc++; |
15557 |
++ |
15558 |
+ /* to keep locking time low, we copy the interpreter string */ |
15559 |
+ read_lock(&entries_lock); |
15560 |
+ fmt = check_file(bprm); |
15561 |
+@@ -720,7 +722,7 @@ static int bm_fill_super(struct super_bl |
15562 |
+ static struct tree_descr bm_files[] = { |
15563 |
+ [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, |
15564 |
+ [3] = {"register", &bm_register_operations, S_IWUSR}, |
15565 |
+- /* last one */ {""} |
15566 |
++ /* last one */ {"", NULL, 0} |
15567 |
+ }; |
15568 |
+ int err = simple_fill_super(sb, 0x42494e4d, bm_files); |
15569 |
+ if (!err) |
15570 |
+diff -urNp linux-2.6.24.4/fs/buffer.c linux-2.6.24.4/fs/buffer.c |
15571 |
+--- linux-2.6.24.4/fs/buffer.c 2008-03-24 14:49:18.000000000 -0400 |
15572 |
++++ linux-2.6.24.4/fs/buffer.c 2008-03-26 17:56:56.000000000 -0400 |
15573 |
+@@ -41,6 +41,7 @@ |
15574 |
+ #include <linux/bitops.h> |
15575 |
+ #include <linux/mpage.h> |
15576 |
+ #include <linux/bit_spinlock.h> |
15577 |
++#include <linux/grsecurity.h> |
15578 |
+ |
15579 |
+ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); |
15580 |
+ |
15581 |
+@@ -2170,6 +2171,7 @@ int generic_cont_expand_simple(struct in |
15582 |
+ |
15583 |
+ err = -EFBIG; |
15584 |
+ limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; |
15585 |
++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1); |
15586 |
+ if (limit != RLIM_INFINITY && size > (loff_t)limit) { |
15587 |
+ send_sig(SIGXFSZ, current, 0); |
15588 |
+ goto out; |
15589 |
+diff -urNp linux-2.6.24.4/fs/cifs/cifs_uniupr.h linux-2.6.24.4/fs/cifs/cifs_uniupr.h |
15590 |
+--- linux-2.6.24.4/fs/cifs/cifs_uniupr.h 2008-03-24 14:49:18.000000000 -0400 |
15591 |
++++ linux-2.6.24.4/fs/cifs/cifs_uniupr.h 2008-03-26 17:56:56.000000000 -0400 |
15592 |
+@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa |
15593 |
+ {0x0490, 0x04cc, UniCaseRangeU0490}, |
15594 |
+ {0x1e00, 0x1ffc, UniCaseRangeU1e00}, |
15595 |
+ {0xff40, 0xff5a, UniCaseRangeUff40}, |
15596 |
+- {0} |
15597 |
++ {0, 0, NULL} |
15598 |
+ }; |
15599 |
+ #endif |
15600 |
+ |
15601 |
+diff -urNp linux-2.6.24.4/fs/cifs/link.c linux-2.6.24.4/fs/cifs/link.c |
15602 |
+--- linux-2.6.24.4/fs/cifs/link.c 2008-03-24 14:49:18.000000000 -0400 |
15603 |
++++ linux-2.6.24.4/fs/cifs/link.c 2008-03-26 17:56:56.000000000 -0400 |
15604 |
+@@ -355,7 +355,7 @@ cifs_readlink(struct dentry *direntry, c |
15605 |
+ |
15606 |
+ void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie) |
15607 |
+ { |
15608 |
+- char *p = nd_get_link(nd); |
15609 |
++ const char *p = nd_get_link(nd); |
15610 |
+ if (!IS_ERR(p)) |
15611 |
+ kfree(p); |
15612 |
+ } |
15613 |
+diff -urNp linux-2.6.24.4/fs/compat.c linux-2.6.24.4/fs/compat.c |
15614 |
+--- linux-2.6.24.4/fs/compat.c 2008-03-24 14:49:18.000000000 -0400 |
15615 |
++++ linux-2.6.24.4/fs/compat.c 2008-03-26 17:56:56.000000000 -0400 |
15616 |
+@@ -50,6 +50,7 @@ |
15617 |
+ #include <linux/poll.h> |
15618 |
+ #include <linux/mm.h> |
15619 |
+ #include <linux/eventpoll.h> |
15620 |
++#include <linux/grsecurity.h> |
15621 |
+ |
15622 |
+ #include <asm/uaccess.h> |
15623 |
+ #include <asm/mmu_context.h> |
15624 |
+@@ -1300,14 +1301,12 @@ static int compat_copy_strings(int argc, |
15625 |
+ if (!kmapped_page || kpos != (pos & PAGE_MASK)) { |
15626 |
+ struct page *page; |
15627 |
+ |
15628 |
+-#ifdef CONFIG_STACK_GROWSUP |
15629 |
+ ret = expand_stack_downwards(bprm->vma, pos); |
15630 |
+ if (ret < 0) { |
15631 |
+ /* We've exceed the stack rlimit. */ |
15632 |
+ ret = -E2BIG; |
15633 |
+ goto out; |
15634 |
+ } |
15635 |
+-#endif |
15636 |
+ ret = get_user_pages(current, bprm->mm, pos, |
15637 |
+ 1, 1, 1, &page, NULL); |
15638 |
+ if (ret <= 0) { |
15639 |
+@@ -1353,6 +1352,11 @@ int compat_do_execve(char * filename, |
15640 |
+ compat_uptr_t __user *envp, |
15641 |
+ struct pt_regs * regs) |
15642 |
+ { |
15643 |
++#ifdef CONFIG_GRKERNSEC |
15644 |
++ struct file *old_exec_file; |
15645 |
++ struct acl_subject_label *old_acl; |
15646 |
++ struct rlimit old_rlim[RLIM_NLIMITS]; |
15647 |
++#endif |
15648 |
+ struct linux_binprm *bprm; |
15649 |
+ struct file *file; |
15650 |
+ int retval; |
15651 |
+@@ -1373,6 +1377,14 @@ int compat_do_execve(char * filename, |
15652 |
+ bprm->filename = filename; |
15653 |
+ bprm->interp = filename; |
15654 |
+ |
15655 |
++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1); |
15656 |
++ retval = -EAGAIN; |
15657 |
++ if (gr_handle_nproc()) |
15658 |
++ goto out_file; |
15659 |
++ retval = -EACCES; |
15660 |
++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) |
15661 |
++ goto out_file; |
15662 |
++ |
15663 |
+ retval = bprm_mm_init(bprm); |
15664 |
+ if (retval) |
15665 |
+ goto out_file; |
15666 |
+@@ -1406,8 +1418,36 @@ int compat_do_execve(char * filename, |
15667 |
+ if (retval < 0) |
15668 |
+ goto out; |
15669 |
+ |
15670 |
++ if (!gr_tpe_allow(file)) { |
15671 |
++ retval = -EACCES; |
15672 |
++ goto out; |
15673 |
++ } |
15674 |
++ |
15675 |
++ if (gr_check_crash_exec(file)) { |
15676 |
++ retval = -EACCES; |
15677 |
++ goto out; |
15678 |
++ } |
15679 |
++ |
15680 |
++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); |
15681 |
++ |
15682 |
++ gr_handle_exec_args(bprm, (char __user * __user *)argv); |
15683 |
++ |
15684 |
++#ifdef CONFIG_GRKERNSEC |
15685 |
++ old_acl = current->acl; |
15686 |
++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim)); |
15687 |
++ old_exec_file = current->exec_file; |
15688 |
++ get_file(file); |
15689 |
++ current->exec_file = file; |
15690 |
++#endif |
15691 |
++ |
15692 |
++ gr_set_proc_label(file->f_dentry, file->f_vfsmnt); |
15693 |
++ |
15694 |
+ retval = search_binary_handler(bprm, regs); |
15695 |
+ if (retval >= 0) { |
15696 |
++#ifdef CONFIG_GRKERNSEC |
15697 |
++ if (old_exec_file) |
15698 |
++ fput(old_exec_file); |
15699 |
++#endif |
15700 |
+ /* execve success */ |
15701 |
+ security_bprm_free(bprm); |
15702 |
+ acct_update_integrals(current); |
15703 |
+@@ -1415,6 +1455,13 @@ int compat_do_execve(char * filename, |
15704 |
+ return retval; |
15705 |
+ } |
15706 |
+ |
15707 |
++#ifdef CONFIG_GRKERNSEC |
15708 |
++ current->acl = old_acl; |
15709 |
++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim)); |
15710 |
++ fput(current->exec_file); |
15711 |
++ current->exec_file = old_exec_file; |
15712 |
++#endif |
15713 |
++ |
15714 |
+ out: |
15715 |
+ if (bprm->security) |
15716 |
+ security_bprm_free(bprm); |
15717 |
+diff -urNp linux-2.6.24.4/fs/compat_ioctl.c linux-2.6.24.4/fs/compat_ioctl.c |
15718 |
+--- linux-2.6.24.4/fs/compat_ioctl.c 2008-03-24 14:49:18.000000000 -0400 |
15719 |
++++ linux-2.6.24.4/fs/compat_ioctl.c 2008-03-26 17:56:56.000000000 -0400 |
15720 |
+@@ -1890,15 +1890,15 @@ struct ioctl_trans { |
15721 |
+ }; |
15722 |
+ |
15723 |
+ #define HANDLE_IOCTL(cmd,handler) \ |
15724 |
+- { (cmd), (ioctl_trans_handler_t)(handler) }, |
15725 |
++ { (cmd), (ioctl_trans_handler_t)(handler), NULL }, |
15726 |
+ |
15727 |
+ /* pointer to compatible structure or no argument */ |
15728 |
+ #define COMPATIBLE_IOCTL(cmd) \ |
15729 |
+- { (cmd), do_ioctl32_pointer }, |
15730 |
++ { (cmd), do_ioctl32_pointer, NULL }, |
15731 |
+ |
15732 |
+ /* argument is an unsigned long integer, not a pointer */ |
15733 |
+ #define ULONG_IOCTL(cmd) \ |
15734 |
+- { (cmd), (ioctl_trans_handler_t)sys_ioctl }, |
15735 |
++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL }, |
15736 |
+ |
15737 |
+ /* ioctl should not be warned about even if it's not implemented. |
15738 |
+ Valid reasons to use this: |
15739 |
+diff -urNp linux-2.6.24.4/fs/debugfs/inode.c linux-2.6.24.4/fs/debugfs/inode.c |
15740 |
+--- linux-2.6.24.4/fs/debugfs/inode.c 2008-03-24 14:49:18.000000000 -0400 |
15741 |
++++ linux-2.6.24.4/fs/debugfs/inode.c 2008-03-26 17:56:56.000000000 -0400 |
15742 |
+@@ -125,7 +125,7 @@ static inline int debugfs_positive(struc |
15743 |
+ |
15744 |
+ static int debug_fill_super(struct super_block *sb, void *data, int silent) |
15745 |
+ { |
15746 |
+- static struct tree_descr debug_files[] = {{""}}; |
15747 |
++ static struct tree_descr debug_files[] = {{"", NULL, 0}}; |
15748 |
+ |
15749 |
+ return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files); |
15750 |
+ } |
15751 |
+diff -urNp linux-2.6.24.4/fs/exec.c linux-2.6.24.4/fs/exec.c |
15752 |
+--- linux-2.6.24.4/fs/exec.c 2008-03-24 14:49:18.000000000 -0400 |
15753 |
++++ linux-2.6.24.4/fs/exec.c 2008-03-26 18:53:27.000000000 -0400 |
15754 |
+@@ -51,6 +51,8 @@ |
15755 |
+ #include <linux/tsacct_kern.h> |
15756 |
+ #include <linux/cn_proc.h> |
15757 |
+ #include <linux/audit.h> |
15758 |
++#include <linux/random.h> |
15759 |
++#include <linux/grsecurity.h> |
15760 |
+ |
15761 |
+ #include <asm/uaccess.h> |
15762 |
+ #include <asm/mmu_context.h> |
15763 |
+@@ -60,6 +62,11 @@ |
15764 |
+ #include <linux/kmod.h> |
15765 |
+ #endif |
15766 |
+ |
15767 |
++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS |
15768 |
++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm); |
15769 |
++EXPORT_SYMBOL(pax_set_initial_flags_func); |
15770 |
++#endif |
15771 |
++ |
15772 |
+ int core_uses_pid; |
15773 |
+ char core_pattern[CORENAME_MAX_SIZE] = "core"; |
15774 |
+ int suid_dumpable = 0; |
15775 |
+@@ -158,18 +165,10 @@ static struct page *get_arg_page(struct |
15776 |
+ int write) |
15777 |
+ { |
15778 |
+ struct page *page; |
15779 |
+- int ret; |
15780 |
+ |
15781 |
+-#ifdef CONFIG_STACK_GROWSUP |
15782 |
+- if (write) { |
15783 |
+- ret = expand_stack_downwards(bprm->vma, pos); |
15784 |
+- if (ret < 0) |
15785 |
+- return NULL; |
15786 |
+- } |
15787 |
+-#endif |
15788 |
+- ret = get_user_pages(current, bprm->mm, pos, |
15789 |
+- 1, write, 1, &page, NULL); |
15790 |
+- if (ret <= 0) |
15791 |
++ if (0 > expand_stack_downwards(bprm->vma, pos)) |
15792 |
++ return NULL; |
15793 |
++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL)) |
15794 |
+ return NULL; |
15795 |
+ |
15796 |
+ if (write) { |
15797 |
+@@ -234,6 +233,11 @@ static int __bprm_mm_init(struct linux_b |
15798 |
+ vma->vm_start = vma->vm_end - PAGE_SIZE; |
15799 |
+ |
15800 |
+ vma->vm_flags = VM_STACK_FLAGS; |
15801 |
++ |
15802 |
++#ifdef CONFIG_PAX_SEGMEXEC |
15803 |
++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC); |
15804 |
++#endif |
15805 |
++ |
15806 |
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
15807 |
+ err = insert_vm_struct(mm, vma); |
15808 |
+ if (err) { |
15809 |
+@@ -246,6 +250,11 @@ static int __bprm_mm_init(struct linux_b |
15810 |
+ |
15811 |
+ bprm->p = vma->vm_end - sizeof(void *); |
15812 |
+ |
15813 |
++#ifdef CONFIG_PAX_RANDUSTACK |
15814 |
++ if (randomize_va_space) |
15815 |
++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK; |
15816 |
++#endif |
15817 |
++ |
15818 |
+ return 0; |
15819 |
+ |
15820 |
+ err: |
15821 |
+@@ -369,7 +378,7 @@ static int count(char __user * __user * |
15822 |
+ if (!p) |
15823 |
+ break; |
15824 |
+ argv++; |
15825 |
+- if(++i > max) |
15826 |
++ if (++i > max) |
15827 |
+ return -E2BIG; |
15828 |
+ cond_resched(); |
15829 |
+ } |
15830 |
+@@ -509,6 +518,10 @@ static int shift_arg_pages(struct vm_are |
15831 |
+ if (vma != find_vma(mm, new_start)) |
15832 |
+ return -EFAULT; |
15833 |
+ |
15834 |
++#ifdef CONFIG_PAX_SEGMEXEC |
15835 |
++ BUG_ON(pax_find_mirror_vma(vma)); |
15836 |
++#endif |
15837 |
++ |
15838 |
+ /* |
15839 |
+ * cover the whole range: [new_start, old_end) |
15840 |
+ */ |
15841 |
+@@ -597,6 +610,14 @@ int setup_arg_pages(struct linux_binprm |
15842 |
+ bprm->exec -= stack_shift; |
15843 |
+ |
15844 |
+ down_write(&mm->mmap_sem); |
15845 |
++ |
15846 |
++ /* Move stack pages down in memory. */ |
15847 |
++ if (stack_shift) { |
15848 |
++ ret = shift_arg_pages(vma, stack_shift); |
15849 |
++ if (ret) |
15850 |
++ goto out_unlock; |
15851 |
++ } |
15852 |
++ |
15853 |
+ vm_flags = vma->vm_flags; |
15854 |
+ |
15855 |
+ /* |
15856 |
+@@ -608,23 +629,28 @@ int setup_arg_pages(struct linux_binprm |
15857 |
+ vm_flags |= VM_EXEC; |
15858 |
+ else if (executable_stack == EXSTACK_DISABLE_X) |
15859 |
+ vm_flags &= ~VM_EXEC; |
15860 |
++ else |
15861 |
++ vm_flags = VM_STACK_FLAGS; |
15862 |
+ vm_flags |= mm->def_flags; |
15863 |
+ |
15864 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
15865 |
++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
15866 |
++ vm_flags &= ~VM_EXEC; |
15867 |
++ |
15868 |
++#ifdef CONFIG_PAX_MPROTECT |
15869 |
++ if (mm->pax_flags & MF_PAX_MPROTECT) |
15870 |
++ vm_flags &= ~VM_MAYEXEC; |
15871 |
++#endif |
15872 |
++ |
15873 |
++ } |
15874 |
++#endif |
15875 |
++ |
15876 |
+ ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end, |
15877 |
+ vm_flags); |
15878 |
+ if (ret) |
15879 |
+ goto out_unlock; |
15880 |
+ BUG_ON(prev != vma); |
15881 |
+ |
15882 |
+- /* Move stack pages down in memory. */ |
15883 |
+- if (stack_shift) { |
15884 |
+- ret = shift_arg_pages(vma, stack_shift); |
15885 |
+- if (ret) { |
15886 |
+- up_write(&mm->mmap_sem); |
15887 |
+- return ret; |
15888 |
+- } |
15889 |
+- } |
15890 |
+- |
15891 |
+ #ifdef CONFIG_STACK_GROWSUP |
15892 |
+ stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE; |
15893 |
+ #else |
15894 |
+@@ -636,7 +662,7 @@ int setup_arg_pages(struct linux_binprm |
15895 |
+ |
15896 |
+ out_unlock: |
15897 |
+ up_write(&mm->mmap_sem); |
15898 |
+- return 0; |
15899 |
++ return ret; |
15900 |
+ } |
15901 |
+ EXPORT_SYMBOL(setup_arg_pages); |
15902 |
+ |
15903 |
+@@ -655,7 +681,7 @@ struct file *open_exec(const char *name) |
15904 |
+ struct inode *inode = nd.dentry->d_inode; |
15905 |
+ file = ERR_PTR(-EACCES); |
15906 |
+ if (S_ISREG(inode->i_mode)) { |
15907 |
+- int err = vfs_permission(&nd, MAY_EXEC); |
15908 |
++ err = vfs_permission(&nd, MAY_EXEC); |
15909 |
+ file = ERR_PTR(err); |
15910 |
+ if (!err) { |
15911 |
+ file = nameidata_to_filp(&nd, O_RDONLY); |
15912 |
+@@ -1293,6 +1319,11 @@ int do_execve(char * filename, |
15913 |
+ char __user *__user *envp, |
15914 |
+ struct pt_regs * regs) |
15915 |
+ { |
15916 |
++#ifdef CONFIG_GRKERNSEC |
15917 |
++ struct file *old_exec_file; |
15918 |
++ struct acl_subject_label *old_acl; |
15919 |
++ struct rlimit old_rlim[RLIM_NLIMITS]; |
15920 |
++#endif |
15921 |
+ struct linux_binprm *bprm; |
15922 |
+ struct file *file; |
15923 |
+ unsigned long env_p; |
15924 |
+@@ -1308,6 +1339,20 @@ int do_execve(char * filename, |
15925 |
+ if (IS_ERR(file)) |
15926 |
+ goto out_kfree; |
15927 |
+ |
15928 |
++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1); |
15929 |
++ |
15930 |
++ if (gr_handle_nproc()) { |
15931 |
++ allow_write_access(file); |
15932 |
++ fput(file); |
15933 |
++ return -EAGAIN; |
15934 |
++ } |
15935 |
++ |
15936 |
++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) { |
15937 |
++ allow_write_access(file); |
15938 |
++ fput(file); |
15939 |
++ return -EACCES; |
15940 |
++ } |
15941 |
++ |
15942 |
+ sched_exec(); |
15943 |
+ |
15944 |
+ bprm->file = file; |
15945 |
+@@ -1349,8 +1394,38 @@ int do_execve(char * filename, |
15946 |
+ goto out; |
15947 |
+ bprm->argv_len = env_p - bprm->p; |
15948 |
+ |
15949 |
++ if (!gr_tpe_allow(file)) { |
15950 |
++ retval = -EACCES; |
15951 |
++ goto out; |
15952 |
++ } |
15953 |
++ |
15954 |
++ if (gr_check_crash_exec(file)) { |
15955 |
++ retval = -EACCES; |
15956 |
++ goto out; |
15957 |
++ } |
15958 |
++ |
15959 |
++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); |
15960 |
++ |
15961 |
++ gr_handle_exec_args(bprm, argv); |
15962 |
++ |
15963 |
++#ifdef CONFIG_GRKERNSEC |
15964 |
++ old_acl = current->acl; |
15965 |
++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim)); |
15966 |
++ old_exec_file = current->exec_file; |
15967 |
++ get_file(file); |
15968 |
++ current->exec_file = file; |
15969 |
++#endif |
15970 |
++ |
15971 |
++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt); |
15972 |
++ if (retval < 0) |
15973 |
++ goto out_fail; |
15974 |
++ |
15975 |
+ retval = search_binary_handler(bprm,regs); |
15976 |
+ if (retval >= 0) { |
15977 |
++#ifdef CONFIG_GRKERNSEC |
15978 |
++ if (old_exec_file) |
15979 |
++ fput(old_exec_file); |
15980 |
++#endif |
15981 |
+ /* execve success */ |
15982 |
+ free_arg_pages(bprm); |
15983 |
+ security_bprm_free(bprm); |
15984 |
+@@ -1359,6 +1434,14 @@ int do_execve(char * filename, |
15985 |
+ return retval; |
15986 |
+ } |
15987 |
+ |
15988 |
++out_fail: |
15989 |
++#ifdef CONFIG_GRKERNSEC |
15990 |
++ current->acl = old_acl; |
15991 |
++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim)); |
15992 |
++ fput(current->exec_file); |
15993 |
++ current->exec_file = old_exec_file; |
15994 |
++#endif |
15995 |
++ |
15996 |
+ out: |
15997 |
+ free_arg_pages(bprm); |
15998 |
+ if (bprm->security) |
15999 |
+@@ -1523,6 +1606,114 @@ out: |
16000 |
+ return ispipe; |
16001 |
+ } |
16002 |
+ |
16003 |
++int pax_check_flags(unsigned long *flags) |
16004 |
++{ |
16005 |
++ int retval = 0; |
16006 |
++ |
16007 |
++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC) |
16008 |
++ if (*flags & MF_PAX_SEGMEXEC) |
16009 |
++ { |
16010 |
++ *flags &= ~MF_PAX_SEGMEXEC; |
16011 |
++ retval = -EINVAL; |
16012 |
++ } |
16013 |
++#endif |
16014 |
++ |
16015 |
++ if ((*flags & MF_PAX_PAGEEXEC) |
16016 |
++ |
16017 |
++#ifdef CONFIG_PAX_PAGEEXEC |
16018 |
++ && (*flags & MF_PAX_SEGMEXEC) |
16019 |
++#endif |
16020 |
++ |
16021 |
++ ) |
16022 |
++ { |
16023 |
++ *flags &= ~MF_PAX_PAGEEXEC; |
16024 |
++ retval = -EINVAL; |
16025 |
++ } |
16026 |
++ |
16027 |
++ if ((*flags & MF_PAX_MPROTECT) |
16028 |
++ |
16029 |
++#ifdef CONFIG_PAX_MPROTECT |
16030 |
++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) |
16031 |
++#endif |
16032 |
++ |
16033 |
++ ) |
16034 |
++ { |
16035 |
++ *flags &= ~MF_PAX_MPROTECT; |
16036 |
++ retval = -EINVAL; |
16037 |
++ } |
16038 |
++ |
16039 |
++ if ((*flags & MF_PAX_EMUTRAMP) |
16040 |
++ |
16041 |
++#ifdef CONFIG_PAX_EMUTRAMP |
16042 |
++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) |
16043 |
++#endif |
16044 |
++ |
16045 |
++ ) |
16046 |
++ { |
16047 |
++ *flags &= ~MF_PAX_EMUTRAMP; |
16048 |
++ retval = -EINVAL; |
16049 |
++ } |
16050 |
++ |
16051 |
++ return retval; |
16052 |
++} |
16053 |
++ |
16054 |
++EXPORT_SYMBOL(pax_check_flags); |
16055 |
++ |
16056 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
16057 |
++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp) |
16058 |
++{ |
16059 |
++ struct task_struct *tsk = current; |
16060 |
++ struct mm_struct *mm = current->mm; |
16061 |
++ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL); |
16062 |
++ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL); |
16063 |
++ char *path_exec = NULL; |
16064 |
++ char *path_fault = NULL; |
16065 |
++ unsigned long start = 0UL, end = 0UL, offset = 0UL; |
16066 |
++ |
16067 |
++ if (buffer_exec && buffer_fault) { |
16068 |
++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL; |
16069 |
++ |
16070 |
++ down_read(&mm->mmap_sem); |
16071 |
++ vma = mm->mmap; |
16072 |
++ while (vma && (!vma_exec || !vma_fault)) { |
16073 |
++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) |
16074 |
++ vma_exec = vma; |
16075 |
++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end) |
16076 |
++ vma_fault = vma; |
16077 |
++ vma = vma->vm_next; |
16078 |
++ } |
16079 |
++ if (vma_exec) { |
16080 |
++ path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE); |
16081 |
++ if (IS_ERR(path_exec)) |
16082 |
++ path_exec = "<path too long>"; |
16083 |
++ } |
16084 |
++ if (vma_fault) { |
16085 |
++ start = vma_fault->vm_start; |
16086 |
++ end = vma_fault->vm_end; |
16087 |
++ offset = vma_fault->vm_pgoff << PAGE_SHIFT; |
16088 |
++ if (vma_fault->vm_file) { |
16089 |
++ path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE); |
16090 |
++ if (IS_ERR(path_fault)) |
16091 |
++ path_fault = "<path too long>"; |
16092 |
++ } else |
16093 |
++ path_fault = "<anonymous mapping>"; |
16094 |
++ } |
16095 |
++ up_read(&mm->mmap_sem); |
16096 |
++ } |
16097 |
++ if (tsk->signal->curr_ip) |
16098 |
++ 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); |
16099 |
++ else |
16100 |
++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset); |
16101 |
++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, " |
16102 |
++ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk), |
16103 |
++ tsk->uid, tsk->euid, pc, sp); |
16104 |
++ free_page((unsigned long)buffer_exec); |
16105 |
++ free_page((unsigned long)buffer_fault); |
16106 |
++ pax_report_insns(pc, sp); |
16107 |
++ do_coredump(SIGKILL, SIGKILL, regs); |
16108 |
++} |
16109 |
++#endif |
16110 |
++ |
16111 |
+ static void zap_process(struct task_struct *start) |
16112 |
+ { |
16113 |
+ struct task_struct *t; |
16114 |
+@@ -1720,6 +1911,10 @@ int do_coredump(long signr, int exit_cod |
16115 |
+ */ |
16116 |
+ clear_thread_flag(TIF_SIGPENDING); |
16117 |
+ |
16118 |
++ if (signr == SIGKILL || signr == SIGILL) |
16119 |
++ gr_handle_brute_attach(current); |
16120 |
++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1); |
16121 |
++ |
16122 |
+ /* |
16123 |
+ * lock_kernel() because format_corename() is controlled by sysctl, which |
16124 |
+ * uses lock_kernel() |
16125 |
+@@ -1740,6 +1935,8 @@ int do_coredump(long signr, int exit_cod |
16126 |
+ |
16127 |
+ if (ispipe) { |
16128 |
+ helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); |
16129 |
++ if (!helper_argv) |
16130 |
++ goto fail_unlock; |
16131 |
+ /* Terminate the string before the first option */ |
16132 |
+ delimit = strchr(corename, ' '); |
16133 |
+ if (delimit) |
16134 |
+diff -urNp linux-2.6.24.4/fs/ext2/balloc.c linux-2.6.24.4/fs/ext2/balloc.c |
16135 |
+--- linux-2.6.24.4/fs/ext2/balloc.c 2008-03-24 14:49:18.000000000 -0400 |
16136 |
++++ linux-2.6.24.4/fs/ext2/balloc.c 2008-03-26 17:56:56.000000000 -0400 |
16137 |
+@@ -1127,7 +1127,7 @@ static int ext2_has_free_blocks(struct e |
16138 |
+ |
16139 |
+ free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
16140 |
+ root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); |
16141 |
+- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && |
16142 |
++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) && |
16143 |
+ sbi->s_resuid != current->fsuid && |
16144 |
+ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { |
16145 |
+ return 0; |
16146 |
+diff -urNp linux-2.6.24.4/fs/ext3/balloc.c linux-2.6.24.4/fs/ext3/balloc.c |
16147 |
+--- linux-2.6.24.4/fs/ext3/balloc.c 2008-03-24 14:49:18.000000000 -0400 |
16148 |
++++ linux-2.6.24.4/fs/ext3/balloc.c 2008-03-26 17:56:56.000000000 -0400 |
16149 |
+@@ -1359,7 +1359,7 @@ static int ext3_has_free_blocks(struct e |
16150 |
+ |
16151 |
+ free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
16152 |
+ root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); |
16153 |
+- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && |
16154 |
++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) && |
16155 |
+ sbi->s_resuid != current->fsuid && |
16156 |
+ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { |
16157 |
+ return 0; |
16158 |
+diff -urNp linux-2.6.24.4/fs/ext3/namei.c linux-2.6.24.4/fs/ext3/namei.c |
16159 |
+--- linux-2.6.24.4/fs/ext3/namei.c 2008-03-24 14:49:18.000000000 -0400 |
16160 |
++++ linux-2.6.24.4/fs/ext3/namei.c 2008-03-26 17:56:56.000000000 -0400 |
16161 |
+@@ -1181,9 +1181,9 @@ static struct ext3_dir_entry_2 *do_split |
16162 |
+ u32 hash2; |
16163 |
+ struct dx_map_entry *map; |
16164 |
+ char *data1 = (*bh)->b_data, *data2; |
16165 |
+- unsigned split, move, size, i; |
16166 |
++ unsigned split, move, size; |
16167 |
+ struct ext3_dir_entry_2 *de = NULL, *de2; |
16168 |
+- int err = 0; |
16169 |
++ int i, err = 0; |
16170 |
+ |
16171 |
+ bh2 = ext3_append (handle, dir, &newblock, &err); |
16172 |
+ if (!(bh2)) { |
16173 |
+diff -urNp linux-2.6.24.4/fs/ext3/xattr.c linux-2.6.24.4/fs/ext3/xattr.c |
16174 |
+--- linux-2.6.24.4/fs/ext3/xattr.c 2008-03-24 14:49:18.000000000 -0400 |
16175 |
++++ linux-2.6.24.4/fs/ext3/xattr.c 2008-03-26 17:56:56.000000000 -0400 |
16176 |
+@@ -89,8 +89,8 @@ |
16177 |
+ printk("\n"); \ |
16178 |
+ } while (0) |
16179 |
+ #else |
16180 |
+-# define ea_idebug(f...) |
16181 |
+-# define ea_bdebug(f...) |
16182 |
++# define ea_idebug(f...) do {} while (0) |
16183 |
++# define ea_bdebug(f...) do {} while (0) |
16184 |
+ #endif |
16185 |
+ |
16186 |
+ static void ext3_xattr_cache_insert(struct buffer_head *); |
16187 |
+diff -urNp linux-2.6.24.4/fs/ext4/balloc.c linux-2.6.24.4/fs/ext4/balloc.c |
16188 |
+--- linux-2.6.24.4/fs/ext4/balloc.c 2008-03-24 14:49:18.000000000 -0400 |
16189 |
++++ linux-2.6.24.4/fs/ext4/balloc.c 2008-03-26 17:56:56.000000000 -0400 |
16190 |
+@@ -1479,7 +1479,7 @@ static int ext4_has_free_blocks(struct e |
16191 |
+ |
16192 |
+ free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
16193 |
+ root_blocks = ext4_r_blocks_count(sbi->s_es); |
16194 |
+- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && |
16195 |
++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) && |
16196 |
+ sbi->s_resuid != current->fsuid && |
16197 |
+ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { |
16198 |
+ return 0; |
16199 |
+diff -urNp linux-2.6.24.4/fs/ext4/namei.c linux-2.6.24.4/fs/ext4/namei.c |
16200 |
+--- linux-2.6.24.4/fs/ext4/namei.c 2008-03-24 14:49:18.000000000 -0400 |
16201 |
++++ linux-2.6.24.4/fs/ext4/namei.c 2008-03-26 17:56:56.000000000 -0400 |
16202 |
+@@ -1178,9 +1178,9 @@ static struct ext4_dir_entry_2 *do_split |
16203 |
+ u32 hash2; |
16204 |
+ struct dx_map_entry *map; |
16205 |
+ char *data1 = (*bh)->b_data, *data2; |
16206 |
+- unsigned split, move, size, i; |
16207 |
++ unsigned split, move, size; |
16208 |
+ struct ext4_dir_entry_2 *de = NULL, *de2; |
16209 |
+- int err = 0; |
16210 |
++ int i, err = 0; |
16211 |
+ |
16212 |
+ bh2 = ext4_append (handle, dir, &newblock, &err); |
16213 |
+ if (!(bh2)) { |
16214 |
+diff -urNp linux-2.6.24.4/fs/fcntl.c linux-2.6.24.4/fs/fcntl.c |
16215 |
+--- linux-2.6.24.4/fs/fcntl.c 2008-03-24 14:49:18.000000000 -0400 |
16216 |
++++ linux-2.6.24.4/fs/fcntl.c 2008-03-26 17:56:56.000000000 -0400 |
16217 |
+@@ -19,6 +19,7 @@ |
16218 |
+ #include <linux/signal.h> |
16219 |
+ #include <linux/rcupdate.h> |
16220 |
+ #include <linux/pid_namespace.h> |
16221 |
++#include <linux/grsecurity.h> |
16222 |
+ |
16223 |
+ #include <asm/poll.h> |
16224 |
+ #include <asm/siginfo.h> |
16225 |
+@@ -64,6 +65,7 @@ static int locate_fd(struct files_struct |
16226 |
+ struct fdtable *fdt; |
16227 |
+ |
16228 |
+ error = -EINVAL; |
16229 |
++ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0); |
16230 |
+ if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) |
16231 |
+ goto out; |
16232 |
+ |
16233 |
+@@ -83,6 +85,7 @@ repeat: |
16234 |
+ fdt->max_fds, start); |
16235 |
+ |
16236 |
+ error = -EMFILE; |
16237 |
++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0); |
16238 |
+ if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) |
16239 |
+ goto out; |
16240 |
+ |
16241 |
+@@ -144,6 +147,8 @@ asmlinkage long sys_dup2(unsigned int ol |
16242 |
+ struct files_struct * files = current->files; |
16243 |
+ struct fdtable *fdt; |
16244 |
+ |
16245 |
++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0); |
16246 |
++ |
16247 |
+ spin_lock(&files->file_lock); |
16248 |
+ if (!(file = fcheck(oldfd))) |
16249 |
+ goto out_unlock; |
16250 |
+@@ -463,7 +468,8 @@ static inline int sigio_perm(struct task |
16251 |
+ return (((fown->euid == 0) || |
16252 |
+ (fown->euid == p->suid) || (fown->euid == p->uid) || |
16253 |
+ (fown->uid == p->suid) || (fown->uid == p->uid)) && |
16254 |
+- !security_file_send_sigiotask(p, fown, sig)); |
16255 |
++ !security_file_send_sigiotask(p, fown, sig) && |
16256 |
++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p)); |
16257 |
+ } |
16258 |
+ |
16259 |
+ static void send_sigio_to_task(struct task_struct *p, |
16260 |
+diff -urNp linux-2.6.24.4/fs/fuse/control.c linux-2.6.24.4/fs/fuse/control.c |
16261 |
+--- linux-2.6.24.4/fs/fuse/control.c 2008-03-24 14:49:18.000000000 -0400 |
16262 |
++++ linux-2.6.24.4/fs/fuse/control.c 2008-03-26 17:56:56.000000000 -0400 |
16263 |
+@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co |
16264 |
+ |
16265 |
+ static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent) |
16266 |
+ { |
16267 |
+- struct tree_descr empty_descr = {""}; |
16268 |
++ struct tree_descr empty_descr = {"", NULL, 0}; |
16269 |
+ struct fuse_conn *fc; |
16270 |
+ int err; |
16271 |
+ |
16272 |
+diff -urNp linux-2.6.24.4/fs/fuse/dir.c linux-2.6.24.4/fs/fuse/dir.c |
16273 |
+--- linux-2.6.24.4/fs/fuse/dir.c 2008-03-24 14:49:18.000000000 -0400 |
16274 |
++++ linux-2.6.24.4/fs/fuse/dir.c 2008-03-26 17:56:56.000000000 -0400 |
16275 |
+@@ -1030,7 +1030,7 @@ static char *read_link(struct dentry *de |
16276 |
+ return link; |
16277 |
+ } |
16278 |
+ |
16279 |
+-static void free_link(char *link) |
16280 |
++static void free_link(const char *link) |
16281 |
+ { |
16282 |
+ if (!IS_ERR(link)) |
16283 |
+ free_page((unsigned long) link); |
16284 |
+diff -urNp linux-2.6.24.4/fs/hfs/inode.c linux-2.6.24.4/fs/hfs/inode.c |
16285 |
+--- linux-2.6.24.4/fs/hfs/inode.c 2008-03-24 14:49:18.000000000 -0400 |
16286 |
++++ linux-2.6.24.4/fs/hfs/inode.c 2008-03-26 17:56:56.000000000 -0400 |
16287 |
+@@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode, |
16288 |
+ |
16289 |
+ if (S_ISDIR(main_inode->i_mode)) { |
16290 |
+ if (fd.entrylength < sizeof(struct hfs_cat_dir)) |
16291 |
+- /* panic? */; |
16292 |
++ {/* panic? */} |
16293 |
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, |
16294 |
+ sizeof(struct hfs_cat_dir)); |
16295 |
+ if (rec.type != HFS_CDR_DIR || |
16296 |
+@@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode, |
16297 |
+ sizeof(struct hfs_cat_file)); |
16298 |
+ } else { |
16299 |
+ if (fd.entrylength < sizeof(struct hfs_cat_file)) |
16300 |
+- /* panic? */; |
16301 |
++ {/* panic? */} |
16302 |
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, |
16303 |
+ sizeof(struct hfs_cat_file)); |
16304 |
+ if (rec.type != HFS_CDR_FIL || |
16305 |
+diff -urNp linux-2.6.24.4/fs/hfsplus/inode.c linux-2.6.24.4/fs/hfsplus/inode.c |
16306 |
+--- linux-2.6.24.4/fs/hfsplus/inode.c 2008-03-24 14:49:18.000000000 -0400 |
16307 |
++++ linux-2.6.24.4/fs/hfsplus/inode.c 2008-03-26 17:56:56.000000000 -0400 |
16308 |
+@@ -422,7 +422,7 @@ int hfsplus_cat_read_inode(struct inode |
16309 |
+ struct hfsplus_cat_folder *folder = &entry.folder; |
16310 |
+ |
16311 |
+ if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) |
16312 |
+- /* panic? */; |
16313 |
++ {/* panic? */} |
16314 |
+ hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, |
16315 |
+ sizeof(struct hfsplus_cat_folder)); |
16316 |
+ hfsplus_get_perms(inode, &folder->permissions, 1); |
16317 |
+@@ -439,7 +439,7 @@ int hfsplus_cat_read_inode(struct inode |
16318 |
+ struct hfsplus_cat_file *file = &entry.file; |
16319 |
+ |
16320 |
+ if (fd->entrylength < sizeof(struct hfsplus_cat_file)) |
16321 |
+- /* panic? */; |
16322 |
++ {/* panic? */} |
16323 |
+ hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, |
16324 |
+ sizeof(struct hfsplus_cat_file)); |
16325 |
+ |
16326 |
+@@ -495,7 +495,7 @@ int hfsplus_cat_write_inode(struct inode |
16327 |
+ struct hfsplus_cat_folder *folder = &entry.folder; |
16328 |
+ |
16329 |
+ if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) |
16330 |
+- /* panic? */; |
16331 |
++ {/* panic? */} |
16332 |
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, |
16333 |
+ sizeof(struct hfsplus_cat_folder)); |
16334 |
+ /* simple node checks? */ |
16335 |
+@@ -517,7 +517,7 @@ int hfsplus_cat_write_inode(struct inode |
16336 |
+ struct hfsplus_cat_file *file = &entry.file; |
16337 |
+ |
16338 |
+ if (fd.entrylength < sizeof(struct hfsplus_cat_file)) |
16339 |
+- /* panic? */; |
16340 |
++ {/* panic? */} |
16341 |
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, |
16342 |
+ sizeof(struct hfsplus_cat_file)); |
16343 |
+ hfsplus_inode_write_fork(inode, &file->data_fork); |
16344 |
+diff -urNp linux-2.6.24.4/fs/jffs2/debug.h linux-2.6.24.4/fs/jffs2/debug.h |
16345 |
+--- linux-2.6.24.4/fs/jffs2/debug.h 2008-03-24 14:49:18.000000000 -0400 |
16346 |
++++ linux-2.6.24.4/fs/jffs2/debug.h 2008-03-26 17:56:56.000000000 -0400 |
16347 |
+@@ -51,13 +51,13 @@ |
16348 |
+ #if CONFIG_JFFS2_FS_DEBUG > 0 |
16349 |
+ #define D1(x) x |
16350 |
+ #else |
16351 |
+-#define D1(x) |
16352 |
++#define D1(x) do {} while (0); |
16353 |
+ #endif |
16354 |
+ |
16355 |
+ #if CONFIG_JFFS2_FS_DEBUG > 1 |
16356 |
+ #define D2(x) x |
16357 |
+ #else |
16358 |
+-#define D2(x) |
16359 |
++#define D2(x) do {} while (0); |
16360 |
+ #endif |
16361 |
+ |
16362 |
+ /* The prefixes of JFFS2 messages */ |
16363 |
+@@ -113,68 +113,68 @@ |
16364 |
+ #ifdef JFFS2_DBG_READINODE_MESSAGES |
16365 |
+ #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16366 |
+ #else |
16367 |
+-#define dbg_readinode(fmt, ...) |
16368 |
++#define dbg_readinode(fmt, ...) do {} while (0) |
16369 |
+ #endif |
16370 |
+ |
16371 |
+ /* Fragtree build debugging messages */ |
16372 |
+ #ifdef JFFS2_DBG_FRAGTREE_MESSAGES |
16373 |
+ #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16374 |
+ #else |
16375 |
+-#define dbg_fragtree(fmt, ...) |
16376 |
++#define dbg_fragtree(fmt, ...) do {} while (0) |
16377 |
+ #endif |
16378 |
+ #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES |
16379 |
+ #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16380 |
+ #else |
16381 |
+-#define dbg_fragtree2(fmt, ...) |
16382 |
++#define dbg_fragtree2(fmt, ...) do {} while (0) |
16383 |
+ #endif |
16384 |
+ |
16385 |
+ /* Directory entry list manilulation debugging messages */ |
16386 |
+ #ifdef JFFS2_DBG_DENTLIST_MESSAGES |
16387 |
+ #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16388 |
+ #else |
16389 |
+-#define dbg_dentlist(fmt, ...) |
16390 |
++#define dbg_dentlist(fmt, ...) do {} while (0) |
16391 |
+ #endif |
16392 |
+ |
16393 |
+ /* Print the messages about manipulating node_refs */ |
16394 |
+ #ifdef JFFS2_DBG_NODEREF_MESSAGES |
16395 |
+ #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16396 |
+ #else |
16397 |
+-#define dbg_noderef(fmt, ...) |
16398 |
++#define dbg_noderef(fmt, ...) do {} while (0) |
16399 |
+ #endif |
16400 |
+ |
16401 |
+ /* Manipulations with the list of inodes (JFFS2 inocache) */ |
16402 |
+ #ifdef JFFS2_DBG_INOCACHE_MESSAGES |
16403 |
+ #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16404 |
+ #else |
16405 |
+-#define dbg_inocache(fmt, ...) |
16406 |
++#define dbg_inocache(fmt, ...) do {} while (0) |
16407 |
+ #endif |
16408 |
+ |
16409 |
+ /* Summary debugging messages */ |
16410 |
+ #ifdef JFFS2_DBG_SUMMARY_MESSAGES |
16411 |
+ #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16412 |
+ #else |
16413 |
+-#define dbg_summary(fmt, ...) |
16414 |
++#define dbg_summary(fmt, ...) do {} while (0) |
16415 |
+ #endif |
16416 |
+ |
16417 |
+ /* File system build messages */ |
16418 |
+ #ifdef JFFS2_DBG_FSBUILD_MESSAGES |
16419 |
+ #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16420 |
+ #else |
16421 |
+-#define dbg_fsbuild(fmt, ...) |
16422 |
++#define dbg_fsbuild(fmt, ...) do {} while (0) |
16423 |
+ #endif |
16424 |
+ |
16425 |
+ /* Watch the object allocations */ |
16426 |
+ #ifdef JFFS2_DBG_MEMALLOC_MESSAGES |
16427 |
+ #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16428 |
+ #else |
16429 |
+-#define dbg_memalloc(fmt, ...) |
16430 |
++#define dbg_memalloc(fmt, ...) do {} while (0) |
16431 |
+ #endif |
16432 |
+ |
16433 |
+ /* Watch the XATTR subsystem */ |
16434 |
+ #ifdef JFFS2_DBG_XATTR_MESSAGES |
16435 |
+ #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16436 |
+ #else |
16437 |
+-#define dbg_xattr(fmt, ...) |
16438 |
++#define dbg_xattr(fmt, ...) do {} while (0) |
16439 |
+ #endif |
16440 |
+ |
16441 |
+ /* "Sanity" checks */ |
16442 |
+diff -urNp linux-2.6.24.4/fs/jffs2/erase.c linux-2.6.24.4/fs/jffs2/erase.c |
16443 |
+--- linux-2.6.24.4/fs/jffs2/erase.c 2008-03-24 14:49:18.000000000 -0400 |
16444 |
++++ linux-2.6.24.4/fs/jffs2/erase.c 2008-03-26 17:56:56.000000000 -0400 |
16445 |
+@@ -428,7 +428,8 @@ static void jffs2_mark_erased_block(stru |
16446 |
+ struct jffs2_unknown_node marker = { |
16447 |
+ .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK), |
16448 |
+ .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), |
16449 |
+- .totlen = cpu_to_je32(c->cleanmarker_size) |
16450 |
++ .totlen = cpu_to_je32(c->cleanmarker_size), |
16451 |
++ .hdr_crc = cpu_to_je32(0) |
16452 |
+ }; |
16453 |
+ |
16454 |
+ jffs2_prealloc_raw_node_refs(c, jeb, 1); |
16455 |
+diff -urNp linux-2.6.24.4/fs/jffs2/summary.h linux-2.6.24.4/fs/jffs2/summary.h |
16456 |
+--- linux-2.6.24.4/fs/jffs2/summary.h 2008-03-24 14:49:18.000000000 -0400 |
16457 |
++++ linux-2.6.24.4/fs/jffs2/summary.h 2008-03-26 17:56:56.000000000 -0400 |
16458 |
+@@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_ |
16459 |
+ |
16460 |
+ #define jffs2_sum_active() (0) |
16461 |
+ #define jffs2_sum_init(a) (0) |
16462 |
+-#define jffs2_sum_exit(a) |
16463 |
+-#define jffs2_sum_disable_collecting(a) |
16464 |
++#define jffs2_sum_exit(a) do {} while (0) |
16465 |
++#define jffs2_sum_disable_collecting(a) do {} while (0) |
16466 |
+ #define jffs2_sum_is_disabled(a) (0) |
16467 |
+-#define jffs2_sum_reset_collected(a) |
16468 |
++#define jffs2_sum_reset_collected(a) do {} while (0) |
16469 |
+ #define jffs2_sum_add_kvec(a,b,c,d) (0) |
16470 |
+-#define jffs2_sum_move_collected(a,b) |
16471 |
++#define jffs2_sum_move_collected(a,b) do {} while (0) |
16472 |
+ #define jffs2_sum_write_sumnode(a) (0) |
16473 |
+-#define jffs2_sum_add_padding_mem(a,b) |
16474 |
+-#define jffs2_sum_add_inode_mem(a,b,c) |
16475 |
+-#define jffs2_sum_add_dirent_mem(a,b,c) |
16476 |
+-#define jffs2_sum_add_xattr_mem(a,b,c) |
16477 |
+-#define jffs2_sum_add_xref_mem(a,b,c) |
16478 |
++#define jffs2_sum_add_padding_mem(a,b) do {} while (0) |
16479 |
++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0) |
16480 |
++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0) |
16481 |
++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0) |
16482 |
++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0) |
16483 |
+ #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0) |
16484 |
+ |
16485 |
+ #endif /* CONFIG_JFFS2_SUMMARY */ |
16486 |
+diff -urNp linux-2.6.24.4/fs/jffs2/wbuf.c linux-2.6.24.4/fs/jffs2/wbuf.c |
16487 |
+--- linux-2.6.24.4/fs/jffs2/wbuf.c 2008-03-24 14:49:18.000000000 -0400 |
16488 |
++++ linux-2.6.24.4/fs/jffs2/wbuf.c 2008-03-26 17:56:56.000000000 -0400 |
16489 |
+@@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o |
16490 |
+ { |
16491 |
+ .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK), |
16492 |
+ .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), |
16493 |
+- .totlen = constant_cpu_to_je32(8) |
16494 |
++ .totlen = constant_cpu_to_je32(8), |
16495 |
++ .hdr_crc = constant_cpu_to_je32(0) |
16496 |
+ }; |
16497 |
+ |
16498 |
+ /* |
16499 |
+diff -urNp linux-2.6.24.4/fs/Kconfig linux-2.6.24.4/fs/Kconfig |
16500 |
+--- linux-2.6.24.4/fs/Kconfig 2008-03-24 14:49:18.000000000 -0400 |
16501 |
++++ linux-2.6.24.4/fs/Kconfig 2008-03-26 17:56:56.000000000 -0400 |
16502 |
+@@ -937,7 +937,7 @@ config PROC_FS |
16503 |
+ |
16504 |
+ config PROC_KCORE |
16505 |
+ bool "/proc/kcore support" if !ARM |
16506 |
+- depends on PROC_FS && MMU |
16507 |
++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD |
16508 |
+ |
16509 |
+ config PROC_VMCORE |
16510 |
+ bool "/proc/vmcore support (EXPERIMENTAL)" |
16511 |
+diff -urNp linux-2.6.24.4/fs/namei.c linux-2.6.24.4/fs/namei.c |
16512 |
+--- linux-2.6.24.4/fs/namei.c 2008-03-24 14:49:18.000000000 -0400 |
16513 |
++++ linux-2.6.24.4/fs/namei.c 2008-03-26 17:56:56.000000000 -0400 |
16514 |
+@@ -30,6 +30,7 @@ |
16515 |
+ #include <linux/capability.h> |
16516 |
+ #include <linux/file.h> |
16517 |
+ #include <linux/fcntl.h> |
16518 |
++#include <linux/grsecurity.h> |
16519 |
+ #include <asm/namei.h> |
16520 |
+ #include <asm/uaccess.h> |
16521 |
+ |
16522 |
+@@ -621,7 +622,7 @@ static __always_inline int __do_follow_l |
16523 |
+ cookie = dentry->d_inode->i_op->follow_link(dentry, nd); |
16524 |
+ error = PTR_ERR(cookie); |
16525 |
+ if (!IS_ERR(cookie)) { |
16526 |
+- char *s = nd_get_link(nd); |
16527 |
++ const char *s = nd_get_link(nd); |
16528 |
+ error = 0; |
16529 |
+ if (s) |
16530 |
+ error = __vfs_follow_link(nd, s); |
16531 |
+@@ -653,6 +654,13 @@ static inline int do_follow_link(struct |
16532 |
+ err = security_inode_follow_link(path->dentry, nd); |
16533 |
+ if (err) |
16534 |
+ goto loop; |
16535 |
++ |
16536 |
++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode, |
16537 |
++ path->dentry->d_inode, path->dentry, nd->mnt)) { |
16538 |
++ err = -EACCES; |
16539 |
++ goto loop; |
16540 |
++ } |
16541 |
++ |
16542 |
+ current->link_count++; |
16543 |
+ current->total_link_count++; |
16544 |
+ nd->depth++; |
16545 |
+@@ -998,11 +1006,18 @@ return_reval: |
16546 |
+ break; |
16547 |
+ } |
16548 |
+ return_base: |
16549 |
++ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) { |
16550 |
++ path_release(nd); |
16551 |
++ return -ENOENT; |
16552 |
++ } |
16553 |
+ return 0; |
16554 |
+ out_dput: |
16555 |
+ dput_path(&next, nd); |
16556 |
+ break; |
16557 |
+ } |
16558 |
++ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) |
16559 |
++ err = -ENOENT; |
16560 |
++ |
16561 |
+ path_release(nd); |
16562 |
+ return_err: |
16563 |
+ return err; |
16564 |
+@@ -1680,9 +1695,17 @@ static int open_namei_create(struct name |
16565 |
+ int error; |
16566 |
+ struct dentry *dir = nd->dentry; |
16567 |
+ |
16568 |
++ if (!gr_acl_handle_creat(path->dentry, nd->dentry, nd->mnt, flag, mode)) { |
16569 |
++ error = -EACCES; |
16570 |
++ goto out_unlock_dput; |
16571 |
++ } |
16572 |
++ |
16573 |
+ if (!IS_POSIXACL(dir->d_inode)) |
16574 |
+ mode &= ~current->fs->umask; |
16575 |
+ error = vfs_create(dir->d_inode, path->dentry, mode, nd); |
16576 |
++ if (!error) |
16577 |
++ gr_handle_create(path->dentry, nd->mnt); |
16578 |
++out_unlock_dput: |
16579 |
+ mutex_unlock(&dir->d_inode->i_mutex); |
16580 |
+ dput(nd->dentry); |
16581 |
+ nd->dentry = path->dentry; |
16582 |
+@@ -1733,6 +1756,17 @@ int open_namei(int dfd, const char *path |
16583 |
+ nd, flag); |
16584 |
+ if (error) |
16585 |
+ return error; |
16586 |
++ |
16587 |
++ if (gr_handle_rawio(nd->dentry->d_inode)) { |
16588 |
++ error = -EPERM; |
16589 |
++ goto exit; |
16590 |
++ } |
16591 |
++ |
16592 |
++ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) { |
16593 |
++ error = -EACCES; |
16594 |
++ goto exit; |
16595 |
++ } |
16596 |
++ |
16597 |
+ goto ok; |
16598 |
+ } |
16599 |
+ |
16600 |
+@@ -1782,6 +1816,23 @@ do_last: |
16601 |
+ /* |
16602 |
+ * It already exists. |
16603 |
+ */ |
16604 |
++ |
16605 |
++ if (gr_handle_rawio(path.dentry->d_inode)) { |
16606 |
++ mutex_unlock(&dir->d_inode->i_mutex); |
16607 |
++ error = -EPERM; |
16608 |
++ goto exit_dput; |
16609 |
++ } |
16610 |
++ if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) { |
16611 |
++ mutex_unlock(&dir->d_inode->i_mutex); |
16612 |
++ error = -EACCES; |
16613 |
++ goto exit_dput; |
16614 |
++ } |
16615 |
++ if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) { |
16616 |
++ mutex_unlock(&dir->d_inode->i_mutex); |
16617 |
++ error = -EACCES; |
16618 |
++ goto exit_dput; |
16619 |
++ } |
16620 |
++ |
16621 |
+ mutex_unlock(&dir->d_inode->i_mutex); |
16622 |
+ audit_inode(pathname, path.dentry); |
16623 |
+ |
16624 |
+@@ -1837,6 +1888,13 @@ do_link: |
16625 |
+ error = security_inode_follow_link(path.dentry, nd); |
16626 |
+ if (error) |
16627 |
+ goto exit_dput; |
16628 |
++ |
16629 |
++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode, |
16630 |
++ path.dentry, nd->mnt)) { |
16631 |
++ error = -EACCES; |
16632 |
++ goto exit_dput; |
16633 |
++ } |
16634 |
++ |
16635 |
+ error = __do_follow_link(&path, nd); |
16636 |
+ if (error) { |
16637 |
+ /* Does someone understand code flow here? Or it is only |
16638 |
+@@ -1965,6 +2023,22 @@ asmlinkage long sys_mknodat(int dfd, con |
16639 |
+ if (!IS_POSIXACL(nd.dentry->d_inode)) |
16640 |
+ mode &= ~current->fs->umask; |
16641 |
+ if (!IS_ERR(dentry)) { |
16642 |
++ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) { |
16643 |
++ error = -EPERM; |
16644 |
++ dput(dentry); |
16645 |
++ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16646 |
++ path_release(&nd); |
16647 |
++ goto out; |
16648 |
++ } |
16649 |
++ |
16650 |
++ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) { |
16651 |
++ error = -EACCES; |
16652 |
++ dput(dentry); |
16653 |
++ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16654 |
++ path_release(&nd); |
16655 |
++ goto out; |
16656 |
++ } |
16657 |
++ |
16658 |
+ switch (mode & S_IFMT) { |
16659 |
+ case 0: case S_IFREG: |
16660 |
+ error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); |
16661 |
+@@ -1982,6 +2056,10 @@ asmlinkage long sys_mknodat(int dfd, con |
16662 |
+ default: |
16663 |
+ error = -EINVAL; |
16664 |
+ } |
16665 |
++ |
16666 |
++ if (!error) |
16667 |
++ gr_handle_create(dentry, nd.mnt); |
16668 |
++ |
16669 |
+ dput(dentry); |
16670 |
+ } |
16671 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16672 |
+@@ -2039,9 +2117,18 @@ asmlinkage long sys_mkdirat(int dfd, con |
16673 |
+ if (IS_ERR(dentry)) |
16674 |
+ goto out_unlock; |
16675 |
+ |
16676 |
++ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt)) { |
16677 |
++ error = -EACCES; |
16678 |
++ goto out_unlock_dput; |
16679 |
++ } |
16680 |
++ |
16681 |
+ if (!IS_POSIXACL(nd.dentry->d_inode)) |
16682 |
+ mode &= ~current->fs->umask; |
16683 |
+ error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); |
16684 |
++ |
16685 |
++ if (!error) |
16686 |
++ gr_handle_create(dentry, nd.mnt); |
16687 |
++out_unlock_dput: |
16688 |
+ dput(dentry); |
16689 |
+ out_unlock: |
16690 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16691 |
+@@ -2123,6 +2210,8 @@ static long do_rmdir(int dfd, const char |
16692 |
+ char * name; |
16693 |
+ struct dentry *dentry; |
16694 |
+ struct nameidata nd; |
16695 |
++ ino_t saved_ino = 0; |
16696 |
++ dev_t saved_dev = 0; |
16697 |
+ |
16698 |
+ name = getname(pathname); |
16699 |
+ if(IS_ERR(name)) |
16700 |
+@@ -2148,7 +2237,22 @@ static long do_rmdir(int dfd, const char |
16701 |
+ error = PTR_ERR(dentry); |
16702 |
+ if (IS_ERR(dentry)) |
16703 |
+ goto exit2; |
16704 |
++ |
16705 |
++ if (dentry->d_inode != NULL) { |
16706 |
++ if (dentry->d_inode->i_nlink <= 1) { |
16707 |
++ saved_ino = dentry->d_inode->i_ino; |
16708 |
++ saved_dev = dentry->d_inode->i_sb->s_dev; |
16709 |
++ } |
16710 |
++ |
16711 |
++ if (!gr_acl_handle_rmdir(dentry, nd.mnt)) { |
16712 |
++ error = -EACCES; |
16713 |
++ goto dput_exit2; |
16714 |
++ } |
16715 |
++ } |
16716 |
+ error = vfs_rmdir(nd.dentry->d_inode, dentry); |
16717 |
++ if (!error && (saved_dev || saved_ino)) |
16718 |
++ gr_handle_delete(saved_ino, saved_dev); |
16719 |
++dput_exit2: |
16720 |
+ dput(dentry); |
16721 |
+ exit2: |
16722 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16723 |
+@@ -2207,6 +2311,8 @@ static long do_unlinkat(int dfd, const c |
16724 |
+ struct dentry *dentry; |
16725 |
+ struct nameidata nd; |
16726 |
+ struct inode *inode = NULL; |
16727 |
++ ino_t saved_ino = 0; |
16728 |
++ dev_t saved_dev = 0; |
16729 |
+ |
16730 |
+ name = getname(pathname); |
16731 |
+ if(IS_ERR(name)) |
16732 |
+@@ -2222,13 +2328,26 @@ static long do_unlinkat(int dfd, const c |
16733 |
+ dentry = lookup_hash(&nd); |
16734 |
+ error = PTR_ERR(dentry); |
16735 |
+ if (!IS_ERR(dentry)) { |
16736 |
++ error = 0; |
16737 |
+ /* Why not before? Because we want correct error value */ |
16738 |
+ if (nd.last.name[nd.last.len]) |
16739 |
+ goto slashes; |
16740 |
+ inode = dentry->d_inode; |
16741 |
+- if (inode) |
16742 |
++ if (inode) { |
16743 |
++ if (inode->i_nlink <= 1) { |
16744 |
++ saved_ino = inode->i_ino; |
16745 |
++ saved_dev = inode->i_sb->s_dev; |
16746 |
++ } |
16747 |
++ |
16748 |
++ if (!gr_acl_handle_unlink(dentry, nd.mnt)) |
16749 |
++ error = -EACCES; |
16750 |
++ |
16751 |
+ atomic_inc(&inode->i_count); |
16752 |
+- error = vfs_unlink(nd.dentry->d_inode, dentry); |
16753 |
++ } |
16754 |
++ if (!error) |
16755 |
++ error = vfs_unlink(nd.dentry->d_inode, dentry); |
16756 |
++ if (!error && (saved_ino || saved_dev)) |
16757 |
++ gr_handle_delete(saved_ino, saved_dev); |
16758 |
+ exit2: |
16759 |
+ dput(dentry); |
16760 |
+ } |
16761 |
+@@ -2309,7 +2428,16 @@ asmlinkage long sys_symlinkat(const char |
16762 |
+ if (IS_ERR(dentry)) |
16763 |
+ goto out_unlock; |
16764 |
+ |
16765 |
++ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from)) { |
16766 |
++ error = -EACCES; |
16767 |
++ goto out_dput_unlock; |
16768 |
++ } |
16769 |
++ |
16770 |
+ error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); |
16771 |
++ |
16772 |
++ if (!error) |
16773 |
++ gr_handle_create(dentry, nd.mnt); |
16774 |
++out_dput_unlock: |
16775 |
+ dput(dentry); |
16776 |
+ out_unlock: |
16777 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16778 |
+@@ -2404,7 +2532,25 @@ asmlinkage long sys_linkat(int olddfd, c |
16779 |
+ error = PTR_ERR(new_dentry); |
16780 |
+ if (IS_ERR(new_dentry)) |
16781 |
+ goto out_unlock; |
16782 |
++ |
16783 |
++ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt, |
16784 |
++ old_nd.dentry->d_inode, |
16785 |
++ old_nd.dentry->d_inode->i_mode, to)) { |
16786 |
++ error = -EACCES; |
16787 |
++ goto out_unlock_dput; |
16788 |
++ } |
16789 |
++ |
16790 |
++ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt, |
16791 |
++ old_nd.dentry, old_nd.mnt, to)) { |
16792 |
++ error = -EACCES; |
16793 |
++ goto out_unlock_dput; |
16794 |
++ } |
16795 |
++ |
16796 |
+ error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); |
16797 |
++ |
16798 |
++ if (!error) |
16799 |
++ gr_handle_create(new_dentry, nd.mnt); |
16800 |
++out_unlock_dput: |
16801 |
+ dput(new_dentry); |
16802 |
+ out_unlock: |
16803 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16804 |
+@@ -2630,8 +2776,16 @@ static int do_rename(int olddfd, const c |
16805 |
+ if (new_dentry == trap) |
16806 |
+ goto exit5; |
16807 |
+ |
16808 |
+- error = vfs_rename(old_dir->d_inode, old_dentry, |
16809 |
++ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt, |
16810 |
++ old_dentry, old_dir->d_inode, oldnd.mnt, |
16811 |
++ newname); |
16812 |
++ |
16813 |
++ if (!error) |
16814 |
++ error = vfs_rename(old_dir->d_inode, old_dentry, |
16815 |
+ new_dir->d_inode, new_dentry); |
16816 |
++ if (!error) |
16817 |
++ gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, |
16818 |
++ new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0); |
16819 |
+ exit5: |
16820 |
+ dput(new_dentry); |
16821 |
+ exit4: |
16822 |
+diff -urNp linux-2.6.24.4/fs/namespace.c linux-2.6.24.4/fs/namespace.c |
16823 |
+--- linux-2.6.24.4/fs/namespace.c 2008-03-24 14:49:18.000000000 -0400 |
16824 |
++++ linux-2.6.24.4/fs/namespace.c 2008-03-26 17:56:56.000000000 -0400 |
16825 |
+@@ -25,6 +25,7 @@ |
16826 |
+ #include <linux/security.h> |
16827 |
+ #include <linux/mount.h> |
16828 |
+ #include <linux/ramfs.h> |
16829 |
++#include <linux/grsecurity.h> |
16830 |
+ #include <asm/uaccess.h> |
16831 |
+ #include <asm/unistd.h> |
16832 |
+ #include "pnode.h" |
16833 |
+@@ -597,6 +598,8 @@ static int do_umount(struct vfsmount *mn |
16834 |
+ DQUOT_OFF(sb); |
16835 |
+ retval = do_remount_sb(sb, MS_RDONLY, NULL, 0); |
16836 |
+ unlock_kernel(); |
16837 |
++ |
16838 |
++ gr_log_remount(mnt->mnt_devname, retval); |
16839 |
+ } |
16840 |
+ up_write(&sb->s_umount); |
16841 |
+ return retval; |
16842 |
+@@ -617,6 +620,9 @@ static int do_umount(struct vfsmount *mn |
16843 |
+ security_sb_umount_busy(mnt); |
16844 |
+ up_write(&namespace_sem); |
16845 |
+ release_mounts(&umount_list); |
16846 |
++ |
16847 |
++ gr_log_unmount(mnt->mnt_devname, retval); |
16848 |
++ |
16849 |
+ return retval; |
16850 |
+ } |
16851 |
+ |
16852 |
+@@ -1442,6 +1448,11 @@ long do_mount(char *dev_name, char *dir_ |
16853 |
+ if (retval) |
16854 |
+ goto dput_out; |
16855 |
+ |
16856 |
++ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) { |
16857 |
++ retval = -EPERM; |
16858 |
++ goto dput_out; |
16859 |
++ } |
16860 |
++ |
16861 |
+ if (flags & MS_REMOUNT) |
16862 |
+ retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, |
16863 |
+ data_page); |
16864 |
+@@ -1456,6 +1467,9 @@ long do_mount(char *dev_name, char *dir_ |
16865 |
+ dev_name, data_page); |
16866 |
+ dput_out: |
16867 |
+ path_release(&nd); |
16868 |
++ |
16869 |
++ gr_log_mount(dev_name, dir_name, retval); |
16870 |
++ |
16871 |
+ return retval; |
16872 |
+ } |
16873 |
+ |
16874 |
+@@ -1693,6 +1707,9 @@ asmlinkage long sys_pivot_root(const cha |
16875 |
+ if (!capable(CAP_SYS_ADMIN)) |
16876 |
+ return -EPERM; |
16877 |
+ |
16878 |
++ if (gr_handle_chroot_pivot()) |
16879 |
++ return -EPERM; |
16880 |
++ |
16881 |
+ lock_kernel(); |
16882 |
+ |
16883 |
+ error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, |
16884 |
+diff -urNp linux-2.6.24.4/fs/nfs/callback_xdr.c linux-2.6.24.4/fs/nfs/callback_xdr.c |
16885 |
+--- linux-2.6.24.4/fs/nfs/callback_xdr.c 2008-03-24 14:49:18.000000000 -0400 |
16886 |
++++ linux-2.6.24.4/fs/nfs/callback_xdr.c 2008-03-26 17:56:56.000000000 -0400 |
16887 |
+@@ -139,7 +139,7 @@ static __be32 decode_compound_hdr_arg(st |
16888 |
+ if (unlikely(status != 0)) |
16889 |
+ return status; |
16890 |
+ /* We do not like overly long tags! */ |
16891 |
+- if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) { |
16892 |
++ if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12) { |
16893 |
+ printk("NFSv4 CALLBACK %s: client sent tag of length %u\n", |
16894 |
+ __FUNCTION__, hdr->taglen); |
16895 |
+ return htonl(NFS4ERR_RESOURCE); |
16896 |
+diff -urNp linux-2.6.24.4/fs/nfs/nfs4proc.c linux-2.6.24.4/fs/nfs/nfs4proc.c |
16897 |
+--- linux-2.6.24.4/fs/nfs/nfs4proc.c 2008-03-24 14:49:18.000000000 -0400 |
16898 |
++++ linux-2.6.24.4/fs/nfs/nfs4proc.c 2008-03-26 17:56:56.000000000 -0400 |
16899 |
+@@ -656,7 +656,7 @@ static int _nfs4_do_open_reclaim(struct |
16900 |
+ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state) |
16901 |
+ { |
16902 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
16903 |
+- struct nfs4_exception exception = { }; |
16904 |
++ struct nfs4_exception exception = {0, 0}; |
16905 |
+ int err; |
16906 |
+ do { |
16907 |
+ err = _nfs4_do_open_reclaim(ctx, state); |
16908 |
+@@ -698,7 +698,7 @@ static int _nfs4_open_delegation_recall( |
16909 |
+ |
16910 |
+ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) |
16911 |
+ { |
16912 |
+- struct nfs4_exception exception = { }; |
16913 |
++ struct nfs4_exception exception = {0, 0}; |
16914 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
16915 |
+ int err; |
16916 |
+ do { |
16917 |
+@@ -987,7 +987,7 @@ static int _nfs4_open_expired(struct nfs |
16918 |
+ static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) |
16919 |
+ { |
16920 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
16921 |
+- struct nfs4_exception exception = { }; |
16922 |
++ struct nfs4_exception exception = {0, 0}; |
16923 |
+ int err; |
16924 |
+ |
16925 |
+ do { |
16926 |
+@@ -1089,7 +1089,7 @@ out_err: |
16927 |
+ |
16928 |
+ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred) |
16929 |
+ { |
16930 |
+- struct nfs4_exception exception = { }; |
16931 |
++ struct nfs4_exception exception = {0, 0}; |
16932 |
+ struct nfs4_state *res; |
16933 |
+ int status; |
16934 |
+ |
16935 |
+@@ -1178,7 +1178,7 @@ static int nfs4_do_setattr(struct inode |
16936 |
+ struct iattr *sattr, struct nfs4_state *state) |
16937 |
+ { |
16938 |
+ struct nfs_server *server = NFS_SERVER(inode); |
16939 |
+- struct nfs4_exception exception = { }; |
16940 |
++ struct nfs4_exception exception = {0, 0}; |
16941 |
+ int err; |
16942 |
+ do { |
16943 |
+ err = nfs4_handle_exception(server, |
16944 |
+@@ -1484,7 +1484,7 @@ static int _nfs4_server_capabilities(str |
16945 |
+ |
16946 |
+ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) |
16947 |
+ { |
16948 |
+- struct nfs4_exception exception = { }; |
16949 |
++ struct nfs4_exception exception = {0, 0}; |
16950 |
+ int err; |
16951 |
+ do { |
16952 |
+ err = nfs4_handle_exception(server, |
16953 |
+@@ -1517,7 +1517,7 @@ static int _nfs4_lookup_root(struct nfs_ |
16954 |
+ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, |
16955 |
+ struct nfs_fsinfo *info) |
16956 |
+ { |
16957 |
+- struct nfs4_exception exception = { }; |
16958 |
++ struct nfs4_exception exception = {0, 0}; |
16959 |
+ int err; |
16960 |
+ do { |
16961 |
+ err = nfs4_handle_exception(server, |
16962 |
+@@ -1606,7 +1606,7 @@ static int _nfs4_proc_getattr(struct nfs |
16963 |
+ |
16964 |
+ static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) |
16965 |
+ { |
16966 |
+- struct nfs4_exception exception = { }; |
16967 |
++ struct nfs4_exception exception = {0, 0}; |
16968 |
+ int err; |
16969 |
+ do { |
16970 |
+ err = nfs4_handle_exception(server, |
16971 |
+@@ -1696,7 +1696,7 @@ static int nfs4_proc_lookupfh(struct nfs |
16972 |
+ struct qstr *name, struct nfs_fh *fhandle, |
16973 |
+ struct nfs_fattr *fattr) |
16974 |
+ { |
16975 |
+- struct nfs4_exception exception = { }; |
16976 |
++ struct nfs4_exception exception = {0, 0}; |
16977 |
+ int err; |
16978 |
+ do { |
16979 |
+ err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr); |
16980 |
+@@ -1725,7 +1725,7 @@ static int _nfs4_proc_lookup(struct inod |
16981 |
+ |
16982 |
+ static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr) |
16983 |
+ { |
16984 |
+- struct nfs4_exception exception = { }; |
16985 |
++ struct nfs4_exception exception = {0, 0}; |
16986 |
+ int err; |
16987 |
+ do { |
16988 |
+ err = nfs4_handle_exception(NFS_SERVER(dir), |
16989 |
+@@ -1789,7 +1789,7 @@ static int _nfs4_proc_access(struct inod |
16990 |
+ |
16991 |
+ static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) |
16992 |
+ { |
16993 |
+- struct nfs4_exception exception = { }; |
16994 |
++ struct nfs4_exception exception = {0, 0}; |
16995 |
+ int err; |
16996 |
+ do { |
16997 |
+ err = nfs4_handle_exception(NFS_SERVER(inode), |
16998 |
+@@ -1844,7 +1844,7 @@ static int _nfs4_proc_readlink(struct in |
16999 |
+ static int nfs4_proc_readlink(struct inode *inode, struct page *page, |
17000 |
+ unsigned int pgbase, unsigned int pglen) |
17001 |
+ { |
17002 |
+- struct nfs4_exception exception = { }; |
17003 |
++ struct nfs4_exception exception = {0, 0}; |
17004 |
+ int err; |
17005 |
+ do { |
17006 |
+ err = nfs4_handle_exception(NFS_SERVER(inode), |
17007 |
+@@ -1940,7 +1940,7 @@ static int _nfs4_proc_remove(struct inod |
17008 |
+ |
17009 |
+ static int nfs4_proc_remove(struct inode *dir, struct qstr *name) |
17010 |
+ { |
17011 |
+- struct nfs4_exception exception = { }; |
17012 |
++ struct nfs4_exception exception = {0, 0}; |
17013 |
+ int err; |
17014 |
+ do { |
17015 |
+ err = nfs4_handle_exception(NFS_SERVER(dir), |
17016 |
+@@ -2012,7 +2012,7 @@ static int _nfs4_proc_rename(struct inod |
17017 |
+ static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, |
17018 |
+ struct inode *new_dir, struct qstr *new_name) |
17019 |
+ { |
17020 |
+- struct nfs4_exception exception = { }; |
17021 |
++ struct nfs4_exception exception = {0, 0}; |
17022 |
+ int err; |
17023 |
+ do { |
17024 |
+ err = nfs4_handle_exception(NFS_SERVER(old_dir), |
17025 |
+@@ -2059,7 +2059,7 @@ static int _nfs4_proc_link(struct inode |
17026 |
+ |
17027 |
+ static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) |
17028 |
+ { |
17029 |
+- struct nfs4_exception exception = { }; |
17030 |
++ struct nfs4_exception exception = {0, 0}; |
17031 |
+ int err; |
17032 |
+ do { |
17033 |
+ err = nfs4_handle_exception(NFS_SERVER(inode), |
17034 |
+@@ -2116,7 +2116,7 @@ static int _nfs4_proc_symlink(struct ino |
17035 |
+ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, |
17036 |
+ struct page *page, unsigned int len, struct iattr *sattr) |
17037 |
+ { |
17038 |
+- struct nfs4_exception exception = { }; |
17039 |
++ struct nfs4_exception exception = {0, 0}; |
17040 |
+ int err; |
17041 |
+ do { |
17042 |
+ err = nfs4_handle_exception(NFS_SERVER(dir), |
17043 |
+@@ -2169,7 +2169,7 @@ static int _nfs4_proc_mkdir(struct inode |
17044 |
+ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, |
17045 |
+ struct iattr *sattr) |
17046 |
+ { |
17047 |
+- struct nfs4_exception exception = { }; |
17048 |
++ struct nfs4_exception exception = {0, 0}; |
17049 |
+ int err; |
17050 |
+ do { |
17051 |
+ err = nfs4_handle_exception(NFS_SERVER(dir), |
17052 |
+@@ -2218,7 +2218,7 @@ static int _nfs4_proc_readdir(struct den |
17053 |
+ static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, |
17054 |
+ u64 cookie, struct page *page, unsigned int count, int plus) |
17055 |
+ { |
17056 |
+- struct nfs4_exception exception = { }; |
17057 |
++ struct nfs4_exception exception = {0, 0}; |
17058 |
+ int err; |
17059 |
+ do { |
17060 |
+ err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode), |
17061 |
+@@ -2288,7 +2288,7 @@ static int _nfs4_proc_mknod(struct inode |
17062 |
+ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, |
17063 |
+ struct iattr *sattr, dev_t rdev) |
17064 |
+ { |
17065 |
+- struct nfs4_exception exception = { }; |
17066 |
++ struct nfs4_exception exception = {0, 0}; |
17067 |
+ int err; |
17068 |
+ do { |
17069 |
+ err = nfs4_handle_exception(NFS_SERVER(dir), |
17070 |
+@@ -2317,7 +2317,7 @@ static int _nfs4_proc_statfs(struct nfs_ |
17071 |
+ |
17072 |
+ static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat) |
17073 |
+ { |
17074 |
+- struct nfs4_exception exception = { }; |
17075 |
++ struct nfs4_exception exception = {0, 0}; |
17076 |
+ int err; |
17077 |
+ do { |
17078 |
+ err = nfs4_handle_exception(server, |
17079 |
+@@ -2345,7 +2345,7 @@ static int _nfs4_do_fsinfo(struct nfs_se |
17080 |
+ |
17081 |
+ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) |
17082 |
+ { |
17083 |
+- struct nfs4_exception exception = { }; |
17084 |
++ struct nfs4_exception exception = {0, 0}; |
17085 |
+ int err; |
17086 |
+ |
17087 |
+ do { |
17088 |
+@@ -2388,7 +2388,7 @@ static int _nfs4_proc_pathconf(struct nf |
17089 |
+ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, |
17090 |
+ struct nfs_pathconf *pathconf) |
17091 |
+ { |
17092 |
+- struct nfs4_exception exception = { }; |
17093 |
++ struct nfs4_exception exception = {0, 0}; |
17094 |
+ int err; |
17095 |
+ |
17096 |
+ do { |
17097 |
+@@ -2708,7 +2708,7 @@ out_free: |
17098 |
+ |
17099 |
+ static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) |
17100 |
+ { |
17101 |
+- struct nfs4_exception exception = { }; |
17102 |
++ struct nfs4_exception exception = {0, 0}; |
17103 |
+ ssize_t ret; |
17104 |
+ do { |
17105 |
+ ret = __nfs4_get_acl_uncached(inode, buf, buflen); |
17106 |
+@@ -2762,7 +2762,7 @@ static int __nfs4_proc_set_acl(struct in |
17107 |
+ |
17108 |
+ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) |
17109 |
+ { |
17110 |
+- struct nfs4_exception exception = { }; |
17111 |
++ struct nfs4_exception exception = {0, 0}; |
17112 |
+ int err; |
17113 |
+ do { |
17114 |
+ err = nfs4_handle_exception(NFS_SERVER(inode), |
17115 |
+@@ -3059,7 +3059,7 @@ static int _nfs4_proc_delegreturn(struct |
17116 |
+ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) |
17117 |
+ { |
17118 |
+ struct nfs_server *server = NFS_SERVER(inode); |
17119 |
+- struct nfs4_exception exception = { }; |
17120 |
++ struct nfs4_exception exception = {0, 0}; |
17121 |
+ int err; |
17122 |
+ do { |
17123 |
+ err = _nfs4_proc_delegreturn(inode, cred, stateid); |
17124 |
+@@ -3134,7 +3134,7 @@ out: |
17125 |
+ |
17126 |
+ static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request) |
17127 |
+ { |
17128 |
+- struct nfs4_exception exception = { }; |
17129 |
++ struct nfs4_exception exception = {0, 0}; |
17130 |
+ int err; |
17131 |
+ |
17132 |
+ do { |
17133 |
+@@ -3476,7 +3476,7 @@ static int _nfs4_do_setlk(struct nfs4_st |
17134 |
+ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request) |
17135 |
+ { |
17136 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
17137 |
+- struct nfs4_exception exception = { }; |
17138 |
++ struct nfs4_exception exception = {0, 0}; |
17139 |
+ int err; |
17140 |
+ |
17141 |
+ do { |
17142 |
+@@ -3494,7 +3494,7 @@ static int nfs4_lock_reclaim(struct nfs4 |
17143 |
+ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request) |
17144 |
+ { |
17145 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
17146 |
+- struct nfs4_exception exception = { }; |
17147 |
++ struct nfs4_exception exception = {0, 0}; |
17148 |
+ int err; |
17149 |
+ |
17150 |
+ err = nfs4_set_lock_state(state, request); |
17151 |
+@@ -3555,7 +3555,7 @@ out: |
17152 |
+ |
17153 |
+ static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) |
17154 |
+ { |
17155 |
+- struct nfs4_exception exception = { }; |
17156 |
++ struct nfs4_exception exception = {0, 0}; |
17157 |
+ int err; |
17158 |
+ |
17159 |
+ do { |
17160 |
+@@ -3605,7 +3605,7 @@ nfs4_proc_lock(struct file *filp, int cm |
17161 |
+ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) |
17162 |
+ { |
17163 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
17164 |
+- struct nfs4_exception exception = { }; |
17165 |
++ struct nfs4_exception exception = {0, 0}; |
17166 |
+ int err; |
17167 |
+ |
17168 |
+ err = nfs4_set_lock_state(state, fl); |
17169 |
+diff -urNp linux-2.6.24.4/fs/nfsd/export.c linux-2.6.24.4/fs/nfsd/export.c |
17170 |
+--- linux-2.6.24.4/fs/nfsd/export.c 2008-03-24 14:49:18.000000000 -0400 |
17171 |
++++ linux-2.6.24.4/fs/nfsd/export.c 2008-03-26 17:56:56.000000000 -0400 |
17172 |
+@@ -476,7 +476,7 @@ static int secinfo_parse(char **mesg, ch |
17173 |
+ * probably discover the problem when someone fails to |
17174 |
+ * authenticate. |
17175 |
+ */ |
17176 |
+- if (f->pseudoflavor < 0) |
17177 |
++ if ((s32)f->pseudoflavor < 0) |
17178 |
+ return -EINVAL; |
17179 |
+ err = get_int(mesg, &f->flags); |
17180 |
+ if (err) |
17181 |
+diff -urNp linux-2.6.24.4/fs/nfsd/nfs4state.c linux-2.6.24.4/fs/nfsd/nfs4state.c |
17182 |
+--- linux-2.6.24.4/fs/nfsd/nfs4state.c 2008-03-24 14:49:18.000000000 -0400 |
17183 |
++++ linux-2.6.24.4/fs/nfsd/nfs4state.c 2008-03-26 17:56:56.000000000 -0400 |
17184 |
+@@ -1233,7 +1233,7 @@ static int access_valid(u32 x) |
17185 |
+ |
17186 |
+ static int deny_valid(u32 x) |
17187 |
+ { |
17188 |
+- return (x >= 0 && x < 5); |
17189 |
++ return (x < 5); |
17190 |
+ } |
17191 |
+ |
17192 |
+ static void |
17193 |
+diff -urNp linux-2.6.24.4/fs/nls/nls_base.c linux-2.6.24.4/fs/nls/nls_base.c |
17194 |
+--- linux-2.6.24.4/fs/nls/nls_base.c 2008-03-24 14:49:18.000000000 -0400 |
17195 |
++++ linux-2.6.24.4/fs/nls/nls_base.c 2008-03-26 17:56:56.000000000 -0400 |
17196 |
+@@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl |
17197 |
+ {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */}, |
17198 |
+ {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */}, |
17199 |
+ {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */}, |
17200 |
+- {0, /* end of table */} |
17201 |
++ {0, 0, 0, 0, 0, /* end of table */} |
17202 |
+ }; |
17203 |
+ |
17204 |
+ int |
17205 |
+diff -urNp linux-2.6.24.4/fs/ntfs/file.c linux-2.6.24.4/fs/ntfs/file.c |
17206 |
+--- linux-2.6.24.4/fs/ntfs/file.c 2008-03-24 14:49:18.000000000 -0400 |
17207 |
++++ linux-2.6.24.4/fs/ntfs/file.c 2008-03-26 17:56:56.000000000 -0400 |
17208 |
+@@ -2293,6 +2293,6 @@ const struct inode_operations ntfs_file_ |
17209 |
+ #endif /* NTFS_RW */ |
17210 |
+ }; |
17211 |
+ |
17212 |
+-const struct file_operations ntfs_empty_file_ops = {}; |
17213 |
++const struct file_operations ntfs_empty_file_ops; |
17214 |
+ |
17215 |
+-const struct inode_operations ntfs_empty_inode_ops = {}; |
17216 |
++const struct inode_operations ntfs_empty_inode_ops; |
17217 |
+diff -urNp linux-2.6.24.4/fs/open.c linux-2.6.24.4/fs/open.c |
17218 |
+--- linux-2.6.24.4/fs/open.c 2008-03-24 14:49:18.000000000 -0400 |
17219 |
++++ linux-2.6.24.4/fs/open.c 2008-03-26 17:56:56.000000000 -0400 |
17220 |
+@@ -27,6 +27,7 @@ |
17221 |
+ #include <linux/rcupdate.h> |
17222 |
+ #include <linux/audit.h> |
17223 |
+ #include <linux/falloc.h> |
17224 |
++#include <linux/grsecurity.h> |
17225 |
+ |
17226 |
+ int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
17227 |
+ { |
17228 |
+@@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l |
17229 |
+ if (length < 0) |
17230 |
+ return -EINVAL; |
17231 |
+ |
17232 |
++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt)) |
17233 |
++ return -EACCES; |
17234 |
++ |
17235 |
+ newattrs.ia_size = length; |
17236 |
+ newattrs.ia_valid = ATTR_SIZE | time_attrs; |
17237 |
+ if (filp) { |
17238 |
+@@ -461,6 +465,9 @@ asmlinkage long sys_faccessat(int dfd, c |
17239 |
+ if(IS_RDONLY(nd.dentry->d_inode)) |
17240 |
+ res = -EROFS; |
17241 |
+ |
17242 |
++ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode)) |
17243 |
++ res = -EACCES; |
17244 |
++ |
17245 |
+ out_path_release: |
17246 |
+ path_release(&nd); |
17247 |
+ out: |
17248 |
+@@ -490,6 +497,8 @@ asmlinkage long sys_chdir(const char __u |
17249 |
+ if (error) |
17250 |
+ goto dput_and_out; |
17251 |
+ |
17252 |
++ gr_log_chdir(nd.dentry, nd.mnt); |
17253 |
++ |
17254 |
+ set_fs_pwd(current->fs, nd.mnt, nd.dentry); |
17255 |
+ |
17256 |
+ dput_and_out: |
17257 |
+@@ -520,6 +529,13 @@ asmlinkage long sys_fchdir(unsigned int |
17258 |
+ goto out_putf; |
17259 |
+ |
17260 |
+ error = file_permission(file, MAY_EXEC); |
17261 |
++ |
17262 |
++ if (!error && !gr_chroot_fchdir(dentry, mnt)) |
17263 |
++ error = -EPERM; |
17264 |
++ |
17265 |
++ if (!error) |
17266 |
++ gr_log_chdir(dentry, mnt); |
17267 |
++ |
17268 |
+ if (!error) |
17269 |
+ set_fs_pwd(current->fs, mnt, dentry); |
17270 |
+ out_putf: |
17271 |
+@@ -545,8 +561,16 @@ asmlinkage long sys_chroot(const char __ |
17272 |
+ if (!capable(CAP_SYS_CHROOT)) |
17273 |
+ goto dput_and_out; |
17274 |
+ |
17275 |
++ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt)) |
17276 |
++ goto dput_and_out; |
17277 |
++ |
17278 |
+ set_fs_root(current->fs, nd.mnt, nd.dentry); |
17279 |
+ set_fs_altroot(); |
17280 |
++ |
17281 |
++ gr_handle_chroot_caps(current); |
17282 |
++ |
17283 |
++ gr_handle_chroot_chdir(nd.dentry, nd.mnt); |
17284 |
++ |
17285 |
+ error = 0; |
17286 |
+ dput_and_out: |
17287 |
+ path_release(&nd); |
17288 |
+@@ -577,9 +601,22 @@ asmlinkage long sys_fchmod(unsigned int |
17289 |
+ err = -EPERM; |
17290 |
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
17291 |
+ goto out_putf; |
17292 |
++ |
17293 |
++ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) { |
17294 |
++ err = -EACCES; |
17295 |
++ goto out_putf; |
17296 |
++ } |
17297 |
++ |
17298 |
+ mutex_lock(&inode->i_mutex); |
17299 |
+ if (mode == (mode_t) -1) |
17300 |
+ mode = inode->i_mode; |
17301 |
++ |
17302 |
++ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) { |
17303 |
++ err = -EPERM; |
17304 |
++ mutex_unlock(&inode->i_mutex); |
17305 |
++ goto out_putf; |
17306 |
++ } |
17307 |
++ |
17308 |
+ newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
17309 |
+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
17310 |
+ err = notify_change(dentry, &newattrs); |
17311 |
+@@ -612,9 +649,21 @@ asmlinkage long sys_fchmodat(int dfd, co |
17312 |
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
17313 |
+ goto dput_and_out; |
17314 |
+ |
17315 |
++ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) { |
17316 |
++ error = -EACCES; |
17317 |
++ goto dput_and_out; |
17318 |
++ }; |
17319 |
++ |
17320 |
+ mutex_lock(&inode->i_mutex); |
17321 |
+ if (mode == (mode_t) -1) |
17322 |
+ mode = inode->i_mode; |
17323 |
++ |
17324 |
++ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) { |
17325 |
++ error = -EACCES; |
17326 |
++ mutex_unlock(&inode->i_mutex); |
17327 |
++ goto dput_and_out; |
17328 |
++ } |
17329 |
++ |
17330 |
+ newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
17331 |
+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
17332 |
+ error = notify_change(nd.dentry, &newattrs); |
17333 |
+@@ -631,7 +680,7 @@ asmlinkage long sys_chmod(const char __u |
17334 |
+ return sys_fchmodat(AT_FDCWD, filename, mode); |
17335 |
+ } |
17336 |
+ |
17337 |
+-static int chown_common(struct dentry * dentry, uid_t user, gid_t group) |
17338 |
++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt) |
17339 |
+ { |
17340 |
+ struct inode * inode; |
17341 |
+ int error; |
17342 |
+@@ -648,6 +697,12 @@ static int chown_common(struct dentry * |
17343 |
+ error = -EPERM; |
17344 |
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
17345 |
+ goto out; |
17346 |
++ |
17347 |
++ if (!gr_acl_handle_chown(dentry, mnt)) { |
17348 |
++ error = -EACCES; |
17349 |
++ goto out; |
17350 |
++ } |
17351 |
++ |
17352 |
+ newattrs.ia_valid = ATTR_CTIME; |
17353 |
+ if (user != (uid_t) -1) { |
17354 |
+ newattrs.ia_valid |= ATTR_UID; |
17355 |
+@@ -675,7 +730,7 @@ asmlinkage long sys_chown(const char __u |
17356 |
+ error = user_path_walk(filename, &nd); |
17357 |
+ if (error) |
17358 |
+ goto out; |
17359 |
+- error = chown_common(nd.dentry, user, group); |
17360 |
++ error = chown_common(nd.dentry, user, group, nd.mnt); |
17361 |
+ path_release(&nd); |
17362 |
+ out: |
17363 |
+ return error; |
17364 |
+@@ -695,7 +750,7 @@ asmlinkage long sys_fchownat(int dfd, co |
17365 |
+ error = __user_walk_fd(dfd, filename, follow, &nd); |
17366 |
+ if (error) |
17367 |
+ goto out; |
17368 |
+- error = chown_common(nd.dentry, user, group); |
17369 |
++ error = chown_common(nd.dentry, user, group, nd.mnt); |
17370 |
+ path_release(&nd); |
17371 |
+ out: |
17372 |
+ return error; |
17373 |
+@@ -709,7 +764,7 @@ asmlinkage long sys_lchown(const char __ |
17374 |
+ error = user_path_walk_link(filename, &nd); |
17375 |
+ if (error) |
17376 |
+ goto out; |
17377 |
+- error = chown_common(nd.dentry, user, group); |
17378 |
++ error = chown_common(nd.dentry, user, group, nd.mnt); |
17379 |
+ path_release(&nd); |
17380 |
+ out: |
17381 |
+ return error; |
17382 |
+@@ -728,7 +783,7 @@ asmlinkage long sys_fchown(unsigned int |
17383 |
+ |
17384 |
+ dentry = file->f_path.dentry; |
17385 |
+ audit_inode(NULL, dentry); |
17386 |
+- error = chown_common(dentry, user, group); |
17387 |
++ error = chown_common(dentry, user, group, file->f_vfsmnt); |
17388 |
+ fput(file); |
17389 |
+ out: |
17390 |
+ return error; |
17391 |
+@@ -939,6 +994,7 @@ repeat: |
17392 |
+ * N.B. For clone tasks sharing a files structure, this test |
17393 |
+ * will limit the total number of files that can be opened. |
17394 |
+ */ |
17395 |
++ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0); |
17396 |
+ if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) |
17397 |
+ goto out; |
17398 |
+ |
17399 |
+diff -urNp linux-2.6.24.4/fs/partitions/efi.c linux-2.6.24.4/fs/partitions/efi.c |
17400 |
+--- linux-2.6.24.4/fs/partitions/efi.c 2008-03-24 14:49:18.000000000 -0400 |
17401 |
++++ linux-2.6.24.4/fs/partitions/efi.c 2008-03-26 17:56:56.000000000 -0400 |
17402 |
+@@ -99,7 +99,7 @@ |
17403 |
+ #ifdef EFI_DEBUG |
17404 |
+ #define Dprintk(x...) printk(KERN_DEBUG x) |
17405 |
+ #else |
17406 |
+-#define Dprintk(x...) |
17407 |
++#define Dprintk(x...) do {} while (0) |
17408 |
+ #endif |
17409 |
+ |
17410 |
+ /* This allows a kernel command line option 'gpt' to override |
17411 |
+diff -urNp linux-2.6.24.4/fs/pipe.c linux-2.6.24.4/fs/pipe.c |
17412 |
+--- linux-2.6.24.4/fs/pipe.c 2008-03-24 14:49:18.000000000 -0400 |
17413 |
++++ linux-2.6.24.4/fs/pipe.c 2008-03-26 17:56:56.000000000 -0400 |
17414 |
+@@ -887,7 +887,7 @@ void free_pipe_info(struct inode *inode) |
17415 |
+ inode->i_pipe = NULL; |
17416 |
+ } |
17417 |
+ |
17418 |
+-static struct vfsmount *pipe_mnt __read_mostly; |
17419 |
++struct vfsmount *pipe_mnt __read_mostly; |
17420 |
+ static int pipefs_delete_dentry(struct dentry *dentry) |
17421 |
+ { |
17422 |
+ /* |
17423 |
+diff -urNp linux-2.6.24.4/fs/proc/array.c linux-2.6.24.4/fs/proc/array.c |
17424 |
+--- linux-2.6.24.4/fs/proc/array.c 2008-03-24 14:49:18.000000000 -0400 |
17425 |
++++ linux-2.6.24.4/fs/proc/array.c 2008-03-26 17:56:56.000000000 -0400 |
17426 |
+@@ -305,6 +305,21 @@ static inline char *task_context_switch_ |
17427 |
+ p->nivcsw); |
17428 |
+ } |
17429 |
+ |
17430 |
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
17431 |
++static inline char *task_pax(struct task_struct *p, char *buffer) |
17432 |
++{ |
17433 |
++ if (p->mm) |
17434 |
++ return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n", |
17435 |
++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p', |
17436 |
++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e', |
17437 |
++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm', |
17438 |
++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r', |
17439 |
++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's'); |
17440 |
++ else |
17441 |
++ return buffer + sprintf(buffer, "PaX:\t-----\n"); |
17442 |
++} |
17443 |
++#endif |
17444 |
++ |
17445 |
+ int proc_pid_status(struct task_struct *task, char *buffer) |
17446 |
+ { |
17447 |
+ char *orig = buffer; |
17448 |
+@@ -324,6 +339,11 @@ int proc_pid_status(struct task_struct * |
17449 |
+ buffer = task_show_regs(task, buffer); |
17450 |
+ #endif |
17451 |
+ buffer = task_context_switch_counts(task, buffer); |
17452 |
++ |
17453 |
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
17454 |
++ buffer = task_pax(task, buffer); |
17455 |
++#endif |
17456 |
++ |
17457 |
+ return buffer - orig; |
17458 |
+ } |
17459 |
+ |
17460 |
+@@ -386,6 +406,12 @@ static cputime_t task_gtime(struct task_ |
17461 |
+ return p->gtime; |
17462 |
+ } |
17463 |
+ |
17464 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
17465 |
++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \ |
17466 |
++ (_mm->pax_flags & MF_PAX_RANDMMAP || \ |
17467 |
++ _mm->pax_flags & MF_PAX_SEGMEXEC)) |
17468 |
++#endif |
17469 |
++ |
17470 |
+ static int do_task_stat(struct task_struct *task, char *buffer, int whole) |
17471 |
+ { |
17472 |
+ unsigned long vsize, eip, esp, wchan = ~0UL; |
17473 |
+@@ -481,6 +507,19 @@ static int do_task_stat(struct task_stru |
17474 |
+ gtime = task_gtime(task); |
17475 |
+ } |
17476 |
+ |
17477 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
17478 |
++ if (PAX_RAND_FLAGS(mm)) { |
17479 |
++ eip = 0; |
17480 |
++ esp = 0; |
17481 |
++ wchan = 0; |
17482 |
++ } |
17483 |
++#endif |
17484 |
++#ifdef CONFIG_GRKERNSEC_HIDESYM |
17485 |
++ wchan = 0; |
17486 |
++ eip =0; |
17487 |
++ esp =0; |
17488 |
++#endif |
17489 |
++ |
17490 |
+ /* scale priority and nice values from timeslices to -20..20 */ |
17491 |
+ /* to make it look like a "normal" Unix priority/nice value */ |
17492 |
+ priority = task_prio(task); |
17493 |
+@@ -521,9 +560,15 @@ static int do_task_stat(struct task_stru |
17494 |
+ vsize, |
17495 |
+ mm ? get_mm_rss(mm) : 0, |
17496 |
+ rsslim, |
17497 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
17498 |
++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0), |
17499 |
++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0), |
17500 |
++ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0), |
17501 |
++#else |
17502 |
+ mm ? mm->start_code : 0, |
17503 |
+ mm ? mm->end_code : 0, |
17504 |
+ mm ? mm->start_stack : 0, |
17505 |
++#endif |
17506 |
+ esp, |
17507 |
+ eip, |
17508 |
+ /* The signal information here is obsolete. |
17509 |
+@@ -572,3 +617,14 @@ int proc_pid_statm(struct task_struct *t |
17510 |
+ return sprintf(buffer, "%d %d %d %d %d %d %d\n", |
17511 |
+ size, resident, shared, text, lib, data, 0); |
17512 |
+ } |
17513 |
++ |
17514 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
17515 |
++int proc_pid_ipaddr(struct task_struct *task, char * buffer) |
17516 |
++{ |
17517 |
++ int len; |
17518 |
++ |
17519 |
++ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip)); |
17520 |
++ return len; |
17521 |
++} |
17522 |
++#endif |
17523 |
++ |
17524 |
+diff -urNp linux-2.6.24.4/fs/proc/base.c linux-2.6.24.4/fs/proc/base.c |
17525 |
+--- linux-2.6.24.4/fs/proc/base.c 2008-03-24 14:49:18.000000000 -0400 |
17526 |
++++ linux-2.6.24.4/fs/proc/base.c 2008-03-26 19:57:50.000000000 -0400 |
17527 |
+@@ -76,6 +76,8 @@ |
17528 |
+ #include <linux/oom.h> |
17529 |
+ #include <linux/elf.h> |
17530 |
+ #include <linux/pid_namespace.h> |
17531 |
++#include <linux/grsecurity.h> |
17532 |
++ |
17533 |
+ #include "internal.h" |
17534 |
+ |
17535 |
+ /* NOTE: |
17536 |
+@@ -126,7 +128,7 @@ struct pid_entry { |
17537 |
+ NULL, &proc_info_file_operations, \ |
17538 |
+ { .proc_read = &proc_##OTYPE } ) |
17539 |
+ |
17540 |
+-int maps_protect; |
17541 |
++int maps_protect = 1; |
17542 |
+ EXPORT_SYMBOL(maps_protect); |
17543 |
+ |
17544 |
+ static struct fs_struct *get_fs_struct(struct task_struct *task) |
17545 |
+@@ -200,7 +202,7 @@ static int proc_root_link(struct inode * |
17546 |
+ (task->parent == current && \ |
17547 |
+ (task->ptrace & PT_PTRACED) && \ |
17548 |
+ (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \ |
17549 |
+- security_ptrace(current,task) == 0)) |
17550 |
++ security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task))) |
17551 |
+ |
17552 |
+ struct mm_struct *mm_for_maps(struct task_struct *task) |
17553 |
+ { |
17554 |
+@@ -265,9 +267,9 @@ static int proc_pid_auxv(struct task_str |
17555 |
+ struct mm_struct *mm = get_task_mm(task); |
17556 |
+ if (mm) { |
17557 |
+ unsigned int nwords = 0; |
17558 |
+- do |
17559 |
++ do { |
17560 |
+ nwords += 2; |
17561 |
+- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ |
17562 |
++ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ |
17563 |
+ res = nwords * sizeof(mm->saved_auxv[0]); |
17564 |
+ if (res > PAGE_SIZE) |
17565 |
+ res = PAGE_SIZE; |
17566 |
+@@ -609,7 +611,7 @@ static ssize_t mem_read(struct file * fi |
17567 |
+ if (!task) |
17568 |
+ goto out_no_task; |
17569 |
+ |
17570 |
+- if (!MAY_PTRACE(task) || !ptrace_may_attach(task)) |
17571 |
++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task)) |
17572 |
+ goto out; |
17573 |
+ |
17574 |
+ ret = -ENOMEM; |
17575 |
+@@ -679,7 +681,7 @@ static ssize_t mem_write(struct file * f |
17576 |
+ if (!task) |
17577 |
+ goto out_no_task; |
17578 |
+ |
17579 |
+- if (!MAY_PTRACE(task) || !ptrace_may_attach(task)) |
17580 |
++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task)) |
17581 |
+ goto out; |
17582 |
+ |
17583 |
+ copied = -ENOMEM; |
17584 |
+@@ -1202,7 +1204,11 @@ static struct inode *proc_pid_make_inode |
17585 |
+ inode->i_gid = 0; |
17586 |
+ if (task_dumpable(task)) { |
17587 |
+ inode->i_uid = task->euid; |
17588 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17589 |
++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; |
17590 |
++#else |
17591 |
+ inode->i_gid = task->egid; |
17592 |
++#endif |
17593 |
+ } |
17594 |
+ security_task_to_inode(task, inode); |
17595 |
+ |
17596 |
+@@ -1218,17 +1224,45 @@ static int pid_getattr(struct vfsmount * |
17597 |
+ { |
17598 |
+ struct inode *inode = dentry->d_inode; |
17599 |
+ struct task_struct *task; |
17600 |
++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17601 |
++ struct task_struct *tmp = current; |
17602 |
++#endif |
17603 |
++ |
17604 |
+ generic_fillattr(inode, stat); |
17605 |
+ |
17606 |
+ rcu_read_lock(); |
17607 |
+ stat->uid = 0; |
17608 |
+ stat->gid = 0; |
17609 |
+ task = pid_task(proc_pid(inode), PIDTYPE_PID); |
17610 |
+- if (task) { |
17611 |
++ |
17612 |
++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) { |
17613 |
++ rcu_read_unlock(); |
17614 |
++ return -ENOENT; |
17615 |
++ } |
17616 |
++ |
17617 |
++ |
17618 |
++ if (task |
17619 |
++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17620 |
++ && (!tmp->uid || (tmp->uid == task->uid) |
17621 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17622 |
++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID) |
17623 |
++#endif |
17624 |
++ ) |
17625 |
++#endif |
17626 |
++ ) { |
17627 |
+ if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || |
17628 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17629 |
++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) || |
17630 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17631 |
++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) || |
17632 |
++#endif |
17633 |
+ task_dumpable(task)) { |
17634 |
+ stat->uid = task->euid; |
17635 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17636 |
++ stat->gid = CONFIG_GRKERNSEC_PROC_GID; |
17637 |
++#else |
17638 |
+ stat->gid = task->egid; |
17639 |
++#endif |
17640 |
+ } |
17641 |
+ } |
17642 |
+ rcu_read_unlock(); |
17643 |
+@@ -1256,11 +1290,21 @@ static int pid_revalidate(struct dentry |
17644 |
+ { |
17645 |
+ struct inode *inode = dentry->d_inode; |
17646 |
+ struct task_struct *task = get_proc_task(inode); |
17647 |
++ |
17648 |
+ if (task) { |
17649 |
+ if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || |
17650 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17651 |
++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) || |
17652 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17653 |
++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) || |
17654 |
++#endif |
17655 |
+ task_dumpable(task)) { |
17656 |
+ inode->i_uid = task->euid; |
17657 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17658 |
++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; |
17659 |
++#else |
17660 |
+ inode->i_gid = task->egid; |
17661 |
++#endif |
17662 |
+ } else { |
17663 |
+ inode->i_uid = 0; |
17664 |
+ inode->i_gid = 0; |
17665 |
+@@ -1633,12 +1677,22 @@ static int proc_fd_permission(struct ino |
17666 |
+ struct nameidata *nd) |
17667 |
+ { |
17668 |
+ int rv; |
17669 |
++ struct task_struct *task; |
17670 |
+ |
17671 |
+ rv = generic_permission(inode, mask, NULL); |
17672 |
+- if (rv == 0) |
17673 |
+- return 0; |
17674 |
++ |
17675 |
+ if (task_pid(current) == proc_pid(inode)) |
17676 |
+ rv = 0; |
17677 |
++ |
17678 |
++ task = get_proc_task(inode); |
17679 |
++ if (task == NULL) |
17680 |
++ return rv; |
17681 |
++ |
17682 |
++ if (gr_acl_handle_procpidmem(task)) |
17683 |
++ rv = -EACCES; |
17684 |
++ |
17685 |
++ put_task_struct(task); |
17686 |
++ |
17687 |
+ return rv; |
17688 |
+ } |
17689 |
+ |
17690 |
+@@ -1749,6 +1803,9 @@ static struct dentry *proc_pident_lookup |
17691 |
+ if (!task) |
17692 |
+ goto out_no_task; |
17693 |
+ |
17694 |
++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)) |
17695 |
++ goto out; |
17696 |
++ |
17697 |
+ /* |
17698 |
+ * Yes, it does not scale. And it should not. Don't add |
17699 |
+ * new entries into /proc/<tgid>/ without very good reasons. |
17700 |
+@@ -1793,6 +1850,9 @@ static int proc_pident_readdir(struct fi |
17701 |
+ if (!task) |
17702 |
+ goto out_no_task; |
17703 |
+ |
17704 |
++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)) |
17705 |
++ goto out; |
17706 |
++ |
17707 |
+ ret = 0; |
17708 |
+ i = filp->f_pos; |
17709 |
+ switch (i) { |
17710 |
+@@ -2147,6 +2207,9 @@ static struct dentry *proc_base_lookup(s |
17711 |
+ if (p > last) |
17712 |
+ goto out; |
17713 |
+ |
17714 |
++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)) |
17715 |
++ goto out; |
17716 |
++ |
17717 |
+ error = proc_base_instantiate(dir, dentry, task, p); |
17718 |
+ |
17719 |
+ out: |
17720 |
+@@ -2250,6 +2313,9 @@ static const struct pid_entry tgid_base_ |
17721 |
+ #ifdef CONFIG_TASK_IO_ACCOUNTING |
17722 |
+ INF("io", S_IRUGO, pid_io_accounting), |
17723 |
+ #endif |
17724 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
17725 |
++ INF("ipaddr", S_IRUSR, pid_ipaddr), |
17726 |
++#endif |
17727 |
+ }; |
17728 |
+ |
17729 |
+ static int proc_tgid_base_readdir(struct file * filp, |
17730 |
+@@ -2378,7 +2444,14 @@ static struct dentry *proc_pid_instantia |
17731 |
+ if (!inode) |
17732 |
+ goto out; |
17733 |
+ |
17734 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17735 |
++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR; |
17736 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17737 |
++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; |
17738 |
++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP; |
17739 |
++#else |
17740 |
+ inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; |
17741 |
++#endif |
17742 |
+ inode->i_op = &proc_tgid_base_inode_operations; |
17743 |
+ inode->i_fop = &proc_tgid_base_operations; |
17744 |
+ inode->i_flags|=S_IMMUTABLE; |
17745 |
+@@ -2421,7 +2494,11 @@ struct dentry *proc_pid_lookup(struct in |
17746 |
+ if (!task) |
17747 |
+ goto out; |
17748 |
+ |
17749 |
++ if (gr_check_hidden_task(task)) |
17750 |
++ goto out_put_task; |
17751 |
++ |
17752 |
+ result = proc_pid_instantiate(dir, dentry, task, NULL); |
17753 |
++out_put_task: |
17754 |
+ put_task_struct(task); |
17755 |
+ out: |
17756 |
+ return result; |
17757 |
+@@ -2486,6 +2563,9 @@ int proc_pid_readdir(struct file * filp, |
17758 |
+ { |
17759 |
+ unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; |
17760 |
+ struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); |
17761 |
++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17762 |
++ struct task_struct *tmp = current; |
17763 |
++#endif |
17764 |
+ struct tgid_iter iter; |
17765 |
+ struct pid_namespace *ns; |
17766 |
+ |
17767 |
+@@ -2504,6 +2584,17 @@ int proc_pid_readdir(struct file * filp, |
17768 |
+ for (iter = next_tgid(ns, iter); |
17769 |
+ iter.task; |
17770 |
+ iter.tgid += 1, iter = next_tgid(ns, iter)) { |
17771 |
++ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task) |
17772 |
++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17773 |
++ || (tmp->uid && (iter.task->uid != tmp->uid) |
17774 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17775 |
++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID) |
17776 |
++#endif |
17777 |
++ ) |
17778 |
++#endif |
17779 |
++ ) |
17780 |
++ continue; |
17781 |
++ |
17782 |
+ filp->f_pos = iter.tgid + TGID_OFFSET; |
17783 |
+ if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) { |
17784 |
+ put_task_struct(iter.task); |
17785 |
+diff -urNp linux-2.6.24.4/fs/proc/inode.c linux-2.6.24.4/fs/proc/inode.c |
17786 |
+--- linux-2.6.24.4/fs/proc/inode.c 2008-03-24 14:49:18.000000000 -0400 |
17787 |
++++ linux-2.6.24.4/fs/proc/inode.c 2008-03-26 17:56:56.000000000 -0400 |
17788 |
+@@ -411,7 +411,11 @@ struct inode *proc_get_inode(struct supe |
17789 |
+ if (de->mode) { |
17790 |
+ inode->i_mode = de->mode; |
17791 |
+ inode->i_uid = de->uid; |
17792 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17793 |
++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; |
17794 |
++#else |
17795 |
+ inode->i_gid = de->gid; |
17796 |
++#endif |
17797 |
+ } |
17798 |
+ if (de->size) |
17799 |
+ inode->i_size = de->size; |
17800 |
+diff -urNp linux-2.6.24.4/fs/proc/internal.h linux-2.6.24.4/fs/proc/internal.h |
17801 |
+--- linux-2.6.24.4/fs/proc/internal.h 2008-03-24 14:49:18.000000000 -0400 |
17802 |
++++ linux-2.6.24.4/fs/proc/internal.h 2008-03-26 17:56:56.000000000 -0400 |
17803 |
+@@ -52,6 +52,9 @@ extern int proc_tid_stat(struct task_str |
17804 |
+ extern int proc_tgid_stat(struct task_struct *, char *); |
17805 |
+ extern int proc_pid_status(struct task_struct *, char *); |
17806 |
+ extern int proc_pid_statm(struct task_struct *, char *); |
17807 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
17808 |
++extern int proc_pid_ipaddr(struct task_struct*,char*); |
17809 |
++#endif |
17810 |
+ |
17811 |
+ extern const struct file_operations proc_maps_operations; |
17812 |
+ extern const struct file_operations proc_numa_maps_operations; |
17813 |
+diff -urNp linux-2.6.24.4/fs/proc/proc_misc.c linux-2.6.24.4/fs/proc/proc_misc.c |
17814 |
+--- linux-2.6.24.4/fs/proc/proc_misc.c 2008-03-24 14:49:18.000000000 -0400 |
17815 |
++++ linux-2.6.24.4/fs/proc/proc_misc.c 2008-03-26 17:56:56.000000000 -0400 |
17816 |
+@@ -687,6 +687,8 @@ void create_seq_entry(char *name, mode_t |
17817 |
+ |
17818 |
+ void __init proc_misc_init(void) |
17819 |
+ { |
17820 |
++ int gr_mode = 0; |
17821 |
++ |
17822 |
+ static struct { |
17823 |
+ char *name; |
17824 |
+ int (*read_proc)(char*,char**,off_t,int,int*,void*); |
17825 |
+@@ -702,13 +704,24 @@ void __init proc_misc_init(void) |
17826 |
+ {"stram", stram_read_proc}, |
17827 |
+ #endif |
17828 |
+ {"filesystems", filesystems_read_proc}, |
17829 |
++#ifndef CONFIG_GRKERNSEC_PROC_ADD |
17830 |
+ {"cmdline", cmdline_read_proc}, |
17831 |
++#endif |
17832 |
+ {"execdomains", execdomains_read_proc}, |
17833 |
+ {NULL,} |
17834 |
+ }; |
17835 |
+ for (p = simple_ones; p->name; p++) |
17836 |
+ create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL); |
17837 |
+ |
17838 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17839 |
++ gr_mode = S_IRUSR; |
17840 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17841 |
++ gr_mode = S_IRUSR | S_IRGRP; |
17842 |
++#endif |
17843 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
17844 |
++ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL); |
17845 |
++#endif |
17846 |
++ |
17847 |
+ proc_symlink("mounts", NULL, "self/mounts"); |
17848 |
+ |
17849 |
+ /* And now for trickier ones */ |
17850 |
+@@ -721,7 +734,11 @@ void __init proc_misc_init(void) |
17851 |
+ } |
17852 |
+ #endif |
17853 |
+ create_seq_entry("locks", 0, &proc_locks_operations); |
17854 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
17855 |
++ create_seq_entry("devices", gr_mode, &proc_devinfo_operations); |
17856 |
++#else |
17857 |
+ create_seq_entry("devices", 0, &proc_devinfo_operations); |
17858 |
++#endif |
17859 |
+ create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); |
17860 |
+ #ifdef CONFIG_BLOCK |
17861 |
+ create_seq_entry("partitions", 0, &proc_partitions_operations); |
17862 |
+@@ -729,7 +746,11 @@ void __init proc_misc_init(void) |
17863 |
+ create_seq_entry("stat", 0, &proc_stat_operations); |
17864 |
+ create_seq_entry("interrupts", 0, &proc_interrupts_operations); |
17865 |
+ #ifdef CONFIG_SLABINFO |
17866 |
++#ifdef CONFIG_GRKRENSEC_PROC_ADD |
17867 |
++ create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations); |
17868 |
++#else |
17869 |
+ create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); |
17870 |
++#endif |
17871 |
+ #ifdef CONFIG_DEBUG_SLAB_LEAK |
17872 |
+ create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations); |
17873 |
+ #endif |
17874 |
+@@ -747,7 +768,7 @@ void __init proc_misc_init(void) |
17875 |
+ #ifdef CONFIG_SCHEDSTATS |
17876 |
+ create_seq_entry("schedstat", 0, &proc_schedstat_operations); |
17877 |
+ #endif |
17878 |
+-#ifdef CONFIG_PROC_KCORE |
17879 |
++#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD) |
17880 |
+ proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL); |
17881 |
+ if (proc_root_kcore) { |
17882 |
+ proc_root_kcore->proc_fops = &proc_kcore_operations; |
17883 |
+diff -urNp linux-2.6.24.4/fs/proc/proc_net.c linux-2.6.24.4/fs/proc/proc_net.c |
17884 |
+--- linux-2.6.24.4/fs/proc/proc_net.c 2008-03-24 14:49:18.000000000 -0400 |
17885 |
++++ linux-2.6.24.4/fs/proc/proc_net.c 2008-03-26 17:56:56.000000000 -0400 |
17886 |
+@@ -69,7 +69,13 @@ static __net_init int proc_net_ns_init(s |
17887 |
+ goto out; |
17888 |
+ |
17889 |
+ err = -EEXIST; |
17890 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17891 |
++ netd = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, root); |
17892 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17893 |
++ netd = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, root); |
17894 |
++#else |
17895 |
+ netd = proc_mkdir("net", root); |
17896 |
++#endif |
17897 |
+ if (!netd) |
17898 |
+ goto free_root; |
17899 |
+ |
17900 |
+diff -urNp linux-2.6.24.4/fs/proc/proc_sysctl.c linux-2.6.24.4/fs/proc/proc_sysctl.c |
17901 |
+--- linux-2.6.24.4/fs/proc/proc_sysctl.c 2008-03-24 14:49:18.000000000 -0400 |
17902 |
++++ linux-2.6.24.4/fs/proc/proc_sysctl.c 2008-03-26 17:56:56.000000000 -0400 |
17903 |
+@@ -7,6 +7,8 @@ |
17904 |
+ #include <linux/security.h> |
17905 |
+ #include "internal.h" |
17906 |
+ |
17907 |
++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op); |
17908 |
++ |
17909 |
+ static struct dentry_operations proc_sys_dentry_operations; |
17910 |
+ static const struct file_operations proc_sys_file_operations; |
17911 |
+ static struct inode_operations proc_sys_inode_operations; |
17912 |
+@@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st |
17913 |
+ if (!table) |
17914 |
+ goto out; |
17915 |
+ |
17916 |
++ if (gr_handle_sysctl(table, 001)) |
17917 |
++ goto out; |
17918 |
++ |
17919 |
+ err = ERR_PTR(-ENOMEM); |
17920 |
+ inode = proc_sys_make_inode(dir, table); |
17921 |
+ if (!inode) |
17922 |
+@@ -360,6 +365,9 @@ static int proc_sys_readdir(struct file |
17923 |
+ if (pos < filp->f_pos) |
17924 |
+ continue; |
17925 |
+ |
17926 |
++ if (gr_handle_sysctl(table, 0)) |
17927 |
++ continue; |
17928 |
++ |
17929 |
+ if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0) |
17930 |
+ goto out; |
17931 |
+ filp->f_pos = pos + 1; |
17932 |
+@@ -422,6 +430,30 @@ out: |
17933 |
+ return error; |
17934 |
+ } |
17935 |
+ |
17936 |
++/* Eric Biederman is to blame */ |
17937 |
++static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) |
17938 |
++{ |
17939 |
++ int error = 0; |
17940 |
++ struct ctl_table_header *head; |
17941 |
++ struct ctl_table *table; |
17942 |
++ |
17943 |
++ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); |
17944 |
++ /* Has the sysctl entry disappeared on us? */ |
17945 |
++ if (!table) |
17946 |
++ goto out; |
17947 |
++ |
17948 |
++ if (gr_handle_sysctl(table, 001)) { |
17949 |
++ error = -ENOENT; |
17950 |
++ goto out; |
17951 |
++ } |
17952 |
++ |
17953 |
++out: |
17954 |
++ sysctl_head_finish(head); |
17955 |
++ |
17956 |
++ generic_fillattr(dentry->d_inode, stat); |
17957 |
++ |
17958 |
++ return error; |
17959 |
++} |
17960 |
+ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr) |
17961 |
+ { |
17962 |
+ struct inode *inode = dentry->d_inode; |
17963 |
+@@ -450,6 +482,7 @@ static struct inode_operations proc_sys_ |
17964 |
+ .lookup = proc_sys_lookup, |
17965 |
+ .permission = proc_sys_permission, |
17966 |
+ .setattr = proc_sys_setattr, |
17967 |
++ .getattr = proc_sys_getattr, |
17968 |
+ }; |
17969 |
+ |
17970 |
+ static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd) |
17971 |
+diff -urNp linux-2.6.24.4/fs/proc/root.c linux-2.6.24.4/fs/proc/root.c |
17972 |
+--- linux-2.6.24.4/fs/proc/root.c 2008-03-24 14:49:18.000000000 -0400 |
17973 |
++++ linux-2.6.24.4/fs/proc/root.c 2008-03-26 17:56:56.000000000 -0400 |
17974 |
+@@ -137,7 +137,15 @@ void __init proc_root_init(void) |
17975 |
+ #ifdef CONFIG_PROC_DEVICETREE |
17976 |
+ proc_device_tree_init(); |
17977 |
+ #endif |
17978 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
17979 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17980 |
++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL); |
17981 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17982 |
++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL); |
17983 |
++#endif |
17984 |
++#else |
17985 |
+ proc_bus = proc_mkdir("bus", NULL); |
17986 |
++#endif |
17987 |
+ proc_sys_init(); |
17988 |
+ } |
17989 |
+ |
17990 |
+diff -urNp linux-2.6.24.4/fs/proc/task_mmu.c linux-2.6.24.4/fs/proc/task_mmu.c |
17991 |
+--- linux-2.6.24.4/fs/proc/task_mmu.c 2008-03-24 14:49:18.000000000 -0400 |
17992 |
++++ linux-2.6.24.4/fs/proc/task_mmu.c 2008-03-26 17:56:56.000000000 -0400 |
17993 |
+@@ -44,15 +44,27 @@ char *task_mem(struct mm_struct *mm, cha |
17994 |
+ "VmStk:\t%8lu kB\n" |
17995 |
+ "VmExe:\t%8lu kB\n" |
17996 |
+ "VmLib:\t%8lu kB\n" |
17997 |
+- "VmPTE:\t%8lu kB\n", |
17998 |
+- hiwater_vm << (PAGE_SHIFT-10), |
17999 |
++ "VmPTE:\t%8lu kB\n" |
18000 |
++ |
18001 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
18002 |
++ "CsBase:\t%8lx\nCsLim:\t%8lx\n" |
18003 |
++#endif |
18004 |
++ |
18005 |
++ ,hiwater_vm << (PAGE_SHIFT-10), |
18006 |
+ (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), |
18007 |
+ mm->locked_vm << (PAGE_SHIFT-10), |
18008 |
+ hiwater_rss << (PAGE_SHIFT-10), |
18009 |
+ total_rss << (PAGE_SHIFT-10), |
18010 |
+ data << (PAGE_SHIFT-10), |
18011 |
+ mm->stack_vm << (PAGE_SHIFT-10), text, lib, |
18012 |
+- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); |
18013 |
++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10 |
18014 |
++ |
18015 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
18016 |
++ , mm->context.user_cs_base, mm->context.user_cs_limit |
18017 |
++#endif |
18018 |
++ |
18019 |
++ ); |
18020 |
++ |
18021 |
+ return buffer; |
18022 |
+ } |
18023 |
+ |
18024 |
+@@ -131,6 +143,12 @@ struct pmd_walker { |
18025 |
+ unsigned long, void *); |
18026 |
+ }; |
18027 |
+ |
18028 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
18029 |
++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \ |
18030 |
++ (_mm->pax_flags & MF_PAX_RANDMMAP || \ |
18031 |
++ _mm->pax_flags & MF_PAX_SEGMEXEC)) |
18032 |
++#endif |
18033 |
++ |
18034 |
+ static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss) |
18035 |
+ { |
18036 |
+ struct proc_maps_private *priv = m->private; |
18037 |
+@@ -153,13 +171,22 @@ static int show_map_internal(struct seq_ |
18038 |
+ } |
18039 |
+ |
18040 |
+ seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n", |
18041 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
18042 |
++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start, |
18043 |
++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end, |
18044 |
++#else |
18045 |
+ vma->vm_start, |
18046 |
+ vma->vm_end, |
18047 |
++#endif |
18048 |
+ flags & VM_READ ? 'r' : '-', |
18049 |
+ flags & VM_WRITE ? 'w' : '-', |
18050 |
+ flags & VM_EXEC ? 'x' : '-', |
18051 |
+ flags & VM_MAYSHARE ? 's' : 'p', |
18052 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
18053 |
++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT, |
18054 |
++#else |
18055 |
+ vma->vm_pgoff << PAGE_SHIFT, |
18056 |
++#endif |
18057 |
+ MAJOR(dev), MINOR(dev), ino, &len); |
18058 |
+ |
18059 |
+ /* |
18060 |
+@@ -173,11 +200,11 @@ static int show_map_internal(struct seq_ |
18061 |
+ const char *name = arch_vma_name(vma); |
18062 |
+ if (!name) { |
18063 |
+ if (mm) { |
18064 |
+- if (vma->vm_start <= mm->start_brk && |
18065 |
+- vma->vm_end >= mm->brk) { |
18066 |
++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { |
18067 |
+ name = "[heap]"; |
18068 |
+- } else if (vma->vm_start <= mm->start_stack && |
18069 |
+- vma->vm_end >= mm->start_stack) { |
18070 |
++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) || |
18071 |
++ (vma->vm_start <= mm->start_stack && |
18072 |
++ vma->vm_end >= mm->start_stack)) { |
18073 |
+ name = "[stack]"; |
18074 |
+ } |
18075 |
+ } else { |
18076 |
+@@ -191,7 +218,27 @@ static int show_map_internal(struct seq_ |
18077 |
+ } |
18078 |
+ seq_putc(m, '\n'); |
18079 |
+ |
18080 |
+- if (mss) |
18081 |
++ |
18082 |
++ if (mss) { |
18083 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
18084 |
++ if (PAX_RAND_FLAGS(mm)) |
18085 |
++ seq_printf(m, |
18086 |
++ "Size: %8lu kB\n" |
18087 |
++ "Rss: %8lu kB\n" |
18088 |
++ "Shared_Clean: %8lu kB\n" |
18089 |
++ "Shared_Dirty: %8lu kB\n" |
18090 |
++ "Private_Clean: %8lu kB\n" |
18091 |
++ "Private_Dirty: %8lu kB\n", |
18092 |
++ "Referenced: %8lu kB\n", |
18093 |
++ 0UL, |
18094 |
++ 0UL, |
18095 |
++ 0UL, |
18096 |
++ 0UL, |
18097 |
++ 0UL, |
18098 |
++ 0UL, |
18099 |
++ 0UL); |
18100 |
++ else |
18101 |
++#endif |
18102 |
+ seq_printf(m, |
18103 |
+ "Size: %8lu kB\n" |
18104 |
+ "Rss: %8lu kB\n" |
18105 |
+@@ -207,6 +254,7 @@ static int show_map_internal(struct seq_ |
18106 |
+ mss->private_clean >> 10, |
18107 |
+ mss->private_dirty >> 10, |
18108 |
+ mss->referenced >> 10); |
18109 |
++ } |
18110 |
+ |
18111 |
+ if (m->count < m->size) /* vma is copied successfully */ |
18112 |
+ m->version = (vma != get_gate_vma(task))? vma->vm_start: 0; |
18113 |
+diff -urNp linux-2.6.24.4/fs/readdir.c linux-2.6.24.4/fs/readdir.c |
18114 |
+--- linux-2.6.24.4/fs/readdir.c 2008-03-24 14:49:18.000000000 -0400 |
18115 |
++++ linux-2.6.24.4/fs/readdir.c 2008-03-26 17:56:56.000000000 -0400 |
18116 |
+@@ -16,6 +16,8 @@ |
18117 |
+ #include <linux/security.h> |
18118 |
+ #include <linux/syscalls.h> |
18119 |
+ #include <linux/unistd.h> |
18120 |
++#include <linux/namei.h> |
18121 |
++#include <linux/grsecurity.h> |
18122 |
+ |
18123 |
+ #include <asm/uaccess.h> |
18124 |
+ |
18125 |
+@@ -64,6 +66,7 @@ struct old_linux_dirent { |
18126 |
+ |
18127 |
+ struct readdir_callback { |
18128 |
+ struct old_linux_dirent __user * dirent; |
18129 |
++ struct file * file; |
18130 |
+ int result; |
18131 |
+ }; |
18132 |
+ |
18133 |
+@@ -79,6 +82,10 @@ static int fillonedir(void * __buf, cons |
18134 |
+ d_ino = ino; |
18135 |
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) |
18136 |
+ return -EOVERFLOW; |
18137 |
++ |
18138 |
++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino)) |
18139 |
++ return 0; |
18140 |
++ |
18141 |
+ buf->result++; |
18142 |
+ dirent = buf->dirent; |
18143 |
+ if (!access_ok(VERIFY_WRITE, dirent, |
18144 |
+@@ -110,6 +117,7 @@ asmlinkage long old_readdir(unsigned int |
18145 |
+ |
18146 |
+ buf.result = 0; |
18147 |
+ buf.dirent = dirent; |
18148 |
++ buf.file = file; |
18149 |
+ |
18150 |
+ error = vfs_readdir(file, fillonedir, &buf); |
18151 |
+ if (error >= 0) |
18152 |
+@@ -136,6 +144,7 @@ struct linux_dirent { |
18153 |
+ struct getdents_callback { |
18154 |
+ struct linux_dirent __user * current_dir; |
18155 |
+ struct linux_dirent __user * previous; |
18156 |
++ struct file * file; |
18157 |
+ int count; |
18158 |
+ int error; |
18159 |
+ }; |
18160 |
+@@ -154,6 +163,10 @@ static int filldir(void * __buf, const c |
18161 |
+ d_ino = ino; |
18162 |
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) |
18163 |
+ return -EOVERFLOW; |
18164 |
++ |
18165 |
++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino)) |
18166 |
++ return 0; |
18167 |
++ |
18168 |
+ dirent = buf->previous; |
18169 |
+ if (dirent) { |
18170 |
+ if (__put_user(offset, &dirent->d_off)) |
18171 |
+@@ -200,6 +213,7 @@ asmlinkage long sys_getdents(unsigned in |
18172 |
+ buf.previous = NULL; |
18173 |
+ buf.count = count; |
18174 |
+ buf.error = 0; |
18175 |
++ buf.file = file; |
18176 |
+ |
18177 |
+ error = vfs_readdir(file, filldir, &buf); |
18178 |
+ if (error < 0) |
18179 |
+@@ -222,6 +236,7 @@ out: |
18180 |
+ struct getdents_callback64 { |
18181 |
+ struct linux_dirent64 __user * current_dir; |
18182 |
+ struct linux_dirent64 __user * previous; |
18183 |
++ struct file *file; |
18184 |
+ int count; |
18185 |
+ int error; |
18186 |
+ }; |
18187 |
+@@ -236,6 +251,10 @@ static int filldir64(void * __buf, const |
18188 |
+ buf->error = -EINVAL; /* only used if we fail.. */ |
18189 |
+ if (reclen > buf->count) |
18190 |
+ return -EINVAL; |
18191 |
++ |
18192 |
++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino)) |
18193 |
++ return 0; |
18194 |
++ |
18195 |
+ dirent = buf->previous; |
18196 |
+ if (dirent) { |
18197 |
+ if (__put_user(offset, &dirent->d_off)) |
18198 |
+@@ -282,6 +301,7 @@ asmlinkage long sys_getdents64(unsigned |
18199 |
+ |
18200 |
+ buf.current_dir = dirent; |
18201 |
+ buf.previous = NULL; |
18202 |
++ buf.file = file; |
18203 |
+ buf.count = count; |
18204 |
+ buf.error = 0; |
18205 |
+ |
18206 |
+diff -urNp linux-2.6.24.4/fs/smbfs/symlink.c linux-2.6.24.4/fs/smbfs/symlink.c |
18207 |
+--- linux-2.6.24.4/fs/smbfs/symlink.c 2008-03-24 14:49:18.000000000 -0400 |
18208 |
++++ linux-2.6.24.4/fs/smbfs/symlink.c 2008-03-26 17:56:56.000000000 -0400 |
18209 |
+@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent |
18210 |
+ |
18211 |
+ static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p) |
18212 |
+ { |
18213 |
+- char *s = nd_get_link(nd); |
18214 |
++ const char *s = nd_get_link(nd); |
18215 |
+ if (!IS_ERR(s)) |
18216 |
+ __putname(s); |
18217 |
+ } |
18218 |
+diff -urNp linux-2.6.24.4/fs/sysfs/symlink.c linux-2.6.24.4/fs/sysfs/symlink.c |
18219 |
+--- linux-2.6.24.4/fs/sysfs/symlink.c 2008-03-24 14:49:18.000000000 -0400 |
18220 |
++++ linux-2.6.24.4/fs/sysfs/symlink.c 2008-03-26 17:56:56.000000000 -0400 |
18221 |
+@@ -172,7 +172,7 @@ static void *sysfs_follow_link(struct de |
18222 |
+ |
18223 |
+ static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) |
18224 |
+ { |
18225 |
+- char *page = nd_get_link(nd); |
18226 |
++ const char *page = nd_get_link(nd); |
18227 |
+ if (!IS_ERR(page)) |
18228 |
+ free_page((unsigned long)page); |
18229 |
+ } |
18230 |
+diff -urNp linux-2.6.24.4/fs/udf/balloc.c linux-2.6.24.4/fs/udf/balloc.c |
18231 |
+--- linux-2.6.24.4/fs/udf/balloc.c 2008-03-24 14:49:18.000000000 -0400 |
18232 |
++++ linux-2.6.24.4/fs/udf/balloc.c 2008-03-26 17:56:56.000000000 -0400 |
18233 |
+@@ -154,8 +154,7 @@ static void udf_bitmap_free_blocks(struc |
18234 |
+ unsigned long overflow; |
18235 |
+ |
18236 |
+ mutex_lock(&sbi->s_alloc_mutex); |
18237 |
+- if (bloc.logicalBlockNum < 0 || |
18238 |
+- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) { |
18239 |
++ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) { |
18240 |
+ udf_debug("%d < %d || %d + %d > %d\n", |
18241 |
+ bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, |
18242 |
+ UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)); |
18243 |
+@@ -221,7 +220,7 @@ static int udf_bitmap_prealloc_blocks(st |
18244 |
+ struct buffer_head *bh; |
18245 |
+ |
18246 |
+ mutex_lock(&sbi->s_alloc_mutex); |
18247 |
+- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition)) |
18248 |
++ if (first_block >= UDF_SB_PARTLEN(sb, partition)) |
18249 |
+ goto out; |
18250 |
+ |
18251 |
+ if (first_block + block_count > UDF_SB_PARTLEN(sb, partition)) |
18252 |
+@@ -287,7 +286,7 @@ static int udf_bitmap_new_block(struct s |
18253 |
+ mutex_lock(&sbi->s_alloc_mutex); |
18254 |
+ |
18255 |
+ repeat: |
18256 |
+- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition)) |
18257 |
++ if (goal >= UDF_SB_PARTLEN(sb, partition)) |
18258 |
+ goal = 0; |
18259 |
+ |
18260 |
+ nr_groups = bitmap->s_nr_groups; |
18261 |
+@@ -420,8 +419,7 @@ static void udf_table_free_blocks(struct |
18262 |
+ int i; |
18263 |
+ |
18264 |
+ mutex_lock(&sbi->s_alloc_mutex); |
18265 |
+- if (bloc.logicalBlockNum < 0 || |
18266 |
+- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) { |
18267 |
++ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) { |
18268 |
+ udf_debug("%d < %d || %d + %d > %d\n", |
18269 |
+ bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, |
18270 |
+ UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)); |
18271 |
+@@ -627,7 +625,7 @@ static int udf_table_prealloc_blocks(str |
18272 |
+ struct extent_position epos; |
18273 |
+ int8_t etype = -1; |
18274 |
+ |
18275 |
+- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition)) |
18276 |
++ if (first_block >= UDF_SB_PARTLEN(sb, partition)) |
18277 |
+ return 0; |
18278 |
+ |
18279 |
+ if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT) |
18280 |
+@@ -703,7 +701,7 @@ static int udf_table_new_block(struct su |
18281 |
+ return newblock; |
18282 |
+ |
18283 |
+ mutex_lock(&sbi->s_alloc_mutex); |
18284 |
+- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition)) |
18285 |
++ if (goal >= UDF_SB_PARTLEN(sb, partition)) |
18286 |
+ goal = 0; |
18287 |
+ |
18288 |
+ /* We search for the closest matching block to goal. If we find a exact hit, |
18289 |
+diff -urNp linux-2.6.24.4/fs/udf/inode.c linux-2.6.24.4/fs/udf/inode.c |
18290 |
+--- linux-2.6.24.4/fs/udf/inode.c 2008-03-24 14:49:18.000000000 -0400 |
18291 |
++++ linux-2.6.24.4/fs/udf/inode.c 2008-03-26 17:56:56.000000000 -0400 |
18292 |
+@@ -311,9 +311,6 @@ static int udf_get_block(struct inode *i |
18293 |
+ |
18294 |
+ lock_kernel(); |
18295 |
+ |
18296 |
+- if (block < 0) |
18297 |
+- goto abort_negative; |
18298 |
+- |
18299 |
+ if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) { |
18300 |
+ UDF_I_NEXT_ALLOC_BLOCK(inode)++; |
18301 |
+ UDF_I_NEXT_ALLOC_GOAL(inode)++; |
18302 |
+@@ -334,10 +331,6 @@ static int udf_get_block(struct inode *i |
18303 |
+ abort: |
18304 |
+ unlock_kernel(); |
18305 |
+ return err; |
18306 |
+- |
18307 |
+-abort_negative: |
18308 |
+- udf_warning(inode->i_sb, "udf_get_block", "block < 0"); |
18309 |
+- goto abort; |
18310 |
+ } |
18311 |
+ |
18312 |
+ static struct buffer_head *udf_getblk(struct inode *inode, long block, |
18313 |
+diff -urNp linux-2.6.24.4/fs/ufs/inode.c linux-2.6.24.4/fs/ufs/inode.c |
18314 |
+--- linux-2.6.24.4/fs/ufs/inode.c 2008-03-24 14:49:18.000000000 -0400 |
18315 |
++++ linux-2.6.24.4/fs/ufs/inode.c 2008-03-26 17:56:56.000000000 -0400 |
18316 |
+@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod |
18317 |
+ |
18318 |
+ |
18319 |
+ UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks); |
18320 |
+- if (i_block < 0) { |
18321 |
+- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0"); |
18322 |
+- } else if (i_block < direct_blocks) { |
18323 |
++ if (i_block < direct_blocks) { |
18324 |
+ offsets[n++] = i_block; |
18325 |
+ } else if ((i_block -= direct_blocks) < indirect_blocks) { |
18326 |
+ offsets[n++] = UFS_IND_BLOCK; |
18327 |
+@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod |
18328 |
+ lock_kernel(); |
18329 |
+ |
18330 |
+ UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment); |
18331 |
+- if (fragment < 0) |
18332 |
+- goto abort_negative; |
18333 |
+ if (fragment > |
18334 |
+ ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb) |
18335 |
+ << uspi->s_fpbshift)) |
18336 |
+@@ -504,10 +500,6 @@ abort: |
18337 |
+ unlock_kernel(); |
18338 |
+ return err; |
18339 |
+ |
18340 |
+-abort_negative: |
18341 |
+- ufs_warning(sb, "ufs_get_block", "block < 0"); |
18342 |
+- goto abort; |
18343 |
+- |
18344 |
+ abort_too_big: |
18345 |
+ ufs_warning(sb, "ufs_get_block", "block > big"); |
18346 |
+ goto abort; |
18347 |
+diff -urNp linux-2.6.24.4/fs/utimes.c linux-2.6.24.4/fs/utimes.c |
18348 |
+--- linux-2.6.24.4/fs/utimes.c 2008-03-24 14:49:18.000000000 -0400 |
18349 |
++++ linux-2.6.24.4/fs/utimes.c 2008-03-26 17:56:56.000000000 -0400 |
18350 |
+@@ -6,6 +6,7 @@ |
18351 |
+ #include <linux/sched.h> |
18352 |
+ #include <linux/stat.h> |
18353 |
+ #include <linux/utime.h> |
18354 |
++#include <linux/grsecurity.h> |
18355 |
+ #include <asm/uaccess.h> |
18356 |
+ #include <asm/unistd.h> |
18357 |
+ |
18358 |
+@@ -55,6 +56,7 @@ long do_utimes(int dfd, char __user *fil |
18359 |
+ int error; |
18360 |
+ struct nameidata nd; |
18361 |
+ struct dentry *dentry; |
18362 |
++ struct vfsmount *mnt; |
18363 |
+ struct inode *inode; |
18364 |
+ struct iattr newattrs; |
18365 |
+ struct file *f = NULL; |
18366 |
+@@ -78,12 +80,14 @@ long do_utimes(int dfd, char __user *fil |
18367 |
+ if (!f) |
18368 |
+ goto out; |
18369 |
+ dentry = f->f_path.dentry; |
18370 |
++ mnt = f->f_path.mnt; |
18371 |
+ } else { |
18372 |
+ error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd); |
18373 |
+ if (error) |
18374 |
+ goto out; |
18375 |
+ |
18376 |
+ dentry = nd.dentry; |
18377 |
++ mnt = nd.mnt; |
18378 |
+ } |
18379 |
+ |
18380 |
+ inode = dentry->d_inode; |
18381 |
+@@ -130,6 +134,12 @@ long do_utimes(int dfd, char __user *fil |
18382 |
+ } |
18383 |
+ } |
18384 |
+ } |
18385 |
++ |
18386 |
++ if (!gr_acl_handle_utime(dentry, mnt)) { |
18387 |
++ error = -EACCES; |
18388 |
++ goto dput_and_out; |
18389 |
++ } |
18390 |
++ |
18391 |
+ mutex_lock(&inode->i_mutex); |
18392 |
+ error = notify_change(dentry, &newattrs); |
18393 |
+ mutex_unlock(&inode->i_mutex); |
18394 |
+diff -urNp linux-2.6.24.4/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.24.4/fs/xfs/linux-2.6/xfs_iops.c |
18395 |
+--- linux-2.6.24.4/fs/xfs/linux-2.6/xfs_iops.c 2008-03-24 14:49:18.000000000 -0400 |
18396 |
++++ linux-2.6.24.4/fs/xfs/linux-2.6/xfs_iops.c 2008-03-26 17:56:56.000000000 -0400 |
18397 |
+@@ -534,7 +534,7 @@ xfs_vn_put_link( |
18398 |
+ struct nameidata *nd, |
18399 |
+ void *p) |
18400 |
+ { |
18401 |
+- char *s = nd_get_link(nd); |
18402 |
++ const char *s = nd_get_link(nd); |
18403 |
+ |
18404 |
+ if (!IS_ERR(s)) |
18405 |
+ kfree(s); |
18406 |
+diff -urNp linux-2.6.24.4/fs/xfs/xfs_bmap.c linux-2.6.24.4/fs/xfs/xfs_bmap.c |
18407 |
+--- linux-2.6.24.4/fs/xfs/xfs_bmap.c 2008-03-24 14:49:18.000000000 -0400 |
18408 |
++++ linux-2.6.24.4/fs/xfs/xfs_bmap.c 2008-03-26 17:56:56.000000000 -0400 |
18409 |
+@@ -360,7 +360,7 @@ xfs_bmap_validate_ret( |
18410 |
+ int nmap, |
18411 |
+ int ret_nmap); |
18412 |
+ #else |
18413 |
+-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) |
18414 |
++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0) |
18415 |
+ #endif /* DEBUG */ |
18416 |
+ |
18417 |
+ #if defined(XFS_RW_TRACE) |
18418 |
+diff -urNp linux-2.6.24.4/grsecurity/gracl_alloc.c linux-2.6.24.4/grsecurity/gracl_alloc.c |
18419 |
+--- linux-2.6.24.4/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500 |
18420 |
++++ linux-2.6.24.4/grsecurity/gracl_alloc.c 2008-03-26 17:56:56.000000000 -0400 |
18421 |
+@@ -0,0 +1,91 @@ |
18422 |
++#include <linux/kernel.h> |
18423 |
++#include <linux/mm.h> |
18424 |
++#include <linux/slab.h> |
18425 |
++#include <linux/vmalloc.h> |
18426 |
++#include <linux/gracl.h> |
18427 |
++#include <linux/grsecurity.h> |
18428 |
++ |
18429 |
++static unsigned long alloc_stack_next = 1; |
18430 |
++static unsigned long alloc_stack_size = 1; |
18431 |
++static void **alloc_stack; |
18432 |
++ |
18433 |
++static __inline__ int |
18434 |
++alloc_pop(void) |
18435 |
++{ |
18436 |
++ if (alloc_stack_next == 1) |
18437 |
++ return 0; |
18438 |
++ |
18439 |
++ kfree(alloc_stack[alloc_stack_next - 2]); |
18440 |
++ |
18441 |
++ alloc_stack_next--; |
18442 |
++ |
18443 |
++ return 1; |
18444 |
++} |
18445 |
++ |
18446 |
++static __inline__ void |
18447 |
++alloc_push(void *buf) |
18448 |
++{ |
18449 |
++ if (alloc_stack_next >= alloc_stack_size) |
18450 |
++ BUG(); |
18451 |
++ |
18452 |
++ alloc_stack[alloc_stack_next - 1] = buf; |
18453 |
++ |
18454 |
++ alloc_stack_next++; |
18455 |
++ |
18456 |
++ return; |
18457 |
++} |
18458 |
++ |
18459 |
++void * |
18460 |
++acl_alloc(unsigned long len) |
18461 |
++{ |
18462 |
++ void *ret; |
18463 |
++ |
18464 |
++ if (len > PAGE_SIZE) |
18465 |
++ BUG(); |
18466 |
++ |
18467 |
++ ret = kmalloc(len, GFP_KERNEL); |
18468 |
++ |
18469 |
++ if (ret) |
18470 |
++ alloc_push(ret); |
18471 |
++ |
18472 |
++ return ret; |
18473 |
++} |
18474 |
++ |
18475 |
++void |
18476 |
++acl_free_all(void) |
18477 |
++{ |
18478 |
++ if (gr_acl_is_enabled() || !alloc_stack) |
18479 |
++ return; |
18480 |
++ |
18481 |
++ while (alloc_pop()) ; |
18482 |
++ |
18483 |
++ if (alloc_stack) { |
18484 |
++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE) |
18485 |
++ kfree(alloc_stack); |
18486 |
++ else |
18487 |
++ vfree(alloc_stack); |
18488 |
++ } |
18489 |
++ |
18490 |
++ alloc_stack = NULL; |
18491 |
++ alloc_stack_size = 1; |
18492 |
++ alloc_stack_next = 1; |
18493 |
++ |
18494 |
++ return; |
18495 |
++} |
18496 |
++ |
18497 |
++int |
18498 |
++acl_alloc_stack_init(unsigned long size) |
18499 |
++{ |
18500 |
++ if ((size * sizeof (void *)) <= PAGE_SIZE) |
18501 |
++ alloc_stack = |
18502 |
++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL); |
18503 |
++ else |
18504 |
++ alloc_stack = (void **) vmalloc(size * sizeof (void *)); |
18505 |
++ |
18506 |
++ alloc_stack_size = size; |
18507 |
++ |
18508 |
++ if (!alloc_stack) |
18509 |
++ return 0; |
18510 |
++ else |
18511 |
++ return 1; |
18512 |
++} |
18513 |
+diff -urNp linux-2.6.24.4/grsecurity/gracl.c linux-2.6.24.4/grsecurity/gracl.c |
18514 |
+--- linux-2.6.24.4/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500 |
18515 |
++++ linux-2.6.24.4/grsecurity/gracl.c 2008-03-26 17:56:56.000000000 -0400 |
18516 |
+@@ -0,0 +1,3722 @@ |
18517 |
++#include <linux/kernel.h> |
18518 |
++#include <linux/module.h> |
18519 |
++#include <linux/sched.h> |
18520 |
++#include <linux/mm.h> |
18521 |
++#include <linux/file.h> |
18522 |
++#include <linux/fs.h> |
18523 |
++#include <linux/namei.h> |
18524 |
++#include <linux/mount.h> |
18525 |
++#include <linux/tty.h> |
18526 |
++#include <linux/proc_fs.h> |
18527 |
++#include <linux/smp_lock.h> |
18528 |
++#include <linux/slab.h> |
18529 |
++#include <linux/vmalloc.h> |
18530 |
++#include <linux/types.h> |
18531 |
++#include <linux/capability.h> |
18532 |
++#include <linux/sysctl.h> |
18533 |
++#include <linux/netdevice.h> |
18534 |
++#include <linux/ptrace.h> |
18535 |
++#include <linux/gracl.h> |
18536 |
++#include <linux/gralloc.h> |
18537 |
++#include <linux/grsecurity.h> |
18538 |
++#include <linux/grinternal.h> |
18539 |
++#include <linux/pid_namespace.h> |
18540 |
++#include <linux/percpu.h> |
18541 |
++ |
18542 |
++#include <asm/uaccess.h> |
18543 |
++#include <asm/errno.h> |
18544 |
++#include <asm/mman.h> |
18545 |
++ |
18546 |
++static struct acl_role_db acl_role_set; |
18547 |
++static struct name_db name_set; |
18548 |
++static struct inodev_db inodev_set; |
18549 |
++ |
18550 |
++/* for keeping track of userspace pointers used for subjects, so we |
18551 |
++ can share references in the kernel as well |
18552 |
++*/ |
18553 |
++ |
18554 |
++static struct dentry *real_root; |
18555 |
++static struct vfsmount *real_root_mnt; |
18556 |
++ |
18557 |
++static struct acl_subj_map_db subj_map_set; |
18558 |
++ |
18559 |
++static struct acl_role_label *default_role; |
18560 |
++ |
18561 |
++static u16 acl_sp_role_value; |
18562 |
++ |
18563 |
++extern char *gr_shared_page[4]; |
18564 |
++static DECLARE_MUTEX(gr_dev_sem); |
18565 |
++rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED; |
18566 |
++ |
18567 |
++struct gr_arg *gr_usermode; |
18568 |
++ |
18569 |
++static unsigned int gr_status = GR_STATUS_INIT; |
18570 |
++ |
18571 |
++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum); |
18572 |
++extern void gr_clear_learn_entries(void); |
18573 |
++ |
18574 |
++#ifdef CONFIG_GRKERNSEC_RESLOG |
18575 |
++extern void gr_log_resource(const struct task_struct *task, |
18576 |
++ const int res, const unsigned long wanted, const int gt); |
18577 |
++#endif |
18578 |
++ |
18579 |
++unsigned char *gr_system_salt; |
18580 |
++unsigned char *gr_system_sum; |
18581 |
++ |
18582 |
++static struct sprole_pw **acl_special_roles = NULL; |
18583 |
++static __u16 num_sprole_pws = 0; |
18584 |
++ |
18585 |
++static struct acl_role_label *kernel_role = NULL; |
18586 |
++ |
18587 |
++static unsigned int gr_auth_attempts = 0; |
18588 |
++static unsigned long gr_auth_expires = 0UL; |
18589 |
++ |
18590 |
++extern struct vfsmount *sock_mnt; |
18591 |
++extern struct vfsmount *pipe_mnt; |
18592 |
++extern struct vfsmount *shm_mnt; |
18593 |
++static struct acl_object_label *fakefs_obj; |
18594 |
++ |
18595 |
++extern int gr_init_uidset(void); |
18596 |
++extern void gr_free_uidset(void); |
18597 |
++extern void gr_remove_uid(uid_t uid); |
18598 |
++extern int gr_find_uid(uid_t uid); |
18599 |
++ |
18600 |
++__inline__ int |
18601 |
++gr_acl_is_enabled(void) |
18602 |
++{ |
18603 |
++ return (gr_status & GR_READY); |
18604 |
++} |
18605 |
++ |
18606 |
++char gr_roletype_to_char(void) |
18607 |
++{ |
18608 |
++ switch (current->role->roletype & |
18609 |
++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP | |
18610 |
++ GR_ROLE_SPECIAL)) { |
18611 |
++ case GR_ROLE_DEFAULT: |
18612 |
++ return 'D'; |
18613 |
++ case GR_ROLE_USER: |
18614 |
++ return 'U'; |
18615 |
++ case GR_ROLE_GROUP: |
18616 |
++ return 'G'; |
18617 |
++ case GR_ROLE_SPECIAL: |
18618 |
++ return 'S'; |
18619 |
++ } |
18620 |
++ |
18621 |
++ return 'X'; |
18622 |
++} |
18623 |
++ |
18624 |
++__inline__ int |
18625 |
++gr_acl_tpe_check(void) |
18626 |
++{ |
18627 |
++ if (unlikely(!(gr_status & GR_READY))) |
18628 |
++ return 0; |
18629 |
++ if (current->role->roletype & GR_ROLE_TPE) |
18630 |
++ return 1; |
18631 |
++ else |
18632 |
++ return 0; |
18633 |
++} |
18634 |
++ |
18635 |
++int |
18636 |
++gr_handle_rawio(const struct inode *inode) |
18637 |
++{ |
18638 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS |
18639 |
++ if (inode && S_ISBLK(inode->i_mode) && |
18640 |
++ grsec_enable_chroot_caps && proc_is_chrooted(current) && |
18641 |
++ !capable(CAP_SYS_RAWIO)) |
18642 |
++ return 1; |
18643 |
++#endif |
18644 |
++ return 0; |
18645 |
++} |
18646 |
++ |
18647 |
++static int |
18648 |
++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb) |
18649 |
++{ |
18650 |
++ int i; |
18651 |
++ unsigned long *l1; |
18652 |
++ unsigned long *l2; |
18653 |
++ unsigned char *c1; |
18654 |
++ unsigned char *c2; |
18655 |
++ int num_longs; |
18656 |
++ |
18657 |
++ if (likely(lena != lenb)) |
18658 |
++ return 0; |
18659 |
++ |
18660 |
++ l1 = (unsigned long *)a; |
18661 |
++ l2 = (unsigned long *)b; |
18662 |
++ |
18663 |
++ num_longs = lena / sizeof(unsigned long); |
18664 |
++ |
18665 |
++ for (i = num_longs; i--; l1++, l2++) { |
18666 |
++ if (unlikely(*l1 != *l2)) |
18667 |
++ return 0; |
18668 |
++ } |
18669 |
++ |
18670 |
++ c1 = (unsigned char *) l1; |
18671 |
++ c2 = (unsigned char *) l2; |
18672 |
++ |
18673 |
++ i = lena - (num_longs * sizeof(unsigned long)); |
18674 |
++ |
18675 |
++ for (; i--; c1++, c2++) { |
18676 |
++ if (unlikely(*c1 != *c2)) |
18677 |
++ return 0; |
18678 |
++ } |
18679 |
++ |
18680 |
++ return 1; |
18681 |
++} |
18682 |
++ |
18683 |
++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt, |
18684 |
++ struct dentry *root, struct vfsmount *rootmnt, |
18685 |
++ char *buffer, int buflen) |
18686 |
++{ |
18687 |
++ char * end = buffer+buflen; |
18688 |
++ char * retval; |
18689 |
++ int namelen; |
18690 |
++ |
18691 |
++ *--end = '\0'; |
18692 |
++ buflen--; |
18693 |
++ |
18694 |
++ if (buflen < 1) |
18695 |
++ goto Elong; |
18696 |
++ /* Get '/' right */ |
18697 |
++ retval = end-1; |
18698 |
++ *retval = '/'; |
18699 |
++ |
18700 |
++ for (;;) { |
18701 |
++ struct dentry * parent; |
18702 |
++ |
18703 |
++ if (dentry == root && vfsmnt == rootmnt) |
18704 |
++ break; |
18705 |
++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { |
18706 |
++ /* Global root? */ |
18707 |
++ spin_lock(&vfsmount_lock); |
18708 |
++ if (vfsmnt->mnt_parent == vfsmnt) { |
18709 |
++ spin_unlock(&vfsmount_lock); |
18710 |
++ goto global_root; |
18711 |
++ } |
18712 |
++ dentry = vfsmnt->mnt_mountpoint; |
18713 |
++ vfsmnt = vfsmnt->mnt_parent; |
18714 |
++ spin_unlock(&vfsmount_lock); |
18715 |
++ continue; |
18716 |
++ } |
18717 |
++ parent = dentry->d_parent; |
18718 |
++ prefetch(parent); |
18719 |
++ namelen = dentry->d_name.len; |
18720 |
++ buflen -= namelen + 1; |
18721 |
++ if (buflen < 0) |
18722 |
++ goto Elong; |
18723 |
++ end -= namelen; |
18724 |
++ memcpy(end, dentry->d_name.name, namelen); |
18725 |
++ *--end = '/'; |
18726 |
++ retval = end; |
18727 |
++ dentry = parent; |
18728 |
++ } |
18729 |
++ |
18730 |
++ return retval; |
18731 |
++ |
18732 |
++global_root: |
18733 |
++ namelen = dentry->d_name.len; |
18734 |
++ buflen -= namelen; |
18735 |
++ if (buflen < 0) |
18736 |
++ goto Elong; |
18737 |
++ retval -= namelen-1; /* hit the slash */ |
18738 |
++ memcpy(retval, dentry->d_name.name, namelen); |
18739 |
++ return retval; |
18740 |
++Elong: |
18741 |
++ return ERR_PTR(-ENAMETOOLONG); |
18742 |
++} |
18743 |
++ |
18744 |
++static char * |
18745 |
++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt, |
18746 |
++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen) |
18747 |
++{ |
18748 |
++ char *retval; |
18749 |
++ |
18750 |
++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen); |
18751 |
++ if (unlikely(IS_ERR(retval))) |
18752 |
++ retval = strcpy(buf, "<path too long>"); |
18753 |
++ else if (unlikely(retval[1] == '/' && retval[2] == '\0')) |
18754 |
++ retval[1] = '\0'; |
18755 |
++ |
18756 |
++ return retval; |
18757 |
++} |
18758 |
++ |
18759 |
++static char * |
18760 |
++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt, |
18761 |
++ char *buf, int buflen) |
18762 |
++{ |
18763 |
++ char *res; |
18764 |
++ |
18765 |
++ /* we can use real_root, real_root_mnt, because this is only called |
18766 |
++ by the RBAC system */ |
18767 |
++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen); |
18768 |
++ |
18769 |
++ return res; |
18770 |
++} |
18771 |
++ |
18772 |
++static char * |
18773 |
++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt, |
18774 |
++ char *buf, int buflen) |
18775 |
++{ |
18776 |
++ char *res; |
18777 |
++ struct dentry *root; |
18778 |
++ struct vfsmount *rootmnt; |
18779 |
++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper; |
18780 |
++ |
18781 |
++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */ |
18782 |
++ read_lock(&reaper->fs->lock); |
18783 |
++ root = dget(reaper->fs->root); |
18784 |
++ rootmnt = mntget(reaper->fs->rootmnt); |
18785 |
++ read_unlock(&reaper->fs->lock); |
18786 |
++ |
18787 |
++ spin_lock(&dcache_lock); |
18788 |
++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen); |
18789 |
++ spin_unlock(&dcache_lock); |
18790 |
++ |
18791 |
++ dput(root); |
18792 |
++ mntput(rootmnt); |
18793 |
++ return res; |
18794 |
++} |
18795 |
++ |
18796 |
++static char * |
18797 |
++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt) |
18798 |
++{ |
18799 |
++ char *ret; |
18800 |
++ spin_lock(&dcache_lock); |
18801 |
++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()), |
18802 |
++ PAGE_SIZE); |
18803 |
++ spin_unlock(&dcache_lock); |
18804 |
++ return ret; |
18805 |
++} |
18806 |
++ |
18807 |
++char * |
18808 |
++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt) |
18809 |
++{ |
18810 |
++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()), |
18811 |
++ PAGE_SIZE); |
18812 |
++} |
18813 |
++ |
18814 |
++char * |
18815 |
++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt) |
18816 |
++{ |
18817 |
++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()), |
18818 |
++ PAGE_SIZE); |
18819 |
++} |
18820 |
++ |
18821 |
++char * |
18822 |
++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt) |
18823 |
++{ |
18824 |
++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()), |
18825 |
++ PAGE_SIZE); |
18826 |
++} |
18827 |
++ |
18828 |
++char * |
18829 |
++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt) |
18830 |
++{ |
18831 |
++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()), |
18832 |
++ PAGE_SIZE); |
18833 |
++} |
18834 |
++ |
18835 |
++char * |
18836 |
++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt) |
18837 |
++{ |
18838 |
++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()), |
18839 |
++ PAGE_SIZE); |
18840 |
++} |
18841 |
++ |
18842 |
++__inline__ __u32 |
18843 |
++to_gr_audit(const __u32 reqmode) |
18844 |
++{ |
18845 |
++ /* masks off auditable permission flags, then shifts them to create |
18846 |
++ auditing flags, and adds the special case of append auditing if |
18847 |
++ we're requesting write */ |
18848 |
++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0)); |
18849 |
++} |
18850 |
++ |
18851 |
++struct acl_subject_label * |
18852 |
++lookup_subject_map(const struct acl_subject_label *userp) |
18853 |
++{ |
18854 |
++ unsigned int index = shash(userp, subj_map_set.s_size); |
18855 |
++ struct subject_map *match; |
18856 |
++ |
18857 |
++ match = subj_map_set.s_hash[index]; |
18858 |
++ |
18859 |
++ while (match && match->user != userp) |
18860 |
++ match = match->next; |
18861 |
++ |
18862 |
++ if (match != NULL) |
18863 |
++ return match->kernel; |
18864 |
++ else |
18865 |
++ return NULL; |
18866 |
++} |
18867 |
++ |
18868 |
++static void |
18869 |
++insert_subj_map_entry(struct subject_map *subjmap) |
18870 |
++{ |
18871 |
++ unsigned int index = shash(subjmap->user, subj_map_set.s_size); |
18872 |
++ struct subject_map **curr; |
18873 |
++ |
18874 |
++ subjmap->prev = NULL; |
18875 |
++ |
18876 |
++ curr = &subj_map_set.s_hash[index]; |
18877 |
++ if (*curr != NULL) |
18878 |
++ (*curr)->prev = subjmap; |
18879 |
++ |
18880 |
++ subjmap->next = *curr; |
18881 |
++ *curr = subjmap; |
18882 |
++ |
18883 |
++ return; |
18884 |
++} |
18885 |
++ |
18886 |
++static struct acl_role_label * |
18887 |
++lookup_acl_role_label(const struct task_struct *task, const uid_t uid, |
18888 |
++ const gid_t gid) |
18889 |
++{ |
18890 |
++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size); |
18891 |
++ struct acl_role_label *match; |
18892 |
++ struct role_allowed_ip *ipp; |
18893 |
++ unsigned int x; |
18894 |
++ |
18895 |
++ match = acl_role_set.r_hash[index]; |
18896 |
++ |
18897 |
++ while (match) { |
18898 |
++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) { |
18899 |
++ for (x = 0; x < match->domain_child_num; x++) { |
18900 |
++ if (match->domain_children[x] == uid) |
18901 |
++ goto found; |
18902 |
++ } |
18903 |
++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER) |
18904 |
++ break; |
18905 |
++ match = match->next; |
18906 |
++ } |
18907 |
++found: |
18908 |
++ if (match == NULL) { |
18909 |
++ try_group: |
18910 |
++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size); |
18911 |
++ match = acl_role_set.r_hash[index]; |
18912 |
++ |
18913 |
++ while (match) { |
18914 |
++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) { |
18915 |
++ for (x = 0; x < match->domain_child_num; x++) { |
18916 |
++ if (match->domain_children[x] == gid) |
18917 |
++ goto found2; |
18918 |
++ } |
18919 |
++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP) |
18920 |
++ break; |
18921 |
++ match = match->next; |
18922 |
++ } |
18923 |
++found2: |
18924 |
++ if (match == NULL) |
18925 |
++ match = default_role; |
18926 |
++ if (match->allowed_ips == NULL) |
18927 |
++ return match; |
18928 |
++ else { |
18929 |
++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) { |
18930 |
++ if (likely |
18931 |
++ ((ntohl(task->signal->curr_ip) & ipp->netmask) == |
18932 |
++ (ntohl(ipp->addr) & ipp->netmask))) |
18933 |
++ return match; |
18934 |
++ } |
18935 |
++ match = default_role; |
18936 |
++ } |
18937 |
++ } else if (match->allowed_ips == NULL) { |
18938 |
++ return match; |
18939 |
++ } else { |
18940 |
++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) { |
18941 |
++ if (likely |
18942 |
++ ((ntohl(task->signal->curr_ip) & ipp->netmask) == |
18943 |
++ (ntohl(ipp->addr) & ipp->netmask))) |
18944 |
++ return match; |
18945 |
++ } |
18946 |
++ goto try_group; |
18947 |
++ } |
18948 |
++ |
18949 |
++ return match; |
18950 |
++} |
18951 |
++ |
18952 |
++struct acl_subject_label * |
18953 |
++lookup_acl_subj_label(const ino_t ino, const dev_t dev, |
18954 |
++ const struct acl_role_label *role) |
18955 |
++{ |
18956 |
++ unsigned int index = fhash(ino, dev, role->subj_hash_size); |
18957 |
++ struct acl_subject_label *match; |
18958 |
++ |
18959 |
++ match = role->subj_hash[index]; |
18960 |
++ |
18961 |
++ while (match && (match->inode != ino || match->device != dev || |
18962 |
++ (match->mode & GR_DELETED))) { |
18963 |
++ match = match->next; |
18964 |
++ } |
18965 |
++ |
18966 |
++ if (match && !(match->mode & GR_DELETED)) |
18967 |
++ return match; |
18968 |
++ else |
18969 |
++ return NULL; |
18970 |
++} |
18971 |
++ |
18972 |
++static struct acl_object_label * |
18973 |
++lookup_acl_obj_label(const ino_t ino, const dev_t dev, |
18974 |
++ const struct acl_subject_label *subj) |
18975 |
++{ |
18976 |
++ unsigned int index = fhash(ino, dev, subj->obj_hash_size); |
18977 |
++ struct acl_object_label *match; |
18978 |
++ |
18979 |
++ match = subj->obj_hash[index]; |
18980 |
++ |
18981 |
++ while (match && (match->inode != ino || match->device != dev || |
18982 |
++ (match->mode & GR_DELETED))) { |
18983 |
++ match = match->next; |
18984 |
++ } |
18985 |
++ |
18986 |
++ if (match && !(match->mode & GR_DELETED)) |
18987 |
++ return match; |
18988 |
++ else |
18989 |
++ return NULL; |
18990 |
++} |
18991 |
++ |
18992 |
++static struct acl_object_label * |
18993 |
++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev, |
18994 |
++ const struct acl_subject_label *subj) |
18995 |
++{ |
18996 |
++ unsigned int index = fhash(ino, dev, subj->obj_hash_size); |
18997 |
++ struct acl_object_label *match; |
18998 |
++ |
18999 |
++ match = subj->obj_hash[index]; |
19000 |
++ |
19001 |
++ while (match && (match->inode != ino || match->device != dev || |
19002 |
++ !(match->mode & GR_DELETED))) { |
19003 |
++ match = match->next; |
19004 |
++ } |
19005 |
++ |
19006 |
++ if (match && (match->mode & GR_DELETED)) |
19007 |
++ return match; |
19008 |
++ |
19009 |
++ match = subj->obj_hash[index]; |
19010 |
++ |
19011 |
++ while (match && (match->inode != ino || match->device != dev || |
19012 |
++ (match->mode & GR_DELETED))) { |
19013 |
++ match = match->next; |
19014 |
++ } |
19015 |
++ |
19016 |
++ if (match && !(match->mode & GR_DELETED)) |
19017 |
++ return match; |
19018 |
++ else |
19019 |
++ return NULL; |
19020 |
++} |
19021 |
++ |
19022 |
++static struct name_entry * |
19023 |
++lookup_name_entry(const char *name) |
19024 |
++{ |
19025 |
++ unsigned int len = strlen(name); |
19026 |
++ unsigned int key = full_name_hash(name, len); |
19027 |
++ unsigned int index = key % name_set.n_size; |
19028 |
++ struct name_entry *match; |
19029 |
++ |
19030 |
++ match = name_set.n_hash[index]; |
19031 |
++ |
19032 |
++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len))) |
19033 |
++ match = match->next; |
19034 |
++ |
19035 |
++ return match; |
19036 |
++} |
19037 |
++ |
19038 |
++static struct name_entry * |
19039 |
++lookup_name_entry_create(const char *name) |
19040 |
++{ |
19041 |
++ unsigned int len = strlen(name); |
19042 |
++ unsigned int key = full_name_hash(name, len); |
19043 |
++ unsigned int index = key % name_set.n_size; |
19044 |
++ struct name_entry *match; |
19045 |
++ |
19046 |
++ match = name_set.n_hash[index]; |
19047 |
++ |
19048 |
++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) || |
19049 |
++ !match->deleted)) |
19050 |
++ match = match->next; |
19051 |
++ |
19052 |
++ if (match && match->deleted) |
19053 |
++ return match; |
19054 |
++ |
19055 |
++ match = name_set.n_hash[index]; |
19056 |
++ |
19057 |
++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) || |
19058 |
++ match->deleted)) |
19059 |
++ match = match->next; |
19060 |
++ |
19061 |
++ if (match && !match->deleted) |
19062 |
++ return match; |
19063 |
++ else |
19064 |
++ return NULL; |
19065 |
++} |
19066 |
++ |
19067 |
++static struct inodev_entry * |
19068 |
++lookup_inodev_entry(const ino_t ino, const dev_t dev) |
19069 |
++{ |
19070 |
++ unsigned int index = fhash(ino, dev, inodev_set.i_size); |
19071 |
++ struct inodev_entry *match; |
19072 |
++ |
19073 |
++ match = inodev_set.i_hash[index]; |
19074 |
++ |
19075 |
++ while (match && (match->nentry->inode != ino || match->nentry->device != dev)) |
19076 |
++ match = match->next; |
19077 |
++ |
19078 |
++ return match; |
19079 |
++} |
19080 |
++ |
19081 |
++static void |
19082 |
++insert_inodev_entry(struct inodev_entry *entry) |
19083 |
++{ |
19084 |
++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device, |
19085 |
++ inodev_set.i_size); |
19086 |
++ struct inodev_entry **curr; |
19087 |
++ |
19088 |
++ entry->prev = NULL; |
19089 |
++ |
19090 |
++ curr = &inodev_set.i_hash[index]; |
19091 |
++ if (*curr != NULL) |
19092 |
++ (*curr)->prev = entry; |
19093 |
++ |
19094 |
++ entry->next = *curr; |
19095 |
++ *curr = entry; |
19096 |
++ |
19097 |
++ return; |
19098 |
++} |
19099 |
++ |
19100 |
++static void |
19101 |
++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid) |
19102 |
++{ |
19103 |
++ unsigned int index = |
19104 |
++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size); |
19105 |
++ struct acl_role_label **curr; |
19106 |
++ |
19107 |
++ role->prev = NULL; |
19108 |
++ |
19109 |
++ curr = &acl_role_set.r_hash[index]; |
19110 |
++ if (*curr != NULL) |
19111 |
++ (*curr)->prev = role; |
19112 |
++ |
19113 |
++ role->next = *curr; |
19114 |
++ *curr = role; |
19115 |
++ |
19116 |
++ return; |
19117 |
++} |
19118 |
++ |
19119 |
++static void |
19120 |
++insert_acl_role_label(struct acl_role_label *role) |
19121 |
++{ |
19122 |
++ int i; |
19123 |
++ |
19124 |
++ if (role->roletype & GR_ROLE_DOMAIN) { |
19125 |
++ for (i = 0; i < role->domain_child_num; i++) |
19126 |
++ __insert_acl_role_label(role, role->domain_children[i]); |
19127 |
++ } else |
19128 |
++ __insert_acl_role_label(role, role->uidgid); |
19129 |
++} |
19130 |
++ |
19131 |
++static int |
19132 |
++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted) |
19133 |
++{ |
19134 |
++ struct name_entry **curr, *nentry; |
19135 |
++ struct inodev_entry *ientry; |
19136 |
++ unsigned int len = strlen(name); |
19137 |
++ unsigned int key = full_name_hash(name, len); |
19138 |
++ unsigned int index = key % name_set.n_size; |
19139 |
++ |
19140 |
++ curr = &name_set.n_hash[index]; |
19141 |
++ |
19142 |
++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len))) |
19143 |
++ curr = &((*curr)->next); |
19144 |
++ |
19145 |
++ if (*curr != NULL) |
19146 |
++ return 1; |
19147 |
++ |
19148 |
++ nentry = acl_alloc(sizeof (struct name_entry)); |
19149 |
++ if (nentry == NULL) |
19150 |
++ return 0; |
19151 |
++ ientry = acl_alloc(sizeof (struct inodev_entry)); |
19152 |
++ if (ientry == NULL) |
19153 |
++ return 0; |
19154 |
++ ientry->nentry = nentry; |
19155 |
++ |
19156 |
++ nentry->key = key; |
19157 |
++ nentry->name = name; |
19158 |
++ nentry->inode = inode; |
19159 |
++ nentry->device = device; |
19160 |
++ nentry->len = len; |
19161 |
++ nentry->deleted = deleted; |
19162 |
++ |
19163 |
++ nentry->prev = NULL; |
19164 |
++ curr = &name_set.n_hash[index]; |
19165 |
++ if (*curr != NULL) |
19166 |
++ (*curr)->prev = nentry; |
19167 |
++ nentry->next = *curr; |
19168 |
++ *curr = nentry; |
19169 |
++ |
19170 |
++ /* insert us into the table searchable by inode/dev */ |
19171 |
++ insert_inodev_entry(ientry); |
19172 |
++ |
19173 |
++ return 1; |
19174 |
++} |
19175 |
++ |
19176 |
++static void |
19177 |
++insert_acl_obj_label(struct acl_object_label *obj, |
19178 |
++ struct acl_subject_label *subj) |
19179 |
++{ |
19180 |
++ unsigned int index = |
19181 |
++ fhash(obj->inode, obj->device, subj->obj_hash_size); |
19182 |
++ struct acl_object_label **curr; |
19183 |
++ |
19184 |
++ |
19185 |
++ obj->prev = NULL; |
19186 |
++ |
19187 |
++ curr = &subj->obj_hash[index]; |
19188 |
++ if (*curr != NULL) |
19189 |
++ (*curr)->prev = obj; |
19190 |
++ |
19191 |
++ obj->next = *curr; |
19192 |
++ *curr = obj; |
19193 |
++ |
19194 |
++ return; |
19195 |
++} |
19196 |
++ |
19197 |
++static void |
19198 |
++insert_acl_subj_label(struct acl_subject_label *obj, |
19199 |
++ struct acl_role_label *role) |
19200 |
++{ |
19201 |
++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size); |
19202 |
++ struct acl_subject_label **curr; |
19203 |
++ |
19204 |
++ obj->prev = NULL; |
19205 |
++ |
19206 |
++ curr = &role->subj_hash[index]; |
19207 |
++ if (*curr != NULL) |
19208 |
++ (*curr)->prev = obj; |
19209 |
++ |
19210 |
++ obj->next = *curr; |
19211 |
++ *curr = obj; |
19212 |
++ |
19213 |
++ return; |
19214 |
++} |
19215 |
++ |
19216 |
++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */ |
19217 |
++ |
19218 |
++static void * |
19219 |
++create_table(__u32 * len, int elementsize) |
19220 |
++{ |
19221 |
++ unsigned int table_sizes[] = { |
19222 |
++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, |
19223 |
++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143, |
19224 |
++ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689, |
19225 |
++ 268435399, 536870909, 1073741789, 2147483647 |
19226 |
++ }; |
19227 |
++ void *newtable = NULL; |
19228 |
++ unsigned int pwr = 0; |
19229 |
++ |
19230 |
++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) && |
19231 |
++ table_sizes[pwr] <= *len) |
19232 |
++ pwr++; |
19233 |
++ |
19234 |
++ if (table_sizes[pwr] <= *len) |
19235 |
++ return newtable; |
19236 |
++ |
19237 |
++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE) |
19238 |
++ newtable = |
19239 |
++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL); |
19240 |
++ else |
19241 |
++ newtable = vmalloc(table_sizes[pwr] * elementsize); |
19242 |
++ |
19243 |
++ *len = table_sizes[pwr]; |
19244 |
++ |
19245 |
++ return newtable; |
19246 |
++} |
19247 |
++ |
19248 |
++static int |
19249 |
++init_variables(const struct gr_arg *arg) |
19250 |
++{ |
19251 |
++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper; |
19252 |
++ unsigned int stacksize; |
19253 |
++ |
19254 |
++ subj_map_set.s_size = arg->role_db.num_subjects; |
19255 |
++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children; |
19256 |
++ name_set.n_size = arg->role_db.num_objects; |
19257 |
++ inodev_set.i_size = arg->role_db.num_objects; |
19258 |
++ |
19259 |
++ if (!subj_map_set.s_size || !acl_role_set.r_size || |
19260 |
++ !name_set.n_size || !inodev_set.i_size) |
19261 |
++ return 1; |
19262 |
++ |
19263 |
++ if (!gr_init_uidset()) |
19264 |
++ return 1; |
19265 |
++ |
19266 |
++ /* set up the stack that holds allocation info */ |
19267 |
++ |
19268 |
++ stacksize = arg->role_db.num_pointers + 5; |
19269 |
++ |
19270 |
++ if (!acl_alloc_stack_init(stacksize)) |
19271 |
++ return 1; |
19272 |
++ |
19273 |
++ /* grab reference for the real root dentry and vfsmount */ |
19274 |
++ read_lock(&reaper->fs->lock); |
19275 |
++ real_root_mnt = mntget(reaper->fs->rootmnt); |
19276 |
++ real_root = dget(reaper->fs->root); |
19277 |
++ read_unlock(&reaper->fs->lock); |
19278 |
++ |
19279 |
++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label)); |
19280 |
++ if (fakefs_obj == NULL) |
19281 |
++ return 1; |
19282 |
++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC; |
19283 |
++ |
19284 |
++ subj_map_set.s_hash = |
19285 |
++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *)); |
19286 |
++ acl_role_set.r_hash = |
19287 |
++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *)); |
19288 |
++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *)); |
19289 |
++ inodev_set.i_hash = |
19290 |
++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *)); |
19291 |
++ |
19292 |
++ if (!subj_map_set.s_hash || !acl_role_set.r_hash || |
19293 |
++ !name_set.n_hash || !inodev_set.i_hash) |
19294 |
++ return 1; |
19295 |
++ |
19296 |
++ memset(subj_map_set.s_hash, 0, |
19297 |
++ sizeof(struct subject_map *) * subj_map_set.s_size); |
19298 |
++ memset(acl_role_set.r_hash, 0, |
19299 |
++ sizeof (struct acl_role_label *) * acl_role_set.r_size); |
19300 |
++ memset(name_set.n_hash, 0, |
19301 |
++ sizeof (struct name_entry *) * name_set.n_size); |
19302 |
++ memset(inodev_set.i_hash, 0, |
19303 |
++ sizeof (struct inodev_entry *) * inodev_set.i_size); |
19304 |
++ |
19305 |
++ return 0; |
19306 |
++} |
19307 |
++ |
19308 |
++/* free information not needed after startup |
19309 |
++ currently contains user->kernel pointer mappings for subjects |
19310 |
++*/ |
19311 |
++ |
19312 |
++static void |
19313 |
++free_init_variables(void) |
19314 |
++{ |
19315 |
++ __u32 i; |
19316 |
++ |
19317 |
++ if (subj_map_set.s_hash) { |
19318 |
++ for (i = 0; i < subj_map_set.s_size; i++) { |
19319 |
++ if (subj_map_set.s_hash[i]) { |
19320 |
++ kfree(subj_map_set.s_hash[i]); |
19321 |
++ subj_map_set.s_hash[i] = NULL; |
19322 |
++ } |
19323 |
++ } |
19324 |
++ |
19325 |
++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <= |
19326 |
++ PAGE_SIZE) |
19327 |
++ kfree(subj_map_set.s_hash); |
19328 |
++ else |
19329 |
++ vfree(subj_map_set.s_hash); |
19330 |
++ } |
19331 |
++ |
19332 |
++ return; |
19333 |
++} |
19334 |
++ |
19335 |
++static void |
19336 |
++free_variables(void) |
19337 |
++{ |
19338 |
++ struct acl_subject_label *s; |
19339 |
++ struct acl_role_label *r; |
19340 |
++ struct task_struct *task, *task2; |
19341 |
++ unsigned int i, x; |
19342 |
++ |
19343 |
++ gr_clear_learn_entries(); |
19344 |
++ |
19345 |
++ read_lock(&tasklist_lock); |
19346 |
++ do_each_thread(task2, task) { |
19347 |
++ task->acl_sp_role = 0; |
19348 |
++ task->acl_role_id = 0; |
19349 |
++ task->acl = NULL; |
19350 |
++ task->role = NULL; |
19351 |
++ } while_each_thread(task2, task); |
19352 |
++ read_unlock(&tasklist_lock); |
19353 |
++ |
19354 |
++ /* release the reference to the real root dentry and vfsmount */ |
19355 |
++ if (real_root) |
19356 |
++ dput(real_root); |
19357 |
++ real_root = NULL; |
19358 |
++ if (real_root_mnt) |
19359 |
++ mntput(real_root_mnt); |
19360 |
++ real_root_mnt = NULL; |
19361 |
++ |
19362 |
++ /* free all object hash tables */ |
19363 |
++ |
19364 |
++ FOR_EACH_ROLE_START(r, i) |
19365 |
++ if (r->subj_hash == NULL) |
19366 |
++ break; |
19367 |
++ FOR_EACH_SUBJECT_START(r, s, x) |
19368 |
++ if (s->obj_hash == NULL) |
19369 |
++ break; |
19370 |
++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE) |
19371 |
++ kfree(s->obj_hash); |
19372 |
++ else |
19373 |
++ vfree(s->obj_hash); |
19374 |
++ FOR_EACH_SUBJECT_END(s, x) |
19375 |
++ FOR_EACH_NESTED_SUBJECT_START(r, s) |
19376 |
++ if (s->obj_hash == NULL) |
19377 |
++ break; |
19378 |
++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE) |
19379 |
++ kfree(s->obj_hash); |
19380 |
++ else |
19381 |
++ vfree(s->obj_hash); |
19382 |
++ FOR_EACH_NESTED_SUBJECT_END(s) |
19383 |
++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE) |
19384 |
++ kfree(r->subj_hash); |
19385 |
++ else |
19386 |
++ vfree(r->subj_hash); |
19387 |
++ r->subj_hash = NULL; |
19388 |
++ FOR_EACH_ROLE_END(r,i) |
19389 |
++ |
19390 |
++ acl_free_all(); |
19391 |
++ |
19392 |
++ if (acl_role_set.r_hash) { |
19393 |
++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <= |
19394 |
++ PAGE_SIZE) |
19395 |
++ kfree(acl_role_set.r_hash); |
19396 |
++ else |
19397 |
++ vfree(acl_role_set.r_hash); |
19398 |
++ } |
19399 |
++ if (name_set.n_hash) { |
19400 |
++ if ((name_set.n_size * sizeof (struct name_entry *)) <= |
19401 |
++ PAGE_SIZE) |
19402 |
++ kfree(name_set.n_hash); |
19403 |
++ else |
19404 |
++ vfree(name_set.n_hash); |
19405 |
++ } |
19406 |
++ |
19407 |
++ if (inodev_set.i_hash) { |
19408 |
++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <= |
19409 |
++ PAGE_SIZE) |
19410 |
++ kfree(inodev_set.i_hash); |
19411 |
++ else |
19412 |
++ vfree(inodev_set.i_hash); |
19413 |
++ } |
19414 |
++ |
19415 |
++ gr_free_uidset(); |
19416 |
++ |
19417 |
++ memset(&name_set, 0, sizeof (struct name_db)); |
19418 |
++ memset(&inodev_set, 0, sizeof (struct inodev_db)); |
19419 |
++ memset(&acl_role_set, 0, sizeof (struct acl_role_db)); |
19420 |
++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db)); |
19421 |
++ |
19422 |
++ default_role = NULL; |
19423 |
++ |
19424 |
++ return; |
19425 |
++} |
19426 |
++ |
19427 |
++static __u32 |
19428 |
++count_user_objs(struct acl_object_label *userp) |
19429 |
++{ |
19430 |
++ struct acl_object_label o_tmp; |
19431 |
++ __u32 num = 0; |
19432 |
++ |
19433 |
++ while (userp) { |
19434 |
++ if (copy_from_user(&o_tmp, userp, |
19435 |
++ sizeof (struct acl_object_label))) |
19436 |
++ break; |
19437 |
++ |
19438 |
++ userp = o_tmp.prev; |
19439 |
++ num++; |
19440 |
++ } |
19441 |
++ |
19442 |
++ return num; |
19443 |
++} |
19444 |
++ |
19445 |
++static struct acl_subject_label * |
19446 |
++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role); |
19447 |
++ |
19448 |
++static int |
19449 |
++copy_user_glob(struct acl_object_label *obj) |
19450 |
++{ |
19451 |
++ struct acl_object_label *g_tmp, **guser; |
19452 |
++ unsigned int len; |
19453 |
++ char *tmp; |
19454 |
++ |
19455 |
++ if (obj->globbed == NULL) |
19456 |
++ return 0; |
19457 |
++ |
19458 |
++ guser = &obj->globbed; |
19459 |
++ while (*guser) { |
19460 |
++ g_tmp = (struct acl_object_label *) |
19461 |
++ acl_alloc(sizeof (struct acl_object_label)); |
19462 |
++ if (g_tmp == NULL) |
19463 |
++ return -ENOMEM; |
19464 |
++ |
19465 |
++ if (copy_from_user(g_tmp, *guser, |
19466 |
++ sizeof (struct acl_object_label))) |
19467 |
++ return -EFAULT; |
19468 |
++ |
19469 |
++ len = strnlen_user(g_tmp->filename, PATH_MAX); |
19470 |
++ |
19471 |
++ if (!len || len >= PATH_MAX) |
19472 |
++ return -EINVAL; |
19473 |
++ |
19474 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) |
19475 |
++ return -ENOMEM; |
19476 |
++ |
19477 |
++ if (copy_from_user(tmp, g_tmp->filename, len)) |
19478 |
++ return -EFAULT; |
19479 |
++ |
19480 |
++ g_tmp->filename = tmp; |
19481 |
++ |
19482 |
++ *guser = g_tmp; |
19483 |
++ guser = &(g_tmp->next); |
19484 |
++ } |
19485 |
++ |
19486 |
++ return 0; |
19487 |
++} |
19488 |
++ |
19489 |
++static int |
19490 |
++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj, |
19491 |
++ struct acl_role_label *role) |
19492 |
++{ |
19493 |
++ struct acl_object_label *o_tmp; |
19494 |
++ unsigned int len; |
19495 |
++ int ret; |
19496 |
++ char *tmp; |
19497 |
++ |
19498 |
++ while (userp) { |
19499 |
++ if ((o_tmp = (struct acl_object_label *) |
19500 |
++ acl_alloc(sizeof (struct acl_object_label))) == NULL) |
19501 |
++ return -ENOMEM; |
19502 |
++ |
19503 |
++ if (copy_from_user(o_tmp, userp, |
19504 |
++ sizeof (struct acl_object_label))) |
19505 |
++ return -EFAULT; |
19506 |
++ |
19507 |
++ userp = o_tmp->prev; |
19508 |
++ |
19509 |
++ len = strnlen_user(o_tmp->filename, PATH_MAX); |
19510 |
++ |
19511 |
++ if (!len || len >= PATH_MAX) |
19512 |
++ return -EINVAL; |
19513 |
++ |
19514 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) |
19515 |
++ return -ENOMEM; |
19516 |
++ |
19517 |
++ if (copy_from_user(tmp, o_tmp->filename, len)) |
19518 |
++ return -EFAULT; |
19519 |
++ |
19520 |
++ o_tmp->filename = tmp; |
19521 |
++ |
19522 |
++ insert_acl_obj_label(o_tmp, subj); |
19523 |
++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode, |
19524 |
++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0)) |
19525 |
++ return -ENOMEM; |
19526 |
++ |
19527 |
++ ret = copy_user_glob(o_tmp); |
19528 |
++ if (ret) |
19529 |
++ return ret; |
19530 |
++ |
19531 |
++ if (o_tmp->nested) { |
19532 |
++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role); |
19533 |
++ if (IS_ERR(o_tmp->nested)) |
19534 |
++ return PTR_ERR(o_tmp->nested); |
19535 |
++ |
19536 |
++ /* insert into nested subject list */ |
19537 |
++ o_tmp->nested->next = role->hash->first; |
19538 |
++ role->hash->first = o_tmp->nested; |
19539 |
++ } |
19540 |
++ } |
19541 |
++ |
19542 |
++ return 0; |
19543 |
++} |
19544 |
++ |
19545 |
++static __u32 |
19546 |
++count_user_subjs(struct acl_subject_label *userp) |
19547 |
++{ |
19548 |
++ struct acl_subject_label s_tmp; |
19549 |
++ __u32 num = 0; |
19550 |
++ |
19551 |
++ while (userp) { |
19552 |
++ if (copy_from_user(&s_tmp, userp, |
19553 |
++ sizeof (struct acl_subject_label))) |
19554 |
++ break; |
19555 |
++ |
19556 |
++ userp = s_tmp.prev; |
19557 |
++ /* do not count nested subjects against this count, since |
19558 |
++ they are not included in the hash table, but are |
19559 |
++ attached to objects. We have already counted |
19560 |
++ the subjects in userspace for the allocation |
19561 |
++ stack |
19562 |
++ */ |
19563 |
++ if (!(s_tmp.mode & GR_NESTED)) |
19564 |
++ num++; |
19565 |
++ } |
19566 |
++ |
19567 |
++ return num; |
19568 |
++} |
19569 |
++ |
19570 |
++static int |
19571 |
++copy_user_allowedips(struct acl_role_label *rolep) |
19572 |
++{ |
19573 |
++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast; |
19574 |
++ |
19575 |
++ ruserip = rolep->allowed_ips; |
19576 |
++ |
19577 |
++ while (ruserip) { |
19578 |
++ rlast = rtmp; |
19579 |
++ |
19580 |
++ if ((rtmp = (struct role_allowed_ip *) |
19581 |
++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL) |
19582 |
++ return -ENOMEM; |
19583 |
++ |
19584 |
++ if (copy_from_user(rtmp, ruserip, |
19585 |
++ sizeof (struct role_allowed_ip))) |
19586 |
++ return -EFAULT; |
19587 |
++ |
19588 |
++ ruserip = rtmp->prev; |
19589 |
++ |
19590 |
++ if (!rlast) { |
19591 |
++ rtmp->prev = NULL; |
19592 |
++ rolep->allowed_ips = rtmp; |
19593 |
++ } else { |
19594 |
++ rlast->next = rtmp; |
19595 |
++ rtmp->prev = rlast; |
19596 |
++ } |
19597 |
++ |
19598 |
++ if (!ruserip) |
19599 |
++ rtmp->next = NULL; |
19600 |
++ } |
19601 |
++ |
19602 |
++ return 0; |
19603 |
++} |
19604 |
++ |
19605 |
++static int |
19606 |
++copy_user_transitions(struct acl_role_label *rolep) |
19607 |
++{ |
19608 |
++ struct role_transition *rusertp, *rtmp = NULL, *rlast; |
19609 |
++ |
19610 |
++ unsigned int len; |
19611 |
++ char *tmp; |
19612 |
++ |
19613 |
++ rusertp = rolep->transitions; |
19614 |
++ |
19615 |
++ while (rusertp) { |
19616 |
++ rlast = rtmp; |
19617 |
++ |
19618 |
++ if ((rtmp = (struct role_transition *) |
19619 |
++ acl_alloc(sizeof (struct role_transition))) == NULL) |
19620 |
++ return -ENOMEM; |
19621 |
++ |
19622 |
++ if (copy_from_user(rtmp, rusertp, |
19623 |
++ sizeof (struct role_transition))) |
19624 |
++ return -EFAULT; |
19625 |
++ |
19626 |
++ rusertp = rtmp->prev; |
19627 |
++ |
19628 |
++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN); |
19629 |
++ |
19630 |
++ if (!len || len >= GR_SPROLE_LEN) |
19631 |
++ return -EINVAL; |
19632 |
++ |
19633 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) |
19634 |
++ return -ENOMEM; |
19635 |
++ |
19636 |
++ if (copy_from_user(tmp, rtmp->rolename, len)) |
19637 |
++ return -EFAULT; |
19638 |
++ |
19639 |
++ rtmp->rolename = tmp; |
19640 |
++ |
19641 |
++ if (!rlast) { |
19642 |
++ rtmp->prev = NULL; |
19643 |
++ rolep->transitions = rtmp; |
19644 |
++ } else { |
19645 |
++ rlast->next = rtmp; |
19646 |
++ rtmp->prev = rlast; |
19647 |
++ } |
19648 |
++ |
19649 |
++ if (!rusertp) |
19650 |
++ rtmp->next = NULL; |
19651 |
++ } |
19652 |
++ |
19653 |
++ return 0; |
19654 |
++} |
19655 |
++ |
19656 |
++static struct acl_subject_label * |
19657 |
++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role) |
19658 |
++{ |
19659 |
++ struct acl_subject_label *s_tmp = NULL, *s_tmp2; |
19660 |
++ unsigned int len; |
19661 |
++ char *tmp; |
19662 |
++ __u32 num_objs; |
19663 |
++ struct acl_ip_label **i_tmp, *i_utmp2; |
19664 |
++ struct gr_hash_struct ghash; |
19665 |
++ struct subject_map *subjmap; |
19666 |
++ unsigned int i_num; |
19667 |
++ int err; |
19668 |
++ |
19669 |
++ s_tmp = lookup_subject_map(userp); |
19670 |
++ |
19671 |
++ /* we've already copied this subject into the kernel, just return |
19672 |
++ the reference to it, and don't copy it over again |
19673 |
++ */ |
19674 |
++ if (s_tmp) |
19675 |
++ return(s_tmp); |
19676 |
++ |
19677 |
++ if ((s_tmp = (struct acl_subject_label *) |
19678 |
++ acl_alloc(sizeof (struct acl_subject_label))) == NULL) |
19679 |
++ return ERR_PTR(-ENOMEM); |
19680 |
++ |
19681 |
++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL); |
19682 |
++ if (subjmap == NULL) |
19683 |
++ return ERR_PTR(-ENOMEM); |
19684 |
++ |
19685 |
++ subjmap->user = userp; |
19686 |
++ subjmap->kernel = s_tmp; |
19687 |
++ insert_subj_map_entry(subjmap); |
19688 |
++ |
19689 |
++ if (copy_from_user(s_tmp, userp, |
19690 |
++ sizeof (struct acl_subject_label))) |
19691 |
++ return ERR_PTR(-EFAULT); |
19692 |
++ |
19693 |
++ len = strnlen_user(s_tmp->filename, PATH_MAX); |
19694 |
++ |
19695 |
++ if (!len || len >= PATH_MAX) |
19696 |
++ return ERR_PTR(-EINVAL); |
19697 |
++ |
19698 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) |
19699 |
++ return ERR_PTR(-ENOMEM); |
19700 |
++ |
19701 |
++ if (copy_from_user(tmp, s_tmp->filename, len)) |
19702 |
++ return ERR_PTR(-EFAULT); |
19703 |
++ |
19704 |
++ s_tmp->filename = tmp; |
19705 |
++ |
19706 |
++ if (!strcmp(s_tmp->filename, "/")) |
19707 |
++ role->root_label = s_tmp; |
19708 |
++ |
19709 |
++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct))) |
19710 |
++ return ERR_PTR(-EFAULT); |
19711 |
++ |
19712 |
++ /* copy user and group transition tables */ |
19713 |
++ |
19714 |
++ if (s_tmp->user_trans_num) { |
19715 |
++ uid_t *uidlist; |
19716 |
++ |
19717 |
++ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t)); |
19718 |
++ if (uidlist == NULL) |
19719 |
++ return ERR_PTR(-ENOMEM); |
19720 |
++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t))) |
19721 |
++ return ERR_PTR(-EFAULT); |
19722 |
++ |
19723 |
++ s_tmp->user_transitions = uidlist; |
19724 |
++ } |
19725 |
++ |
19726 |
++ if (s_tmp->group_trans_num) { |
19727 |
++ gid_t *gidlist; |
19728 |
++ |
19729 |
++ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t)); |
19730 |
++ if (gidlist == NULL) |
19731 |
++ return ERR_PTR(-ENOMEM); |
19732 |
++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t))) |
19733 |
++ return ERR_PTR(-EFAULT); |
19734 |
++ |
19735 |
++ s_tmp->group_transitions = gidlist; |
19736 |
++ } |
19737 |
++ |
19738 |
++ /* set up object hash table */ |
19739 |
++ num_objs = count_user_objs(ghash.first); |
19740 |
++ |
19741 |
++ s_tmp->obj_hash_size = num_objs; |
19742 |
++ s_tmp->obj_hash = |
19743 |
++ (struct acl_object_label **) |
19744 |
++ create_table(&(s_tmp->obj_hash_size), sizeof(void *)); |
19745 |
++ |
19746 |
++ if (!s_tmp->obj_hash) |
19747 |
++ return ERR_PTR(-ENOMEM); |
19748 |
++ |
19749 |
++ memset(s_tmp->obj_hash, 0, |
19750 |
++ s_tmp->obj_hash_size * |
19751 |
++ sizeof (struct acl_object_label *)); |
19752 |
++ |
19753 |
++ /* add in objects */ |
19754 |
++ err = copy_user_objs(ghash.first, s_tmp, role); |
19755 |
++ |
19756 |
++ if (err) |
19757 |
++ return ERR_PTR(err); |
19758 |
++ |
19759 |
++ /* set pointer for parent subject */ |
19760 |
++ if (s_tmp->parent_subject) { |
19761 |
++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role); |
19762 |
++ |
19763 |
++ if (IS_ERR(s_tmp2)) |
19764 |
++ return s_tmp2; |
19765 |
++ |
19766 |
++ s_tmp->parent_subject = s_tmp2; |
19767 |
++ } |
19768 |
++ |
19769 |
++ /* add in ip acls */ |
19770 |
++ |
19771 |
++ if (!s_tmp->ip_num) { |
19772 |
++ s_tmp->ips = NULL; |
19773 |
++ goto insert; |
19774 |
++ } |
19775 |
++ |
19776 |
++ i_tmp = |
19777 |
++ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num * |
19778 |
++ sizeof (struct |
19779 |
++ acl_ip_label *)); |
19780 |
++ |
19781 |
++ if (!i_tmp) |
19782 |
++ return ERR_PTR(-ENOMEM); |
19783 |
++ |
19784 |
++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) { |
19785 |
++ *(i_tmp + i_num) = |
19786 |
++ (struct acl_ip_label *) |
19787 |
++ acl_alloc(sizeof (struct acl_ip_label)); |
19788 |
++ if (!*(i_tmp + i_num)) |
19789 |
++ return ERR_PTR(-ENOMEM); |
19790 |
++ |
19791 |
++ if (copy_from_user |
19792 |
++ (&i_utmp2, s_tmp->ips + i_num, |
19793 |
++ sizeof (struct acl_ip_label *))) |
19794 |
++ return ERR_PTR(-EFAULT); |
19795 |
++ |
19796 |
++ if (copy_from_user |
19797 |
++ (*(i_tmp + i_num), i_utmp2, |
19798 |
++ sizeof (struct acl_ip_label))) |
19799 |
++ return ERR_PTR(-EFAULT); |
19800 |
++ |
19801 |
++ if ((*(i_tmp + i_num))->iface == NULL) |
19802 |
++ continue; |
19803 |
++ |
19804 |
++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ); |
19805 |
++ if (!len || len >= IFNAMSIZ) |
19806 |
++ return ERR_PTR(-EINVAL); |
19807 |
++ tmp = acl_alloc(len); |
19808 |
++ if (tmp == NULL) |
19809 |
++ return ERR_PTR(-ENOMEM); |
19810 |
++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len)) |
19811 |
++ return ERR_PTR(-EFAULT); |
19812 |
++ (*(i_tmp + i_num))->iface = tmp; |
19813 |
++ } |
19814 |
++ |
19815 |
++ s_tmp->ips = i_tmp; |
19816 |
++ |
19817 |
++insert: |
19818 |
++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode, |
19819 |
++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0)) |
19820 |
++ return ERR_PTR(-ENOMEM); |
19821 |
++ |
19822 |
++ return s_tmp; |
19823 |
++} |
19824 |
++ |
19825 |
++static int |
19826 |
++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role) |
19827 |
++{ |
19828 |
++ struct acl_subject_label s_pre; |
19829 |
++ struct acl_subject_label * ret; |
19830 |
++ int err; |
19831 |
++ |
19832 |
++ while (userp) { |
19833 |
++ if (copy_from_user(&s_pre, userp, |
19834 |
++ sizeof (struct acl_subject_label))) |
19835 |
++ return -EFAULT; |
19836 |
++ |
19837 |
++ /* do not add nested subjects here, add |
19838 |
++ while parsing objects |
19839 |
++ */ |
19840 |
++ |
19841 |
++ if (s_pre.mode & GR_NESTED) { |
19842 |
++ userp = s_pre.prev; |
19843 |
++ continue; |
19844 |
++ } |
19845 |
++ |
19846 |
++ ret = do_copy_user_subj(userp, role); |
19847 |
++ |
19848 |
++ err = PTR_ERR(ret); |
19849 |
++ if (IS_ERR(ret)) |
19850 |
++ return err; |
19851 |
++ |
19852 |
++ insert_acl_subj_label(ret, role); |
19853 |
++ |
19854 |
++ userp = s_pre.prev; |
19855 |
++ } |
19856 |
++ |
19857 |
++ return 0; |
19858 |
++} |
19859 |
++ |
19860 |
++static int |
19861 |
++copy_user_acl(struct gr_arg *arg) |
19862 |
++{ |
19863 |
++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2; |
19864 |
++ struct sprole_pw *sptmp; |
19865 |
++ struct gr_hash_struct *ghash; |
19866 |
++ uid_t *domainlist; |
19867 |
++ unsigned int r_num; |
19868 |
++ unsigned int len; |
19869 |
++ char *tmp; |
19870 |
++ int err = 0; |
19871 |
++ __u16 i; |
19872 |
++ __u32 num_subjs; |
19873 |
++ |
19874 |
++ /* we need a default and kernel role */ |
19875 |
++ if (arg->role_db.num_roles < 2) |
19876 |
++ return -EINVAL; |
19877 |
++ |
19878 |
++ /* copy special role authentication info from userspace */ |
19879 |
++ |
19880 |
++ num_sprole_pws = arg->num_sprole_pws; |
19881 |
++ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *)); |
19882 |
++ |
19883 |
++ if (!acl_special_roles) { |
19884 |
++ err = -ENOMEM; |
19885 |
++ goto cleanup; |
19886 |
++ } |
19887 |
++ |
19888 |
++ for (i = 0; i < num_sprole_pws; i++) { |
19889 |
++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw)); |
19890 |
++ if (!sptmp) { |
19891 |
++ err = -ENOMEM; |
19892 |
++ goto cleanup; |
19893 |
++ } |
19894 |
++ if (copy_from_user(sptmp, arg->sprole_pws + i, |
19895 |
++ sizeof (struct sprole_pw))) { |
19896 |
++ err = -EFAULT; |
19897 |
++ goto cleanup; |
19898 |
++ } |
19899 |
++ |
19900 |
++ len = |
19901 |
++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN); |
19902 |
++ |
19903 |
++ if (!len || len >= GR_SPROLE_LEN) { |
19904 |
++ err = -EINVAL; |
19905 |
++ goto cleanup; |
19906 |
++ } |
19907 |
++ |
19908 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) { |
19909 |
++ err = -ENOMEM; |
19910 |
++ goto cleanup; |
19911 |
++ } |
19912 |
++ |
19913 |
++ if (copy_from_user(tmp, sptmp->rolename, len)) { |
19914 |
++ err = -EFAULT; |
19915 |
++ goto cleanup; |
19916 |
++ } |
19917 |
++ |
19918 |
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG |
19919 |
++ printk(KERN_ALERT "Copying special role %s\n", tmp); |
19920 |
++#endif |
19921 |
++ sptmp->rolename = tmp; |
19922 |
++ acl_special_roles[i] = sptmp; |
19923 |
++ } |
19924 |
++ |
19925 |
++ r_utmp = (struct acl_role_label **) arg->role_db.r_table; |
19926 |
++ |
19927 |
++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) { |
19928 |
++ r_tmp = acl_alloc(sizeof (struct acl_role_label)); |
19929 |
++ |
19930 |
++ if (!r_tmp) { |
19931 |
++ err = -ENOMEM; |
19932 |
++ goto cleanup; |
19933 |
++ } |
19934 |
++ |
19935 |
++ if (copy_from_user(&r_utmp2, r_utmp + r_num, |
19936 |
++ sizeof (struct acl_role_label *))) { |
19937 |
++ err = -EFAULT; |
19938 |
++ goto cleanup; |
19939 |
++ } |
19940 |
++ |
19941 |
++ if (copy_from_user(r_tmp, r_utmp2, |
19942 |
++ sizeof (struct acl_role_label))) { |
19943 |
++ err = -EFAULT; |
19944 |
++ goto cleanup; |
19945 |
++ } |
19946 |
++ |
19947 |
++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN); |
19948 |
++ |
19949 |
++ if (!len || len >= PATH_MAX) { |
19950 |
++ err = -EINVAL; |
19951 |
++ goto cleanup; |
19952 |
++ } |
19953 |
++ |
19954 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) { |
19955 |
++ err = -ENOMEM; |
19956 |
++ goto cleanup; |
19957 |
++ } |
19958 |
++ if (copy_from_user(tmp, r_tmp->rolename, len)) { |
19959 |
++ err = -EFAULT; |
19960 |
++ goto cleanup; |
19961 |
++ } |
19962 |
++ r_tmp->rolename = tmp; |
19963 |
++ |
19964 |
++ if (!strcmp(r_tmp->rolename, "default") |
19965 |
++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) { |
19966 |
++ default_role = r_tmp; |
19967 |
++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) { |
19968 |
++ kernel_role = r_tmp; |
19969 |
++ } |
19970 |
++ |
19971 |
++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) { |
19972 |
++ err = -ENOMEM; |
19973 |
++ goto cleanup; |
19974 |
++ } |
19975 |
++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) { |
19976 |
++ err = -EFAULT; |
19977 |
++ goto cleanup; |
19978 |
++ } |
19979 |
++ |
19980 |
++ r_tmp->hash = ghash; |
19981 |
++ |
19982 |
++ num_subjs = count_user_subjs(r_tmp->hash->first); |
19983 |
++ |
19984 |
++ r_tmp->subj_hash_size = num_subjs; |
19985 |
++ r_tmp->subj_hash = |
19986 |
++ (struct acl_subject_label **) |
19987 |
++ create_table(&(r_tmp->subj_hash_size), sizeof(void *)); |
19988 |
++ |
19989 |
++ if (!r_tmp->subj_hash) { |
19990 |
++ err = -ENOMEM; |
19991 |
++ goto cleanup; |
19992 |
++ } |
19993 |
++ |
19994 |
++ err = copy_user_allowedips(r_tmp); |
19995 |
++ if (err) |
19996 |
++ goto cleanup; |
19997 |
++ |
19998 |
++ /* copy domain info */ |
19999 |
++ if (r_tmp->domain_children != NULL) { |
20000 |
++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t)); |
20001 |
++ if (domainlist == NULL) { |
20002 |
++ err = -ENOMEM; |
20003 |
++ goto cleanup; |
20004 |
++ } |
20005 |
++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) { |
20006 |
++ err = -EFAULT; |
20007 |
++ goto cleanup; |
20008 |
++ } |
20009 |
++ r_tmp->domain_children = domainlist; |
20010 |
++ } |
20011 |
++ |
20012 |
++ err = copy_user_transitions(r_tmp); |
20013 |
++ if (err) |
20014 |
++ goto cleanup; |
20015 |
++ |
20016 |
++ memset(r_tmp->subj_hash, 0, |
20017 |
++ r_tmp->subj_hash_size * |
20018 |
++ sizeof (struct acl_subject_label *)); |
20019 |
++ |
20020 |
++ err = copy_user_subjs(r_tmp->hash->first, r_tmp); |
20021 |
++ |
20022 |
++ if (err) |
20023 |
++ goto cleanup; |
20024 |
++ |
20025 |
++ /* set nested subject list to null */ |
20026 |
++ r_tmp->hash->first = NULL; |
20027 |
++ |
20028 |
++ insert_acl_role_label(r_tmp); |
20029 |
++ } |
20030 |
++ |
20031 |
++ goto return_err; |
20032 |
++ cleanup: |
20033 |
++ free_variables(); |
20034 |
++ return_err: |
20035 |
++ return err; |
20036 |
++ |
20037 |
++} |
20038 |
++ |
20039 |
++static int |
20040 |
++gracl_init(struct gr_arg *args) |
20041 |
++{ |
20042 |
++ int error = 0; |
20043 |
++ |
20044 |
++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN); |
20045 |
++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN); |
20046 |
++ |
20047 |
++ if (init_variables(args)) { |
20048 |
++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION); |
20049 |
++ error = -ENOMEM; |
20050 |
++ free_variables(); |
20051 |
++ goto out; |
20052 |
++ } |
20053 |
++ |
20054 |
++ error = copy_user_acl(args); |
20055 |
++ free_init_variables(); |
20056 |
++ if (error) { |
20057 |
++ free_variables(); |
20058 |
++ goto out; |
20059 |
++ } |
20060 |
++ |
20061 |
++ if ((error = gr_set_acls(0))) { |
20062 |
++ free_variables(); |
20063 |
++ goto out; |
20064 |
++ } |
20065 |
++ |
20066 |
++ gr_status |= GR_READY; |
20067 |
++ out: |
20068 |
++ return error; |
20069 |
++} |
20070 |
++ |
20071 |
++/* derived from glibc fnmatch() 0: match, 1: no match*/ |
20072 |
++ |
20073 |
++static int |
20074 |
++glob_match(const char *p, const char *n) |
20075 |
++{ |
20076 |
++ char c; |
20077 |
++ |
20078 |
++ while ((c = *p++) != '\0') { |
20079 |
++ switch (c) { |
20080 |
++ case '?': |
20081 |
++ if (*n == '\0') |
20082 |
++ return 1; |
20083 |
++ else if (*n == '/') |
20084 |
++ return 1; |
20085 |
++ break; |
20086 |
++ case '\\': |
20087 |
++ if (*n != c) |
20088 |
++ return 1; |
20089 |
++ break; |
20090 |
++ case '*': |
20091 |
++ for (c = *p++; c == '?' || c == '*'; c = *p++) { |
20092 |
++ if (*n == '/') |
20093 |
++ return 1; |
20094 |
++ else if (c == '?') { |
20095 |
++ if (*n == '\0') |
20096 |
++ return 1; |
20097 |
++ else |
20098 |
++ ++n; |
20099 |
++ } |
20100 |
++ } |
20101 |
++ if (c == '\0') { |
20102 |
++ return 0; |
20103 |
++ } else { |
20104 |
++ const char *endp; |
20105 |
++ |
20106 |
++ if ((endp = strchr(n, '/')) == NULL) |
20107 |
++ endp = n + strlen(n); |
20108 |
++ |
20109 |
++ if (c == '[') { |
20110 |
++ for (--p; n < endp; ++n) |
20111 |
++ if (!glob_match(p, n)) |
20112 |
++ return 0; |
20113 |
++ } else if (c == '/') { |
20114 |
++ while (*n != '\0' && *n != '/') |
20115 |
++ ++n; |
20116 |
++ if (*n == '/' && !glob_match(p, n + 1)) |
20117 |
++ return 0; |
20118 |
++ } else { |
20119 |
++ for (--p; n < endp; ++n) |
20120 |
++ if (*n == c && !glob_match(p, n)) |
20121 |
++ return 0; |
20122 |
++ } |
20123 |
++ |
20124 |
++ return 1; |
20125 |
++ } |
20126 |
++ case '[': |
20127 |
++ { |
20128 |
++ int not; |
20129 |
++ char cold; |
20130 |
++ |
20131 |
++ if (*n == '\0' || *n == '/') |
20132 |
++ return 1; |
20133 |
++ |
20134 |
++ not = (*p == '!' || *p == '^'); |
20135 |
++ if (not) |
20136 |
++ ++p; |
20137 |
++ |
20138 |
++ c = *p++; |
20139 |
++ for (;;) { |
20140 |
++ unsigned char fn = (unsigned char)*n; |
20141 |
++ |
20142 |
++ if (c == '\0') |
20143 |
++ return 1; |
20144 |
++ else { |
20145 |
++ if (c == fn) |
20146 |
++ goto matched; |
20147 |
++ cold = c; |
20148 |
++ c = *p++; |
20149 |
++ |
20150 |
++ if (c == '-' && *p != ']') { |
20151 |
++ unsigned char cend = *p++; |
20152 |
++ |
20153 |
++ if (cend == '\0') |
20154 |
++ return 1; |
20155 |
++ |
20156 |
++ if (cold <= fn && fn <= cend) |
20157 |
++ goto matched; |
20158 |
++ |
20159 |
++ c = *p++; |
20160 |
++ } |
20161 |
++ } |
20162 |
++ |
20163 |
++ if (c == ']') |
20164 |
++ break; |
20165 |
++ } |
20166 |
++ if (!not) |
20167 |
++ return 1; |
20168 |
++ break; |
20169 |
++ matched: |
20170 |
++ while (c != ']') { |
20171 |
++ if (c == '\0') |
20172 |
++ return 1; |
20173 |
++ |
20174 |
++ c = *p++; |
20175 |
++ } |
20176 |
++ if (not) |
20177 |
++ return 1; |
20178 |
++ } |
20179 |
++ break; |
20180 |
++ default: |
20181 |
++ if (c != *n) |
20182 |
++ return 1; |
20183 |
++ } |
20184 |
++ |
20185 |
++ ++n; |
20186 |
++ } |
20187 |
++ |
20188 |
++ if (*n == '\0') |
20189 |
++ return 0; |
20190 |
++ |
20191 |
++ if (*n == '/') |
20192 |
++ return 0; |
20193 |
++ |
20194 |
++ return 1; |
20195 |
++} |
20196 |
++ |
20197 |
++static struct acl_object_label * |
20198 |
++chk_glob_label(struct acl_object_label *globbed, |
20199 |
++ struct dentry *dentry, struct vfsmount *mnt, char **path) |
20200 |
++{ |
20201 |
++ struct acl_object_label *tmp; |
20202 |
++ |
20203 |
++ if (*path == NULL) |
20204 |
++ *path = gr_to_filename_nolock(dentry, mnt); |
20205 |
++ |
20206 |
++ tmp = globbed; |
20207 |
++ |
20208 |
++ while (tmp) { |
20209 |
++ if (!glob_match(tmp->filename, *path)) |
20210 |
++ return tmp; |
20211 |
++ tmp = tmp->next; |
20212 |
++ } |
20213 |
++ |
20214 |
++ return NULL; |
20215 |
++} |
20216 |
++ |
20217 |
++static struct acl_object_label * |
20218 |
++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt, |
20219 |
++ const ino_t curr_ino, const dev_t curr_dev, |
20220 |
++ const struct acl_subject_label *subj, char **path) |
20221 |
++{ |
20222 |
++ struct acl_subject_label *tmpsubj; |
20223 |
++ struct acl_object_label *retval; |
20224 |
++ struct acl_object_label *retval2; |
20225 |
++ |
20226 |
++ tmpsubj = (struct acl_subject_label *) subj; |
20227 |
++ read_lock(&gr_inode_lock); |
20228 |
++ do { |
20229 |
++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj); |
20230 |
++ if (retval) { |
20231 |
++ if (retval->globbed) { |
20232 |
++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry, |
20233 |
++ (struct vfsmount *)orig_mnt, path); |
20234 |
++ if (retval2) |
20235 |
++ retval = retval2; |
20236 |
++ } |
20237 |
++ break; |
20238 |
++ } |
20239 |
++ } while ((tmpsubj = tmpsubj->parent_subject)); |
20240 |
++ read_unlock(&gr_inode_lock); |
20241 |
++ |
20242 |
++ return retval; |
20243 |
++} |
20244 |
++ |
20245 |
++static __inline__ struct acl_object_label * |
20246 |
++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt, |
20247 |
++ const struct dentry *curr_dentry, |
20248 |
++ const struct acl_subject_label *subj, char **path) |
20249 |
++{ |
20250 |
++ return __full_lookup(orig_dentry, orig_mnt, |
20251 |
++ curr_dentry->d_inode->i_ino, |
20252 |
++ curr_dentry->d_inode->i_sb->s_dev, subj, path); |
20253 |
++} |
20254 |
++ |
20255 |
++static struct acl_object_label * |
20256 |
++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, |
20257 |
++ const struct acl_subject_label *subj, char *path) |
20258 |
++{ |
20259 |
++ struct dentry *dentry = (struct dentry *) l_dentry; |
20260 |
++ struct vfsmount *mnt = (struct vfsmount *) l_mnt; |
20261 |
++ struct acl_object_label *retval; |
20262 |
++ |
20263 |
++ spin_lock(&dcache_lock); |
20264 |
++ |
20265 |
++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt || |
20266 |
++ /* ignore Eric Biederman */ |
20267 |
++ IS_PRIVATE(l_dentry->d_inode))) { |
20268 |
++ retval = fakefs_obj; |
20269 |
++ goto out; |
20270 |
++ } |
20271 |
++ |
20272 |
++ for (;;) { |
20273 |
++ if (dentry == real_root && mnt == real_root_mnt) |
20274 |
++ break; |
20275 |
++ |
20276 |
++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) { |
20277 |
++ if (mnt->mnt_parent == mnt) |
20278 |
++ break; |
20279 |
++ |
20280 |
++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); |
20281 |
++ if (retval != NULL) |
20282 |
++ goto out; |
20283 |
++ |
20284 |
++ dentry = mnt->mnt_mountpoint; |
20285 |
++ mnt = mnt->mnt_parent; |
20286 |
++ continue; |
20287 |
++ } |
20288 |
++ |
20289 |
++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); |
20290 |
++ if (retval != NULL) |
20291 |
++ goto out; |
20292 |
++ |
20293 |
++ dentry = dentry->d_parent; |
20294 |
++ } |
20295 |
++ |
20296 |
++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); |
20297 |
++ |
20298 |
++ if (retval == NULL) |
20299 |
++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path); |
20300 |
++out: |
20301 |
++ spin_unlock(&dcache_lock); |
20302 |
++ return retval; |
20303 |
++} |
20304 |
++ |
20305 |
++static __inline__ struct acl_object_label * |
20306 |
++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, |
20307 |
++ const struct acl_subject_label *subj) |
20308 |
++{ |
20309 |
++ char *path = NULL; |
20310 |
++ return __chk_obj_label(l_dentry, l_mnt, subj, path); |
20311 |
++} |
20312 |
++ |
20313 |
++static __inline__ struct acl_object_label * |
20314 |
++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, |
20315 |
++ const struct acl_subject_label *subj, char *path) |
20316 |
++{ |
20317 |
++ return __chk_obj_label(l_dentry, l_mnt, subj, path); |
20318 |
++} |
20319 |
++ |
20320 |
++static struct acl_subject_label * |
20321 |
++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, |
20322 |
++ const struct acl_role_label *role) |
20323 |
++{ |
20324 |
++ struct dentry *dentry = (struct dentry *) l_dentry; |
20325 |
++ struct vfsmount *mnt = (struct vfsmount *) l_mnt; |
20326 |
++ struct acl_subject_label *retval; |
20327 |
++ |
20328 |
++ spin_lock(&dcache_lock); |
20329 |
++ |
20330 |
++ for (;;) { |
20331 |
++ if (dentry == real_root && mnt == real_root_mnt) |
20332 |
++ break; |
20333 |
++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) { |
20334 |
++ if (mnt->mnt_parent == mnt) |
20335 |
++ break; |
20336 |
++ |
20337 |
++ read_lock(&gr_inode_lock); |
20338 |
++ retval = |
20339 |
++ lookup_acl_subj_label(dentry->d_inode->i_ino, |
20340 |
++ dentry->d_inode->i_sb->s_dev, role); |
20341 |
++ read_unlock(&gr_inode_lock); |
20342 |
++ if (retval != NULL) |
20343 |
++ goto out; |
20344 |
++ |
20345 |
++ dentry = mnt->mnt_mountpoint; |
20346 |
++ mnt = mnt->mnt_parent; |
20347 |
++ continue; |
20348 |
++ } |
20349 |
++ |
20350 |
++ read_lock(&gr_inode_lock); |
20351 |
++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino, |
20352 |
++ dentry->d_inode->i_sb->s_dev, role); |
20353 |
++ read_unlock(&gr_inode_lock); |
20354 |
++ if (retval != NULL) |
20355 |
++ goto out; |
20356 |
++ |
20357 |
++ dentry = dentry->d_parent; |
20358 |
++ } |
20359 |
++ |
20360 |
++ read_lock(&gr_inode_lock); |
20361 |
++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino, |
20362 |
++ dentry->d_inode->i_sb->s_dev, role); |
20363 |
++ read_unlock(&gr_inode_lock); |
20364 |
++ |
20365 |
++ if (unlikely(retval == NULL)) { |
20366 |
++ read_lock(&gr_inode_lock); |
20367 |
++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino, |
20368 |
++ real_root->d_inode->i_sb->s_dev, role); |
20369 |
++ read_unlock(&gr_inode_lock); |
20370 |
++ } |
20371 |
++out: |
20372 |
++ spin_unlock(&dcache_lock); |
20373 |
++ |
20374 |
++ return retval; |
20375 |
++} |
20376 |
++ |
20377 |
++static void |
20378 |
++gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode) |
20379 |
++{ |
20380 |
++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype, |
20381 |
++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry, |
20382 |
++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename, |
20383 |
++ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip)); |
20384 |
++ |
20385 |
++ return; |
20386 |
++} |
20387 |
++ |
20388 |
++static void |
20389 |
++gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode) |
20390 |
++{ |
20391 |
++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype, |
20392 |
++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry, |
20393 |
++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename, |
20394 |
++ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip)); |
20395 |
++ |
20396 |
++ return; |
20397 |
++} |
20398 |
++ |
20399 |
++static void |
20400 |
++gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, |
20401 |
++ const unsigned int effective, const unsigned int fs) |
20402 |
++{ |
20403 |
++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype, |
20404 |
++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry, |
20405 |
++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename, |
20406 |
++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip)); |
20407 |
++ |
20408 |
++ return; |
20409 |
++} |
20410 |
++ |
20411 |
++__u32 |
20412 |
++gr_check_link(const struct dentry * new_dentry, |
20413 |
++ const struct dentry * parent_dentry, |
20414 |
++ const struct vfsmount * parent_mnt, |
20415 |
++ const struct dentry * old_dentry, const struct vfsmount * old_mnt) |
20416 |
++{ |
20417 |
++ struct acl_object_label *obj; |
20418 |
++ __u32 oldmode, newmode; |
20419 |
++ __u32 needmode; |
20420 |
++ |
20421 |
++ if (unlikely(!(gr_status & GR_READY))) |
20422 |
++ return (GR_CREATE | GR_LINK); |
20423 |
++ |
20424 |
++ obj = chk_obj_label(old_dentry, old_mnt, current->acl); |
20425 |
++ oldmode = obj->mode; |
20426 |
++ |
20427 |
++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) |
20428 |
++ oldmode |= (GR_CREATE | GR_LINK); |
20429 |
++ |
20430 |
++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS; |
20431 |
++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID)) |
20432 |
++ needmode |= GR_SETID | GR_AUDIT_SETID; |
20433 |
++ |
20434 |
++ newmode = |
20435 |
++ gr_check_create(new_dentry, parent_dentry, parent_mnt, |
20436 |
++ oldmode | needmode); |
20437 |
++ |
20438 |
++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC | |
20439 |
++ GR_SETID | GR_READ | GR_FIND | GR_DELETE | |
20440 |
++ GR_INHERIT | GR_AUDIT_INHERIT); |
20441 |
++ |
20442 |
++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID)) |
20443 |
++ goto bad; |
20444 |
++ |
20445 |
++ if ((oldmode & needmode) != needmode) |
20446 |
++ goto bad; |
20447 |
++ |
20448 |
++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS); |
20449 |
++ if ((newmode & needmode) != needmode) |
20450 |
++ goto bad; |
20451 |
++ |
20452 |
++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK)) |
20453 |
++ return newmode; |
20454 |
++bad: |
20455 |
++ needmode = oldmode; |
20456 |
++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID)) |
20457 |
++ needmode |= GR_SETID; |
20458 |
++ |
20459 |
++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) { |
20460 |
++ gr_log_learn(current, old_dentry, old_mnt, needmode); |
20461 |
++ return (GR_CREATE | GR_LINK); |
20462 |
++ } else if (newmode & GR_SUPPRESS) |
20463 |
++ return GR_SUPPRESS; |
20464 |
++ else |
20465 |
++ return 0; |
20466 |
++} |
20467 |
++ |
20468 |
++__u32 |
20469 |
++gr_search_file(const struct dentry * dentry, const __u32 mode, |
20470 |
++ const struct vfsmount * mnt) |
20471 |
++{ |
20472 |
++ __u32 retval = mode; |
20473 |
++ struct acl_subject_label *curracl; |
20474 |
++ struct acl_object_label *currobj; |
20475 |
++ |
20476 |
++ if (unlikely(!(gr_status & GR_READY))) |
20477 |
++ return (mode & ~GR_AUDITS); |
20478 |
++ |
20479 |
++ curracl = current->acl; |
20480 |
++ |
20481 |
++ currobj = chk_obj_label(dentry, mnt, curracl); |
20482 |
++ retval = currobj->mode & mode; |
20483 |
++ |
20484 |
++ if (unlikely |
20485 |
++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE) |
20486 |
++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) { |
20487 |
++ __u32 new_mode = mode; |
20488 |
++ |
20489 |
++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); |
20490 |
++ |
20491 |
++ retval = new_mode; |
20492 |
++ |
20493 |
++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN) |
20494 |
++ new_mode |= GR_INHERIT; |
20495 |
++ |
20496 |
++ if (!(mode & GR_NOLEARN)) |
20497 |
++ gr_log_learn(current, dentry, mnt, new_mode); |
20498 |
++ } |
20499 |
++ |
20500 |
++ return retval; |
20501 |
++} |
20502 |
++ |
20503 |
++__u32 |
20504 |
++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent, |
20505 |
++ const struct vfsmount * mnt, const __u32 mode) |
20506 |
++{ |
20507 |
++ struct name_entry *match; |
20508 |
++ struct acl_object_label *matchpo; |
20509 |
++ struct acl_subject_label *curracl; |
20510 |
++ char *path; |
20511 |
++ __u32 retval; |
20512 |
++ |
20513 |
++ if (unlikely(!(gr_status & GR_READY))) |
20514 |
++ return (mode & ~GR_AUDITS); |
20515 |
++ |
20516 |
++ preempt_disable(); |
20517 |
++ path = gr_to_filename_rbac(new_dentry, mnt); |
20518 |
++ match = lookup_name_entry_create(path); |
20519 |
++ |
20520 |
++ if (!match) |
20521 |
++ goto check_parent; |
20522 |
++ |
20523 |
++ curracl = current->acl; |
20524 |
++ |
20525 |
++ read_lock(&gr_inode_lock); |
20526 |
++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl); |
20527 |
++ read_unlock(&gr_inode_lock); |
20528 |
++ |
20529 |
++ if (matchpo) { |
20530 |
++ if ((matchpo->mode & mode) != |
20531 |
++ (mode & ~(GR_AUDITS | GR_SUPPRESS)) |
20532 |
++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) { |
20533 |
++ __u32 new_mode = mode; |
20534 |
++ |
20535 |
++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); |
20536 |
++ |
20537 |
++ gr_log_learn(current, new_dentry, mnt, new_mode); |
20538 |
++ |
20539 |
++ preempt_enable(); |
20540 |
++ return new_mode; |
20541 |
++ } |
20542 |
++ preempt_enable(); |
20543 |
++ return (matchpo->mode & mode); |
20544 |
++ } |
20545 |
++ |
20546 |
++ check_parent: |
20547 |
++ curracl = current->acl; |
20548 |
++ |
20549 |
++ matchpo = chk_obj_create_label(parent, mnt, curracl, path); |
20550 |
++ retval = matchpo->mode & mode; |
20551 |
++ |
20552 |
++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))) |
20553 |
++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) { |
20554 |
++ __u32 new_mode = mode; |
20555 |
++ |
20556 |
++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); |
20557 |
++ |
20558 |
++ gr_log_learn(current, new_dentry, mnt, new_mode); |
20559 |
++ preempt_enable(); |
20560 |
++ return new_mode; |
20561 |
++ } |
20562 |
++ |
20563 |
++ preempt_enable(); |
20564 |
++ return retval; |
20565 |
++} |
20566 |
++ |
20567 |
++int |
20568 |
++gr_check_hidden_task(const struct task_struct *task) |
20569 |
++{ |
20570 |
++ if (unlikely(!(gr_status & GR_READY))) |
20571 |
++ return 0; |
20572 |
++ |
20573 |
++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW)) |
20574 |
++ return 1; |
20575 |
++ |
20576 |
++ return 0; |
20577 |
++} |
20578 |
++ |
20579 |
++int |
20580 |
++gr_check_protected_task(const struct task_struct *task) |
20581 |
++{ |
20582 |
++ if (unlikely(!(gr_status & GR_READY) || !task)) |
20583 |
++ return 0; |
20584 |
++ |
20585 |
++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) && |
20586 |
++ task->acl != current->acl) |
20587 |
++ return 1; |
20588 |
++ |
20589 |
++ return 0; |
20590 |
++} |
20591 |
++ |
20592 |
++void |
20593 |
++gr_copy_label(struct task_struct *tsk) |
20594 |
++{ |
20595 |
++ tsk->signal->used_accept = 0; |
20596 |
++ tsk->acl_sp_role = 0; |
20597 |
++ tsk->acl_role_id = current->acl_role_id; |
20598 |
++ tsk->acl = current->acl; |
20599 |
++ tsk->role = current->role; |
20600 |
++ tsk->signal->curr_ip = current->signal->curr_ip; |
20601 |
++ if (current->exec_file) |
20602 |
++ get_file(current->exec_file); |
20603 |
++ tsk->exec_file = current->exec_file; |
20604 |
++ tsk->is_writable = current->is_writable; |
20605 |
++ if (unlikely(current->signal->used_accept)) |
20606 |
++ current->signal->curr_ip = 0; |
20607 |
++ |
20608 |
++ return; |
20609 |
++} |
20610 |
++ |
20611 |
++static void |
20612 |
++gr_set_proc_res(struct task_struct *task) |
20613 |
++{ |
20614 |
++ struct acl_subject_label *proc; |
20615 |
++ unsigned short i; |
20616 |
++ |
20617 |
++ proc = task->acl; |
20618 |
++ |
20619 |
++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN)) |
20620 |
++ return; |
20621 |
++ |
20622 |
++ for (i = 0; i < (GR_NLIMITS - 1); i++) { |
20623 |
++ if (!(proc->resmask & (1 << i))) |
20624 |
++ continue; |
20625 |
++ |
20626 |
++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur; |
20627 |
++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max; |
20628 |
++ } |
20629 |
++ |
20630 |
++ return; |
20631 |
++} |
20632 |
++ |
20633 |
++int |
20634 |
++gr_check_user_change(int real, int effective, int fs) |
20635 |
++{ |
20636 |
++ unsigned int i; |
20637 |
++ __u16 num; |
20638 |
++ uid_t *uidlist; |
20639 |
++ int curuid; |
20640 |
++ int realok = 0; |
20641 |
++ int effectiveok = 0; |
20642 |
++ int fsok = 0; |
20643 |
++ |
20644 |
++ if (unlikely(!(gr_status & GR_READY))) |
20645 |
++ return 0; |
20646 |
++ |
20647 |
++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) |
20648 |
++ gr_log_learn_id_change(current, 'u', real, effective, fs); |
20649 |
++ |
20650 |
++ num = current->acl->user_trans_num; |
20651 |
++ uidlist = current->acl->user_transitions; |
20652 |
++ |
20653 |
++ if (uidlist == NULL) |
20654 |
++ return 0; |
20655 |
++ |
20656 |
++ if (real == -1) |
20657 |
++ realok = 1; |
20658 |
++ if (effective == -1) |
20659 |
++ effectiveok = 1; |
20660 |
++ if (fs == -1) |
20661 |
++ fsok = 1; |
20662 |
++ |
20663 |
++ if (current->acl->user_trans_type & GR_ID_ALLOW) { |
20664 |
++ for (i = 0; i < num; i++) { |
20665 |
++ curuid = (int)uidlist[i]; |
20666 |
++ if (real == curuid) |
20667 |
++ realok = 1; |
20668 |
++ if (effective == curuid) |
20669 |
++ effectiveok = 1; |
20670 |
++ if (fs == curuid) |
20671 |
++ fsok = 1; |
20672 |
++ } |
20673 |
++ } else if (current->acl->user_trans_type & GR_ID_DENY) { |
20674 |
++ for (i = 0; i < num; i++) { |
20675 |
++ curuid = (int)uidlist[i]; |
20676 |
++ if (real == curuid) |
20677 |
++ break; |
20678 |
++ if (effective == curuid) |
20679 |
++ break; |
20680 |
++ if (fs == curuid) |
20681 |
++ break; |
20682 |
++ } |
20683 |
++ /* not in deny list */ |
20684 |
++ if (i == num) { |
20685 |
++ realok = 1; |
20686 |
++ effectiveok = 1; |
20687 |
++ fsok = 1; |
20688 |
++ } |
20689 |
++ } |
20690 |
++ |
20691 |
++ if (realok && effectiveok && fsok) |
20692 |
++ return 0; |
20693 |
++ else { |
20694 |
++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real); |
20695 |
++ return 1; |
20696 |
++ } |
20697 |
++} |
20698 |
++ |
20699 |
++int |
20700 |
++gr_check_group_change(int real, int effective, int fs) |
20701 |
++{ |
20702 |
++ unsigned int i; |
20703 |
++ __u16 num; |
20704 |
++ gid_t *gidlist; |
20705 |
++ int curgid; |
20706 |
++ int realok = 0; |
20707 |
++ int effectiveok = 0; |
20708 |
++ int fsok = 0; |
20709 |
++ |
20710 |
++ if (unlikely(!(gr_status & GR_READY))) |
20711 |
++ return 0; |
20712 |
++ |
20713 |
++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) |
20714 |
++ gr_log_learn_id_change(current, 'g', real, effective, fs); |
20715 |
++ |
20716 |
++ num = current->acl->group_trans_num; |
20717 |
++ gidlist = current->acl->group_transitions; |
20718 |
++ |
20719 |
++ if (gidlist == NULL) |
20720 |
++ return 0; |
20721 |
++ |
20722 |
++ if (real == -1) |
20723 |
++ realok = 1; |
20724 |
++ if (effective == -1) |
20725 |
++ effectiveok = 1; |
20726 |
++ if (fs == -1) |
20727 |
++ fsok = 1; |
20728 |
++ |
20729 |
++ if (current->acl->group_trans_type & GR_ID_ALLOW) { |
20730 |
++ for (i = 0; i < num; i++) { |
20731 |
++ curgid = (int)gidlist[i]; |
20732 |
++ if (real == curgid) |
20733 |
++ realok = 1; |
20734 |
++ if (effective == curgid) |
20735 |
++ effectiveok = 1; |
20736 |
++ if (fs == curgid) |
20737 |
++ fsok = 1; |
20738 |
++ } |
20739 |
++ } else if (current->acl->group_trans_type & GR_ID_DENY) { |
20740 |
++ for (i = 0; i < num; i++) { |
20741 |
++ curgid = (int)gidlist[i]; |
20742 |
++ if (real == curgid) |
20743 |
++ break; |
20744 |
++ if (effective == curgid) |
20745 |
++ break; |
20746 |
++ if (fs == curgid) |
20747 |
++ break; |
20748 |
++ } |
20749 |
++ /* not in deny list */ |
20750 |
++ if (i == num) { |
20751 |
++ realok = 1; |
20752 |
++ effectiveok = 1; |
20753 |
++ fsok = 1; |
20754 |
++ } |
20755 |
++ } |
20756 |
++ |
20757 |
++ if (realok && effectiveok && fsok) |
20758 |
++ return 0; |
20759 |
++ else { |
20760 |
++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real); |
20761 |
++ return 1; |
20762 |
++ } |
20763 |
++} |
20764 |
++ |
20765 |
++void |
20766 |
++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid) |
20767 |
++{ |
20768 |
++ struct acl_role_label *role = task->role; |
20769 |
++ struct acl_subject_label *subj = NULL; |
20770 |
++ struct acl_object_label *obj; |
20771 |
++ struct file *filp; |
20772 |
++ |
20773 |
++ if (unlikely(!(gr_status & GR_READY))) |
20774 |
++ return; |
20775 |
++ |
20776 |
++ filp = task->exec_file; |
20777 |
++ |
20778 |
++ /* kernel process, we'll give them the kernel role */ |
20779 |
++ if (unlikely(!filp)) { |
20780 |
++ task->role = kernel_role; |
20781 |
++ task->acl = kernel_role->root_label; |
20782 |
++ return; |
20783 |
++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL)) |
20784 |
++ role = lookup_acl_role_label(task, uid, gid); |
20785 |
++ |
20786 |
++ /* perform subject lookup in possibly new role |
20787 |
++ we can use this result below in the case where role == task->role |
20788 |
++ */ |
20789 |
++ subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role); |
20790 |
++ |
20791 |
++ /* if we changed uid/gid, but result in the same role |
20792 |
++ and are using inheritance, don't lose the inherited subject |
20793 |
++ if current subject is other than what normal lookup |
20794 |
++ would result in, we arrived via inheritance, don't |
20795 |
++ lose subject |
20796 |
++ */ |
20797 |
++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) && |
20798 |
++ (subj == task->acl))) |
20799 |
++ task->acl = subj; |
20800 |
++ |
20801 |
++ task->role = role; |
20802 |
++ |
20803 |
++ task->is_writable = 0; |
20804 |
++ |
20805 |
++ /* ignore additional mmap checks for processes that are writable |
20806 |
++ by the default ACL */ |
20807 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); |
20808 |
++ if (unlikely(obj->mode & GR_WRITE)) |
20809 |
++ task->is_writable = 1; |
20810 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label); |
20811 |
++ if (unlikely(obj->mode & GR_WRITE)) |
20812 |
++ task->is_writable = 1; |
20813 |
++ |
20814 |
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG |
20815 |
++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); |
20816 |
++#endif |
20817 |
++ |
20818 |
++ gr_set_proc_res(task); |
20819 |
++ |
20820 |
++ return; |
20821 |
++} |
20822 |
++ |
20823 |
++int |
20824 |
++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt) |
20825 |
++{ |
20826 |
++ struct task_struct *task = current; |
20827 |
++ struct acl_subject_label *newacl; |
20828 |
++ struct acl_object_label *obj; |
20829 |
++ __u32 retmode; |
20830 |
++ |
20831 |
++ if (unlikely(!(gr_status & GR_READY))) |
20832 |
++ return 0; |
20833 |
++ |
20834 |
++ newacl = chk_subj_label(dentry, mnt, task->role); |
20835 |
++ |
20836 |
++ task_lock(task); |
20837 |
++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode & |
20838 |
++ GR_POVERRIDE) && (task->acl != newacl) && |
20839 |
++ !(task->role->roletype & GR_ROLE_GOD) && |
20840 |
++ !gr_search_file(dentry, GR_PTRACERD, mnt) && |
20841 |
++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) || |
20842 |
++ (atomic_read(&task->fs->count) > 1 || |
20843 |
++ atomic_read(&task->files->count) > 1 || |
20844 |
++ atomic_read(&task->sighand->count) > 1)) { |
20845 |
++ task_unlock(task); |
20846 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt); |
20847 |
++ return -EACCES; |
20848 |
++ } |
20849 |
++ task_unlock(task); |
20850 |
++ |
20851 |
++ obj = chk_obj_label(dentry, mnt, task->acl); |
20852 |
++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT); |
20853 |
++ |
20854 |
++ if (!(task->acl->mode & GR_INHERITLEARN) && |
20855 |
++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) { |
20856 |
++ if (obj->nested) |
20857 |
++ task->acl = obj->nested; |
20858 |
++ else |
20859 |
++ task->acl = newacl; |
20860 |
++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT) |
20861 |
++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt); |
20862 |
++ |
20863 |
++ task->is_writable = 0; |
20864 |
++ |
20865 |
++ /* ignore additional mmap checks for processes that are writable |
20866 |
++ by the default ACL */ |
20867 |
++ obj = chk_obj_label(dentry, mnt, default_role->root_label); |
20868 |
++ if (unlikely(obj->mode & GR_WRITE)) |
20869 |
++ task->is_writable = 1; |
20870 |
++ obj = chk_obj_label(dentry, mnt, task->role->root_label); |
20871 |
++ if (unlikely(obj->mode & GR_WRITE)) |
20872 |
++ task->is_writable = 1; |
20873 |
++ |
20874 |
++ gr_set_proc_res(task); |
20875 |
++ |
20876 |
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG |
20877 |
++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); |
20878 |
++#endif |
20879 |
++ return 0; |
20880 |
++} |
20881 |
++ |
20882 |
++/* always called with valid inodev ptr */ |
20883 |
++static void |
20884 |
++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev) |
20885 |
++{ |
20886 |
++ struct acl_object_label *matchpo; |
20887 |
++ struct acl_subject_label *matchps; |
20888 |
++ struct acl_subject_label *subj; |
20889 |
++ struct acl_role_label *role; |
20890 |
++ unsigned int i, x; |
20891 |
++ |
20892 |
++ FOR_EACH_ROLE_START(role, i) |
20893 |
++ FOR_EACH_SUBJECT_START(role, subj, x) |
20894 |
++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL) |
20895 |
++ matchpo->mode |= GR_DELETED; |
20896 |
++ FOR_EACH_SUBJECT_END(subj,x) |
20897 |
++ FOR_EACH_NESTED_SUBJECT_START(role, subj) |
20898 |
++ if (subj->inode == ino && subj->device == dev) |
20899 |
++ subj->mode |= GR_DELETED; |
20900 |
++ FOR_EACH_NESTED_SUBJECT_END(subj) |
20901 |
++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL) |
20902 |
++ matchps->mode |= GR_DELETED; |
20903 |
++ FOR_EACH_ROLE_END(role,i) |
20904 |
++ |
20905 |
++ inodev->nentry->deleted = 1; |
20906 |
++ |
20907 |
++ return; |
20908 |
++} |
20909 |
++ |
20910 |
++void |
20911 |
++gr_handle_delete(const ino_t ino, const dev_t dev) |
20912 |
++{ |
20913 |
++ struct inodev_entry *inodev; |
20914 |
++ |
20915 |
++ if (unlikely(!(gr_status & GR_READY))) |
20916 |
++ return; |
20917 |
++ |
20918 |
++ write_lock(&gr_inode_lock); |
20919 |
++ inodev = lookup_inodev_entry(ino, dev); |
20920 |
++ if (inodev != NULL) |
20921 |
++ do_handle_delete(inodev, ino, dev); |
20922 |
++ write_unlock(&gr_inode_lock); |
20923 |
++ |
20924 |
++ return; |
20925 |
++} |
20926 |
++ |
20927 |
++static void |
20928 |
++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice, |
20929 |
++ const ino_t newinode, const dev_t newdevice, |
20930 |
++ struct acl_subject_label *subj) |
20931 |
++{ |
20932 |
++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size); |
20933 |
++ struct acl_object_label *match; |
20934 |
++ |
20935 |
++ match = subj->obj_hash[index]; |
20936 |
++ |
20937 |
++ while (match && (match->inode != oldinode || |
20938 |
++ match->device != olddevice || |
20939 |
++ !(match->mode & GR_DELETED))) |
20940 |
++ match = match->next; |
20941 |
++ |
20942 |
++ if (match && (match->inode == oldinode) |
20943 |
++ && (match->device == olddevice) |
20944 |
++ && (match->mode & GR_DELETED)) { |
20945 |
++ if (match->prev == NULL) { |
20946 |
++ subj->obj_hash[index] = match->next; |
20947 |
++ if (match->next != NULL) |
20948 |
++ match->next->prev = NULL; |
20949 |
++ } else { |
20950 |
++ match->prev->next = match->next; |
20951 |
++ if (match->next != NULL) |
20952 |
++ match->next->prev = match->prev; |
20953 |
++ } |
20954 |
++ match->prev = NULL; |
20955 |
++ match->next = NULL; |
20956 |
++ match->inode = newinode; |
20957 |
++ match->device = newdevice; |
20958 |
++ match->mode &= ~GR_DELETED; |
20959 |
++ |
20960 |
++ insert_acl_obj_label(match, subj); |
20961 |
++ } |
20962 |
++ |
20963 |
++ return; |
20964 |
++} |
20965 |
++ |
20966 |
++static void |
20967 |
++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice, |
20968 |
++ const ino_t newinode, const dev_t newdevice, |
20969 |
++ struct acl_role_label *role) |
20970 |
++{ |
20971 |
++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size); |
20972 |
++ struct acl_subject_label *match; |
20973 |
++ |
20974 |
++ match = role->subj_hash[index]; |
20975 |
++ |
20976 |
++ while (match && (match->inode != oldinode || |
20977 |
++ match->device != olddevice || |
20978 |
++ !(match->mode & GR_DELETED))) |
20979 |
++ match = match->next; |
20980 |
++ |
20981 |
++ if (match && (match->inode == oldinode) |
20982 |
++ && (match->device == olddevice) |
20983 |
++ && (match->mode & GR_DELETED)) { |
20984 |
++ if (match->prev == NULL) { |
20985 |
++ role->subj_hash[index] = match->next; |
20986 |
++ if (match->next != NULL) |
20987 |
++ match->next->prev = NULL; |
20988 |
++ } else { |
20989 |
++ match->prev->next = match->next; |
20990 |
++ if (match->next != NULL) |
20991 |
++ match->next->prev = match->prev; |
20992 |
++ } |
20993 |
++ match->prev = NULL; |
20994 |
++ match->next = NULL; |
20995 |
++ match->inode = newinode; |
20996 |
++ match->device = newdevice; |
20997 |
++ match->mode &= ~GR_DELETED; |
20998 |
++ |
20999 |
++ insert_acl_subj_label(match, role); |
21000 |
++ } |
21001 |
++ |
21002 |
++ return; |
21003 |
++} |
21004 |
++ |
21005 |
++static void |
21006 |
++update_inodev_entry(const ino_t oldinode, const dev_t olddevice, |
21007 |
++ const ino_t newinode, const dev_t newdevice) |
21008 |
++{ |
21009 |
++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size); |
21010 |
++ struct inodev_entry *match; |
21011 |
++ |
21012 |
++ match = inodev_set.i_hash[index]; |
21013 |
++ |
21014 |
++ while (match && (match->nentry->inode != oldinode || |
21015 |
++ match->nentry->device != olddevice || !match->nentry->deleted)) |
21016 |
++ match = match->next; |
21017 |
++ |
21018 |
++ if (match && (match->nentry->inode == oldinode) |
21019 |
++ && (match->nentry->device == olddevice) && |
21020 |
++ match->nentry->deleted) { |
21021 |
++ if (match->prev == NULL) { |
21022 |
++ inodev_set.i_hash[index] = match->next; |
21023 |
++ if (match->next != NULL) |
21024 |
++ match->next->prev = NULL; |
21025 |
++ } else { |
21026 |
++ match->prev->next = match->next; |
21027 |
++ if (match->next != NULL) |
21028 |
++ match->next->prev = match->prev; |
21029 |
++ } |
21030 |
++ match->prev = NULL; |
21031 |
++ match->next = NULL; |
21032 |
++ match->nentry->inode = newinode; |
21033 |
++ match->nentry->device = newdevice; |
21034 |
++ match->nentry->deleted = 0; |
21035 |
++ |
21036 |
++ insert_inodev_entry(match); |
21037 |
++ } |
21038 |
++ |
21039 |
++ return; |
21040 |
++} |
21041 |
++ |
21042 |
++static void |
21043 |
++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry, |
21044 |
++ const struct vfsmount *mnt) |
21045 |
++{ |
21046 |
++ struct acl_subject_label *subj; |
21047 |
++ struct acl_role_label *role; |
21048 |
++ unsigned int i, x; |
21049 |
++ |
21050 |
++ FOR_EACH_ROLE_START(role, i) |
21051 |
++ update_acl_subj_label(matchn->inode, matchn->device, |
21052 |
++ dentry->d_inode->i_ino, |
21053 |
++ dentry->d_inode->i_sb->s_dev, role); |
21054 |
++ |
21055 |
++ FOR_EACH_NESTED_SUBJECT_START(role, subj) |
21056 |
++ if ((subj->inode == dentry->d_inode->i_ino) && |
21057 |
++ (subj->device == dentry->d_inode->i_sb->s_dev)) { |
21058 |
++ subj->inode = dentry->d_inode->i_ino; |
21059 |
++ subj->device = dentry->d_inode->i_sb->s_dev; |
21060 |
++ } |
21061 |
++ FOR_EACH_NESTED_SUBJECT_END(subj) |
21062 |
++ FOR_EACH_SUBJECT_START(role, subj, x) |
21063 |
++ update_acl_obj_label(matchn->inode, matchn->device, |
21064 |
++ dentry->d_inode->i_ino, |
21065 |
++ dentry->d_inode->i_sb->s_dev, subj); |
21066 |
++ FOR_EACH_SUBJECT_END(subj,x) |
21067 |
++ FOR_EACH_ROLE_END(role,i) |
21068 |
++ |
21069 |
++ update_inodev_entry(matchn->inode, matchn->device, |
21070 |
++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev); |
21071 |
++ |
21072 |
++ return; |
21073 |
++} |
21074 |
++ |
21075 |
++void |
21076 |
++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt) |
21077 |
++{ |
21078 |
++ struct name_entry *matchn; |
21079 |
++ |
21080 |
++ if (unlikely(!(gr_status & GR_READY))) |
21081 |
++ return; |
21082 |
++ |
21083 |
++ preempt_disable(); |
21084 |
++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt)); |
21085 |
++ |
21086 |
++ if (unlikely((unsigned long)matchn)) { |
21087 |
++ write_lock(&gr_inode_lock); |
21088 |
++ do_handle_create(matchn, dentry, mnt); |
21089 |
++ write_unlock(&gr_inode_lock); |
21090 |
++ } |
21091 |
++ preempt_enable(); |
21092 |
++ |
21093 |
++ return; |
21094 |
++} |
21095 |
++ |
21096 |
++void |
21097 |
++gr_handle_rename(struct inode *old_dir, struct inode *new_dir, |
21098 |
++ struct dentry *old_dentry, |
21099 |
++ struct dentry *new_dentry, |
21100 |
++ struct vfsmount *mnt, const __u8 replace) |
21101 |
++{ |
21102 |
++ struct name_entry *matchn; |
21103 |
++ struct inodev_entry *inodev; |
21104 |
++ |
21105 |
++ /* vfs_rename swaps the name and parent link for old_dentry and |
21106 |
++ new_dentry |
21107 |
++ at this point, old_dentry has the new name, parent link, and inode |
21108 |
++ for the renamed file |
21109 |
++ if a file is being replaced by a rename, new_dentry has the inode |
21110 |
++ and name for the replaced file |
21111 |
++ */ |
21112 |
++ |
21113 |
++ if (unlikely(!(gr_status & GR_READY))) |
21114 |
++ return; |
21115 |
++ |
21116 |
++ preempt_disable(); |
21117 |
++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt)); |
21118 |
++ |
21119 |
++ /* we wouldn't have to check d_inode if it weren't for |
21120 |
++ NFS silly-renaming |
21121 |
++ */ |
21122 |
++ |
21123 |
++ write_lock(&gr_inode_lock); |
21124 |
++ if (unlikely(replace && new_dentry->d_inode)) { |
21125 |
++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino, |
21126 |
++ new_dentry->d_inode->i_sb->s_dev); |
21127 |
++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1)) |
21128 |
++ do_handle_delete(inodev, new_dentry->d_inode->i_ino, |
21129 |
++ new_dentry->d_inode->i_sb->s_dev); |
21130 |
++ } |
21131 |
++ |
21132 |
++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino, |
21133 |
++ old_dentry->d_inode->i_sb->s_dev); |
21134 |
++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1)) |
21135 |
++ do_handle_delete(inodev, old_dentry->d_inode->i_ino, |
21136 |
++ old_dentry->d_inode->i_sb->s_dev); |
21137 |
++ |
21138 |
++ if (unlikely((unsigned long)matchn)) |
21139 |
++ do_handle_create(matchn, old_dentry, mnt); |
21140 |
++ |
21141 |
++ write_unlock(&gr_inode_lock); |
21142 |
++ preempt_enable(); |
21143 |
++ |
21144 |
++ return; |
21145 |
++} |
21146 |
++ |
21147 |
++static int |
21148 |
++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt, |
21149 |
++ unsigned char **sum) |
21150 |
++{ |
21151 |
++ struct acl_role_label *r; |
21152 |
++ struct role_allowed_ip *ipp; |
21153 |
++ struct role_transition *trans; |
21154 |
++ unsigned int i; |
21155 |
++ int found = 0; |
21156 |
++ |
21157 |
++ /* check transition table */ |
21158 |
++ |
21159 |
++ for (trans = current->role->transitions; trans; trans = trans->next) { |
21160 |
++ if (!strcmp(rolename, trans->rolename)) { |
21161 |
++ found = 1; |
21162 |
++ break; |
21163 |
++ } |
21164 |
++ } |
21165 |
++ |
21166 |
++ if (!found) |
21167 |
++ return 0; |
21168 |
++ |
21169 |
++ /* handle special roles that do not require authentication |
21170 |
++ and check ip */ |
21171 |
++ |
21172 |
++ FOR_EACH_ROLE_START(r, i) |
21173 |
++ if (!strcmp(rolename, r->rolename) && |
21174 |
++ (r->roletype & GR_ROLE_SPECIAL)) { |
21175 |
++ found = 0; |
21176 |
++ if (r->allowed_ips != NULL) { |
21177 |
++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) { |
21178 |
++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) == |
21179 |
++ (ntohl(ipp->addr) & ipp->netmask)) |
21180 |
++ found = 1; |
21181 |
++ } |
21182 |
++ } else |
21183 |
++ found = 2; |
21184 |
++ if (!found) |
21185 |
++ return 0; |
21186 |
++ |
21187 |
++ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) || |
21188 |
++ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) { |
21189 |
++ *salt = NULL; |
21190 |
++ *sum = NULL; |
21191 |
++ return 1; |
21192 |
++ } |
21193 |
++ } |
21194 |
++ FOR_EACH_ROLE_END(r,i) |
21195 |
++ |
21196 |
++ for (i = 0; i < num_sprole_pws; i++) { |
21197 |
++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) { |
21198 |
++ *salt = acl_special_roles[i]->salt; |
21199 |
++ *sum = acl_special_roles[i]->sum; |
21200 |
++ return 1; |
21201 |
++ } |
21202 |
++ } |
21203 |
++ |
21204 |
++ return 0; |
21205 |
++} |
21206 |
++ |
21207 |
++static void |
21208 |
++assign_special_role(char *rolename) |
21209 |
++{ |
21210 |
++ struct acl_object_label *obj; |
21211 |
++ struct acl_role_label *r; |
21212 |
++ struct acl_role_label *assigned = NULL; |
21213 |
++ struct task_struct *tsk; |
21214 |
++ struct file *filp; |
21215 |
++ unsigned int i; |
21216 |
++ |
21217 |
++ FOR_EACH_ROLE_START(r, i) |
21218 |
++ if (!strcmp(rolename, r->rolename) && |
21219 |
++ (r->roletype & GR_ROLE_SPECIAL)) |
21220 |
++ assigned = r; |
21221 |
++ FOR_EACH_ROLE_END(r,i) |
21222 |
++ |
21223 |
++ if (!assigned) |
21224 |
++ return; |
21225 |
++ |
21226 |
++ read_lock(&tasklist_lock); |
21227 |
++ read_lock(&grsec_exec_file_lock); |
21228 |
++ |
21229 |
++ tsk = current->parent; |
21230 |
++ if (tsk == NULL) |
21231 |
++ goto out_unlock; |
21232 |
++ |
21233 |
++ filp = tsk->exec_file; |
21234 |
++ if (filp == NULL) |
21235 |
++ goto out_unlock; |
21236 |
++ |
21237 |
++ tsk->is_writable = 0; |
21238 |
++ |
21239 |
++ tsk->acl_sp_role = 1; |
21240 |
++ tsk->acl_role_id = ++acl_sp_role_value; |
21241 |
++ tsk->role = assigned; |
21242 |
++ tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role); |
21243 |
++ |
21244 |
++ /* ignore additional mmap checks for processes that are writable |
21245 |
++ by the default ACL */ |
21246 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); |
21247 |
++ if (unlikely(obj->mode & GR_WRITE)) |
21248 |
++ tsk->is_writable = 1; |
21249 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label); |
21250 |
++ if (unlikely(obj->mode & GR_WRITE)) |
21251 |
++ tsk->is_writable = 1; |
21252 |
++ |
21253 |
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG |
21254 |
++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid); |
21255 |
++#endif |
21256 |
++ |
21257 |
++out_unlock: |
21258 |
++ read_unlock(&grsec_exec_file_lock); |
21259 |
++ read_unlock(&tasklist_lock); |
21260 |
++ return; |
21261 |
++} |
21262 |
++ |
21263 |
++int gr_check_secure_terminal(struct task_struct *task) |
21264 |
++{ |
21265 |
++ struct task_struct *p, *p2, *p3; |
21266 |
++ struct files_struct *files; |
21267 |
++ struct fdtable *fdt; |
21268 |
++ struct file *our_file = NULL, *file; |
21269 |
++ int i; |
21270 |
++ |
21271 |
++ if (task->signal->tty == NULL) |
21272 |
++ return 1; |
21273 |
++ |
21274 |
++ files = get_files_struct(task); |
21275 |
++ if (files != NULL) { |
21276 |
++ rcu_read_lock(); |
21277 |
++ fdt = files_fdtable(files); |
21278 |
++ for (i=0; i < fdt->max_fds; i++) { |
21279 |
++ file = fcheck_files(files, i); |
21280 |
++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) { |
21281 |
++ get_file(file); |
21282 |
++ our_file = file; |
21283 |
++ } |
21284 |
++ } |
21285 |
++ rcu_read_unlock(); |
21286 |
++ put_files_struct(files); |
21287 |
++ } |
21288 |
++ |
21289 |
++ if (our_file == NULL) |
21290 |
++ return 1; |
21291 |
++ |
21292 |
++ read_lock(&tasklist_lock); |
21293 |
++ do_each_thread(p2, p) { |
21294 |
++ files = get_files_struct(p); |
21295 |
++ if (files == NULL || |
21296 |
++ (p->signal && p->signal->tty == task->signal->tty)) { |
21297 |
++ if (files != NULL) |
21298 |
++ put_files_struct(files); |
21299 |
++ continue; |
21300 |
++ } |
21301 |
++ rcu_read_lock(); |
21302 |
++ fdt = files_fdtable(files); |
21303 |
++ for (i=0; i < fdt->max_fds; i++) { |
21304 |
++ file = fcheck_files(files, i); |
21305 |
++ if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) && |
21306 |
++ file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) { |
21307 |
++ p3 = task; |
21308 |
++ while (p3->pid > 0) { |
21309 |
++ if (p3 == p) |
21310 |
++ break; |
21311 |
++ p3 = p3->parent; |
21312 |
++ } |
21313 |
++ if (p3 == p) |
21314 |
++ break; |
21315 |
++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p); |
21316 |
++ gr_handle_alertkill(p); |
21317 |
++ rcu_read_unlock(); |
21318 |
++ put_files_struct(files); |
21319 |
++ read_unlock(&tasklist_lock); |
21320 |
++ fput(our_file); |
21321 |
++ return 0; |
21322 |
++ } |
21323 |
++ } |
21324 |
++ rcu_read_unlock(); |
21325 |
++ put_files_struct(files); |
21326 |
++ } while_each_thread(p2, p); |
21327 |
++ read_unlock(&tasklist_lock); |
21328 |
++ |
21329 |
++ fput(our_file); |
21330 |
++ return 1; |
21331 |
++} |
21332 |
++ |
21333 |
++ssize_t |
21334 |
++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos) |
21335 |
++{ |
21336 |
++ struct gr_arg_wrapper uwrap; |
21337 |
++ unsigned char *sprole_salt; |
21338 |
++ unsigned char *sprole_sum; |
21339 |
++ int error = sizeof (struct gr_arg_wrapper); |
21340 |
++ int error2 = 0; |
21341 |
++ |
21342 |
++ down(&gr_dev_sem); |
21343 |
++ |
21344 |
++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) { |
21345 |
++ error = -EPERM; |
21346 |
++ goto out; |
21347 |
++ } |
21348 |
++ |
21349 |
++ if (count != sizeof (struct gr_arg_wrapper)) { |
21350 |
++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper)); |
21351 |
++ error = -EINVAL; |
21352 |
++ goto out; |
21353 |
++ } |
21354 |
++ |
21355 |
++ |
21356 |
++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) { |
21357 |
++ gr_auth_expires = 0; |
21358 |
++ gr_auth_attempts = 0; |
21359 |
++ } |
21360 |
++ |
21361 |
++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) { |
21362 |
++ error = -EFAULT; |
21363 |
++ goto out; |
21364 |
++ } |
21365 |
++ |
21366 |
++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) { |
21367 |
++ error = -EINVAL; |
21368 |
++ goto out; |
21369 |
++ } |
21370 |
++ |
21371 |
++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) { |
21372 |
++ error = -EFAULT; |
21373 |
++ goto out; |
21374 |
++ } |
21375 |
++ |
21376 |
++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM && |
21377 |
++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES && |
21378 |
++ time_after(gr_auth_expires, get_seconds())) { |
21379 |
++ error = -EBUSY; |
21380 |
++ goto out; |
21381 |
++ } |
21382 |
++ |
21383 |
++ /* if non-root trying to do anything other than use a special role, |
21384 |
++ do not attempt authentication, do not count towards authentication |
21385 |
++ locking |
21386 |
++ */ |
21387 |
++ |
21388 |
++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS && |
21389 |
++ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM && |
21390 |
++ current->uid) { |
21391 |
++ error = -EPERM; |
21392 |
++ goto out; |
21393 |
++ } |
21394 |
++ |
21395 |
++ /* ensure pw and special role name are null terminated */ |
21396 |
++ |
21397 |
++ gr_usermode->pw[GR_PW_LEN - 1] = '\0'; |
21398 |
++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0'; |
21399 |
++ |
21400 |
++ /* Okay. |
21401 |
++ * We have our enough of the argument structure..(we have yet |
21402 |
++ * to copy_from_user the tables themselves) . Copy the tables |
21403 |
++ * only if we need them, i.e. for loading operations. */ |
21404 |
++ |
21405 |
++ switch (gr_usermode->mode) { |
21406 |
++ case STATUS: |
21407 |
++ if (gr_status & GR_READY) { |
21408 |
++ error = 1; |
21409 |
++ if (!gr_check_secure_terminal(current)) |
21410 |
++ error = 3; |
21411 |
++ } else |
21412 |
++ error = 2; |
21413 |
++ goto out; |
21414 |
++ case SHUTDOWN: |
21415 |
++ if ((gr_status & GR_READY) |
21416 |
++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { |
21417 |
++ gr_status &= ~GR_READY; |
21418 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG); |
21419 |
++ free_variables(); |
21420 |
++ memset(gr_usermode, 0, sizeof (struct gr_arg)); |
21421 |
++ memset(gr_system_salt, 0, GR_SALT_LEN); |
21422 |
++ memset(gr_system_sum, 0, GR_SHA_LEN); |
21423 |
++ } else if (gr_status & GR_READY) { |
21424 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG); |
21425 |
++ error = -EPERM; |
21426 |
++ } else { |
21427 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG); |
21428 |
++ error = -EAGAIN; |
21429 |
++ } |
21430 |
++ break; |
21431 |
++ case ENABLE: |
21432 |
++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode))) |
21433 |
++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION); |
21434 |
++ else { |
21435 |
++ if (gr_status & GR_READY) |
21436 |
++ error = -EAGAIN; |
21437 |
++ else |
21438 |
++ error = error2; |
21439 |
++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION); |
21440 |
++ } |
21441 |
++ break; |
21442 |
++ case RELOAD: |
21443 |
++ if (!(gr_status & GR_READY)) { |
21444 |
++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION); |
21445 |
++ error = -EAGAIN; |
21446 |
++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { |
21447 |
++ lock_kernel(); |
21448 |
++ gr_status &= ~GR_READY; |
21449 |
++ free_variables(); |
21450 |
++ if (!(error2 = gracl_init(gr_usermode))) { |
21451 |
++ unlock_kernel(); |
21452 |
++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION); |
21453 |
++ } else { |
21454 |
++ unlock_kernel(); |
21455 |
++ error = error2; |
21456 |
++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION); |
21457 |
++ } |
21458 |
++ } else { |
21459 |
++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION); |
21460 |
++ error = -EPERM; |
21461 |
++ } |
21462 |
++ break; |
21463 |
++ case SEGVMOD: |
21464 |
++ if (unlikely(!(gr_status & GR_READY))) { |
21465 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG); |
21466 |
++ error = -EAGAIN; |
21467 |
++ break; |
21468 |
++ } |
21469 |
++ |
21470 |
++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { |
21471 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG); |
21472 |
++ if (gr_usermode->segv_device && gr_usermode->segv_inode) { |
21473 |
++ struct acl_subject_label *segvacl; |
21474 |
++ segvacl = |
21475 |
++ lookup_acl_subj_label(gr_usermode->segv_inode, |
21476 |
++ gr_usermode->segv_device, |
21477 |
++ current->role); |
21478 |
++ if (segvacl) { |
21479 |
++ segvacl->crashes = 0; |
21480 |
++ segvacl->expires = 0; |
21481 |
++ } |
21482 |
++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) { |
21483 |
++ gr_remove_uid(gr_usermode->segv_uid); |
21484 |
++ } |
21485 |
++ } else { |
21486 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG); |
21487 |
++ error = -EPERM; |
21488 |
++ } |
21489 |
++ break; |
21490 |
++ case SPROLE: |
21491 |
++ case SPROLEPAM: |
21492 |
++ if (unlikely(!(gr_status & GR_READY))) { |
21493 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG); |
21494 |
++ error = -EAGAIN; |
21495 |
++ break; |
21496 |
++ } |
21497 |
++ |
21498 |
++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) { |
21499 |
++ current->role->expires = 0; |
21500 |
++ current->role->auth_attempts = 0; |
21501 |
++ } |
21502 |
++ |
21503 |
++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES && |
21504 |
++ time_after(current->role->expires, get_seconds())) { |
21505 |
++ error = -EBUSY; |
21506 |
++ goto out; |
21507 |
++ } |
21508 |
++ |
21509 |
++ if (lookup_special_role_auth |
21510 |
++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum) |
21511 |
++ && ((!sprole_salt && !sprole_sum) |
21512 |
++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) { |
21513 |
++ char *p = ""; |
21514 |
++ assign_special_role(gr_usermode->sp_role); |
21515 |
++ read_lock(&tasklist_lock); |
21516 |
++ if (current->parent) |
21517 |
++ p = current->parent->role->rolename; |
21518 |
++ read_unlock(&tasklist_lock); |
21519 |
++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG, |
21520 |
++ p, acl_sp_role_value); |
21521 |
++ } else { |
21522 |
++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role); |
21523 |
++ error = -EPERM; |
21524 |
++ if(!(current->role->auth_attempts++)) |
21525 |
++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT; |
21526 |
++ |
21527 |
++ goto out; |
21528 |
++ } |
21529 |
++ break; |
21530 |
++ case UNSPROLE: |
21531 |
++ if (unlikely(!(gr_status & GR_READY))) { |
21532 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG); |
21533 |
++ error = -EAGAIN; |
21534 |
++ break; |
21535 |
++ } |
21536 |
++ |
21537 |
++ if (current->role->roletype & GR_ROLE_SPECIAL) { |
21538 |
++ char *p = ""; |
21539 |
++ int i = 0; |
21540 |
++ |
21541 |
++ read_lock(&tasklist_lock); |
21542 |
++ if (current->parent) { |
21543 |
++ p = current->parent->role->rolename; |
21544 |
++ i = current->parent->acl_role_id; |
21545 |
++ } |
21546 |
++ read_unlock(&tasklist_lock); |
21547 |
++ |
21548 |
++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i); |
21549 |
++ gr_set_acls(1); |
21550 |
++ } else { |
21551 |
++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename); |
21552 |
++ error = -EPERM; |
21553 |
++ goto out; |
21554 |
++ } |
21555 |
++ break; |
21556 |
++ default: |
21557 |
++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode); |
21558 |
++ error = -EINVAL; |
21559 |
++ break; |
21560 |
++ } |
21561 |
++ |
21562 |
++ if (error != -EPERM) |
21563 |
++ goto out; |
21564 |
++ |
21565 |
++ if(!(gr_auth_attempts++)) |
21566 |
++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT; |
21567 |
++ |
21568 |
++ out: |
21569 |
++ up(&gr_dev_sem); |
21570 |
++ return error; |
21571 |
++} |
21572 |
++ |
21573 |
++int |
21574 |
++gr_set_acls(const int type) |
21575 |
++{ |
21576 |
++ struct acl_object_label *obj; |
21577 |
++ struct task_struct *task, *task2; |
21578 |
++ struct file *filp; |
21579 |
++ struct acl_role_label *role = current->role; |
21580 |
++ __u16 acl_role_id = current->acl_role_id; |
21581 |
++ |
21582 |
++ read_lock(&tasklist_lock); |
21583 |
++ read_lock(&grsec_exec_file_lock); |
21584 |
++ do_each_thread(task2, task) { |
21585 |
++ /* check to see if we're called from the exit handler, |
21586 |
++ if so, only replace ACLs that have inherited the admin |
21587 |
++ ACL */ |
21588 |
++ |
21589 |
++ if (type && (task->role != role || |
21590 |
++ task->acl_role_id != acl_role_id)) |
21591 |
++ continue; |
21592 |
++ |
21593 |
++ task->acl_role_id = 0; |
21594 |
++ task->acl_sp_role = 0; |
21595 |
++ |
21596 |
++ if ((filp = task->exec_file)) { |
21597 |
++ task->role = lookup_acl_role_label(task, task->uid, task->gid); |
21598 |
++ |
21599 |
++ task->acl = |
21600 |
++ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, |
21601 |
++ task->role); |
21602 |
++ if (task->acl) { |
21603 |
++ struct acl_subject_label *curr; |
21604 |
++ curr = task->acl; |
21605 |
++ |
21606 |
++ task->is_writable = 0; |
21607 |
++ /* ignore additional mmap checks for processes that are writable |
21608 |
++ by the default ACL */ |
21609 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); |
21610 |
++ if (unlikely(obj->mode & GR_WRITE)) |
21611 |
++ task->is_writable = 1; |
21612 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label); |
21613 |
++ if (unlikely(obj->mode & GR_WRITE)) |
21614 |
++ task->is_writable = 1; |
21615 |
++ |
21616 |
++ gr_set_proc_res(task); |
21617 |
++ |
21618 |
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG |
21619 |
++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); |
21620 |
++#endif |
21621 |
++ } else { |
21622 |
++ read_unlock(&grsec_exec_file_lock); |
21623 |
++ read_unlock(&tasklist_lock); |
21624 |
++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid); |
21625 |
++ return 1; |
21626 |
++ } |
21627 |
++ } else { |
21628 |
++ // it's a kernel process |
21629 |
++ task->role = kernel_role; |
21630 |
++ task->acl = kernel_role->root_label; |
21631 |
++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN |
21632 |
++ task->acl->mode &= ~GR_PROCFIND; |
21633 |
++#endif |
21634 |
++ } |
21635 |
++ } while_each_thread(task2, task); |
21636 |
++ read_unlock(&grsec_exec_file_lock); |
21637 |
++ read_unlock(&tasklist_lock); |
21638 |
++ return 0; |
21639 |
++} |
21640 |
++ |
21641 |
++void |
21642 |
++gr_learn_resource(const struct task_struct *task, |
21643 |
++ const int res, const unsigned long wanted, const int gt) |
21644 |
++{ |
21645 |
++ struct acl_subject_label *acl; |
21646 |
++ |
21647 |
++ if (unlikely((gr_status & GR_READY) && |
21648 |
++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN)))) |
21649 |
++ goto skip_reslog; |
21650 |
++ |
21651 |
++#ifdef CONFIG_GRKERNSEC_RESLOG |
21652 |
++ gr_log_resource(task, res, wanted, gt); |
21653 |
++#endif |
21654 |
++ skip_reslog: |
21655 |
++ |
21656 |
++ if (unlikely(!(gr_status & GR_READY) || !wanted)) |
21657 |
++ return; |
21658 |
++ |
21659 |
++ acl = task->acl; |
21660 |
++ |
21661 |
++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) || |
21662 |
++ !(acl->resmask & (1 << (unsigned short) res)))) |
21663 |
++ return; |
21664 |
++ |
21665 |
++ if (wanted >= acl->res[res].rlim_cur) { |
21666 |
++ unsigned long res_add; |
21667 |
++ |
21668 |
++ res_add = wanted; |
21669 |
++ switch (res) { |
21670 |
++ case RLIMIT_CPU: |
21671 |
++ res_add += GR_RLIM_CPU_BUMP; |
21672 |
++ break; |
21673 |
++ case RLIMIT_FSIZE: |
21674 |
++ res_add += GR_RLIM_FSIZE_BUMP; |
21675 |
++ break; |
21676 |
++ case RLIMIT_DATA: |
21677 |
++ res_add += GR_RLIM_DATA_BUMP; |
21678 |
++ break; |
21679 |
++ case RLIMIT_STACK: |
21680 |
++ res_add += GR_RLIM_STACK_BUMP; |
21681 |
++ break; |
21682 |
++ case RLIMIT_CORE: |
21683 |
++ res_add += GR_RLIM_CORE_BUMP; |
21684 |
++ break; |
21685 |
++ case RLIMIT_RSS: |
21686 |
++ res_add += GR_RLIM_RSS_BUMP; |
21687 |
++ break; |
21688 |
++ case RLIMIT_NPROC: |
21689 |
++ res_add += GR_RLIM_NPROC_BUMP; |
21690 |
++ break; |
21691 |
++ case RLIMIT_NOFILE: |
21692 |
++ res_add += GR_RLIM_NOFILE_BUMP; |
21693 |
++ break; |
21694 |
++ case RLIMIT_MEMLOCK: |
21695 |
++ res_add += GR_RLIM_MEMLOCK_BUMP; |
21696 |
++ break; |
21697 |
++ case RLIMIT_AS: |
21698 |
++ res_add += GR_RLIM_AS_BUMP; |
21699 |
++ break; |
21700 |
++ case RLIMIT_LOCKS: |
21701 |
++ res_add += GR_RLIM_LOCKS_BUMP; |
21702 |
++ break; |
21703 |
++ } |
21704 |
++ |
21705 |
++ acl->res[res].rlim_cur = res_add; |
21706 |
++ |
21707 |
++ if (wanted > acl->res[res].rlim_max) |
21708 |
++ acl->res[res].rlim_max = res_add; |
21709 |
++ |
21710 |
++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, |
21711 |
++ task->role->roletype, acl->filename, |
21712 |
++ acl->res[res].rlim_cur, acl->res[res].rlim_max, |
21713 |
++ "", (unsigned long) res); |
21714 |
++ } |
21715 |
++ |
21716 |
++ return; |
21717 |
++} |
21718 |
++ |
21719 |
++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS |
21720 |
++void |
21721 |
++pax_set_initial_flags(struct linux_binprm *bprm) |
21722 |
++{ |
21723 |
++ struct task_struct *task = current; |
21724 |
++ struct acl_subject_label *proc; |
21725 |
++ unsigned long flags; |
21726 |
++ |
21727 |
++ if (unlikely(!(gr_status & GR_READY))) |
21728 |
++ return; |
21729 |
++ |
21730 |
++ flags = pax_get_flags(task); |
21731 |
++ |
21732 |
++ proc = task->acl; |
21733 |
++ |
21734 |
++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC) |
21735 |
++ flags &= ~MF_PAX_PAGEEXEC; |
21736 |
++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC) |
21737 |
++ flags &= ~MF_PAX_SEGMEXEC; |
21738 |
++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP) |
21739 |
++ flags &= ~MF_PAX_RANDMMAP; |
21740 |
++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP) |
21741 |
++ flags &= ~MF_PAX_EMUTRAMP; |
21742 |
++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT) |
21743 |
++ flags &= ~MF_PAX_MPROTECT; |
21744 |
++ |
21745 |
++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC) |
21746 |
++ flags |= MF_PAX_PAGEEXEC; |
21747 |
++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC) |
21748 |
++ flags |= MF_PAX_SEGMEXEC; |
21749 |
++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP) |
21750 |
++ flags |= MF_PAX_RANDMMAP; |
21751 |
++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP) |
21752 |
++ flags |= MF_PAX_EMUTRAMP; |
21753 |
++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT) |
21754 |
++ flags |= MF_PAX_MPROTECT; |
21755 |
++ |
21756 |
++ pax_set_flags(task, flags); |
21757 |
++ |
21758 |
++ return; |
21759 |
++} |
21760 |
++#endif |
21761 |
++ |
21762 |
++#ifdef CONFIG_SYSCTL |
21763 |
++/* Eric Biederman likes breaking userland ABI and every inode-based security |
21764 |
++ system to save 35kb of memory */ |
21765 |
++ |
21766 |
++/* we modify the passed in filename, but adjust it back before returning */ |
21767 |
++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len) |
21768 |
++{ |
21769 |
++ struct name_entry *nmatch; |
21770 |
++ char *p, *lastp = NULL; |
21771 |
++ struct acl_object_label *obj = NULL, *tmp; |
21772 |
++ struct acl_subject_label *tmpsubj; |
21773 |
++ char c = '\0'; |
21774 |
++ |
21775 |
++ read_lock(&gr_inode_lock); |
21776 |
++ |
21777 |
++ p = name + len - 1; |
21778 |
++ do { |
21779 |
++ nmatch = lookup_name_entry(name); |
21780 |
++ if (lastp != NULL) |
21781 |
++ *lastp = c; |
21782 |
++ |
21783 |
++ if (nmatch == NULL) |
21784 |
++ goto next_component; |
21785 |
++ tmpsubj = current->acl; |
21786 |
++ do { |
21787 |
++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj); |
21788 |
++ if (obj != NULL) { |
21789 |
++ tmp = obj->globbed; |
21790 |
++ while (tmp) { |
21791 |
++ if (!glob_match(tmp->filename, name)) { |
21792 |
++ obj = tmp; |
21793 |
++ goto found_obj; |
21794 |
++ } |
21795 |
++ tmp = tmp->next; |
21796 |
++ } |
21797 |
++ goto found_obj; |
21798 |
++ } |
21799 |
++ } while ((tmpsubj = tmpsubj->parent_subject)); |
21800 |
++next_component: |
21801 |
++ /* end case */ |
21802 |
++ if (p == name) |
21803 |
++ break; |
21804 |
++ |
21805 |
++ while (*p != '/') |
21806 |
++ p--; |
21807 |
++ if (p == name) |
21808 |
++ lastp = p + 1; |
21809 |
++ else { |
21810 |
++ lastp = p; |
21811 |
++ p--; |
21812 |
++ } |
21813 |
++ c = *lastp; |
21814 |
++ *lastp = '\0'; |
21815 |
++ } while (1); |
21816 |
++found_obj: |
21817 |
++ read_unlock(&gr_inode_lock); |
21818 |
++ /* obj returned will always be non-null */ |
21819 |
++ return obj; |
21820 |
++} |
21821 |
++ |
21822 |
++/* returns 0 when allowing, non-zero on error |
21823 |
++ op of 0 is used for readdir, so we don't log the names of hidden files |
21824 |
++*/ |
21825 |
++__u32 |
21826 |
++gr_handle_sysctl(const struct ctl_table *table, const int op) |
21827 |
++{ |
21828 |
++ ctl_table *tmp; |
21829 |
++ const char *proc_sys = "/proc/sys"; |
21830 |
++ char *path; |
21831 |
++ struct acl_object_label *obj; |
21832 |
++ unsigned short len = 0, pos = 0, depth = 0, i; |
21833 |
++ __u32 err = 0; |
21834 |
++ __u32 mode = 0; |
21835 |
++ |
21836 |
++ if (unlikely(!(gr_status & GR_READY))) |
21837 |
++ return 0; |
21838 |
++ |
21839 |
++ /* for now, ignore operations on non-sysctl entries if it's not a |
21840 |
++ readdir*/ |
21841 |
++ if (table->child != NULL && op != 0) |
21842 |
++ return 0; |
21843 |
++ |
21844 |
++ mode |= GR_FIND; |
21845 |
++ /* it's only a read if it's an entry, read on dirs is for readdir */ |
21846 |
++ if (op & 004) |
21847 |
++ mode |= GR_READ; |
21848 |
++ if (op & 002) |
21849 |
++ mode |= GR_WRITE; |
21850 |
++ |
21851 |
++ preempt_disable(); |
21852 |
++ |
21853 |
++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id()); |
21854 |
++ |
21855 |
++ /* it's only a read/write if it's an actual entry, not a dir |
21856 |
++ (which are opened for readdir) |
21857 |
++ */ |
21858 |
++ |
21859 |
++ /* convert the requested sysctl entry into a pathname */ |
21860 |
++ |
21861 |
++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) { |
21862 |
++ len += strlen(tmp->procname); |
21863 |
++ len++; |
21864 |
++ depth++; |
21865 |
++ } |
21866 |
++ |
21867 |
++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) { |
21868 |
++ /* deny */ |
21869 |
++ goto out; |
21870 |
++ } |
21871 |
++ |
21872 |
++ memset(path, 0, PAGE_SIZE); |
21873 |
++ |
21874 |
++ memcpy(path, proc_sys, strlen(proc_sys)); |
21875 |
++ |
21876 |
++ pos += strlen(proc_sys); |
21877 |
++ |
21878 |
++ for (; depth > 0; depth--) { |
21879 |
++ path[pos] = '/'; |
21880 |
++ pos++; |
21881 |
++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) { |
21882 |
++ if (depth == i) { |
21883 |
++ memcpy(path + pos, tmp->procname, |
21884 |
++ strlen(tmp->procname)); |
21885 |
++ pos += strlen(tmp->procname); |
21886 |
++ } |
21887 |
++ i++; |
21888 |
++ } |
21889 |
++ } |
21890 |
++ |
21891 |
++ obj = gr_lookup_by_name(path, pos); |
21892 |
++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS); |
21893 |
++ |
21894 |
++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) && |
21895 |
++ ((err & mode) != mode))) { |
21896 |
++ __u32 new_mode = mode; |
21897 |
++ |
21898 |
++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); |
21899 |
++ |
21900 |
++ err = 0; |
21901 |
++ gr_log_learn_sysctl(current, path, new_mode); |
21902 |
++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) { |
21903 |
++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path); |
21904 |
++ err = -ENOENT; |
21905 |
++ } else if (!(err & GR_FIND)) { |
21906 |
++ err = -ENOENT; |
21907 |
++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) { |
21908 |
++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied", |
21909 |
++ path, (mode & GR_READ) ? " reading" : "", |
21910 |
++ (mode & GR_WRITE) ? " writing" : ""); |
21911 |
++ err = -EACCES; |
21912 |
++ } else if ((err & mode) != mode) { |
21913 |
++ err = -EACCES; |
21914 |
++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) { |
21915 |
++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful", |
21916 |
++ path, (mode & GR_READ) ? " reading" : "", |
21917 |
++ (mode & GR_WRITE) ? " writing" : ""); |
21918 |
++ err = 0; |
21919 |
++ } else |
21920 |
++ err = 0; |
21921 |
++ |
21922 |
++ out: |
21923 |
++ preempt_enable(); |
21924 |
++ |
21925 |
++ return err; |
21926 |
++} |
21927 |
++#endif |
21928 |
++ |
21929 |
++int |
21930 |
++gr_handle_proc_ptrace(struct task_struct *task) |
21931 |
++{ |
21932 |
++ struct file *filp; |
21933 |
++ struct task_struct *tmp = task; |
21934 |
++ struct task_struct *curtemp = current; |
21935 |
++ __u32 retmode; |
21936 |
++ |
21937 |
++ if (unlikely(!(gr_status & GR_READY))) |
21938 |
++ return 0; |
21939 |
++ |
21940 |
++ read_lock(&tasklist_lock); |
21941 |
++ read_lock(&grsec_exec_file_lock); |
21942 |
++ filp = task->exec_file; |
21943 |
++ |
21944 |
++ while (tmp->pid > 0) { |
21945 |
++ if (tmp == curtemp) |
21946 |
++ break; |
21947 |
++ tmp = tmp->parent; |
21948 |
++ } |
21949 |
++ |
21950 |
++ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) { |
21951 |
++ read_unlock(&grsec_exec_file_lock); |
21952 |
++ read_unlock(&tasklist_lock); |
21953 |
++ return 1; |
21954 |
++ } |
21955 |
++ |
21956 |
++ retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt); |
21957 |
++ read_unlock(&grsec_exec_file_lock); |
21958 |
++ read_unlock(&tasklist_lock); |
21959 |
++ |
21960 |
++ if (retmode & GR_NOPTRACE) |
21961 |
++ return 1; |
21962 |
++ |
21963 |
++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD) |
21964 |
++ && (current->acl != task->acl || (current->acl != current->role->root_label |
21965 |
++ && current->pid != task->pid))) |
21966 |
++ return 1; |
21967 |
++ |
21968 |
++ return 0; |
21969 |
++} |
21970 |
++ |
21971 |
++int |
21972 |
++gr_handle_ptrace(struct task_struct *task, const long request) |
21973 |
++{ |
21974 |
++ struct task_struct *tmp = task; |
21975 |
++ struct task_struct *curtemp = current; |
21976 |
++ __u32 retmode; |
21977 |
++ |
21978 |
++ if (unlikely(!(gr_status & GR_READY))) |
21979 |
++ return 0; |
21980 |
++ |
21981 |
++ read_lock(&tasklist_lock); |
21982 |
++ while (tmp->pid > 0) { |
21983 |
++ if (tmp == curtemp) |
21984 |
++ break; |
21985 |
++ tmp = tmp->parent; |
21986 |
++ } |
21987 |
++ |
21988 |
++ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) { |
21989 |
++ read_unlock(&tasklist_lock); |
21990 |
++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task); |
21991 |
++ return 1; |
21992 |
++ } |
21993 |
++ read_unlock(&tasklist_lock); |
21994 |
++ |
21995 |
++ read_lock(&grsec_exec_file_lock); |
21996 |
++ if (unlikely(!task->exec_file)) { |
21997 |
++ read_unlock(&grsec_exec_file_lock); |
21998 |
++ return 0; |
21999 |
++ } |
22000 |
++ |
22001 |
++ retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt); |
22002 |
++ read_unlock(&grsec_exec_file_lock); |
22003 |
++ |
22004 |
++ if (retmode & GR_NOPTRACE) { |
22005 |
++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task); |
22006 |
++ return 1; |
22007 |
++ } |
22008 |
++ |
22009 |
++ if (retmode & GR_PTRACERD) { |
22010 |
++ switch (request) { |
22011 |
++ case PTRACE_POKETEXT: |
22012 |
++ case PTRACE_POKEDATA: |
22013 |
++ case PTRACE_POKEUSR: |
22014 |
++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64) |
22015 |
++ case PTRACE_SETREGS: |
22016 |
++ case PTRACE_SETFPREGS: |
22017 |
++#endif |
22018 |
++#ifdef CONFIG_X86 |
22019 |
++ case PTRACE_SETFPXREGS: |
22020 |
++#endif |
22021 |
++#ifdef CONFIG_ALTIVEC |
22022 |
++ case PTRACE_SETVRREGS: |
22023 |
++#endif |
22024 |
++ return 1; |
22025 |
++ default: |
22026 |
++ return 0; |
22027 |
++ } |
22028 |
++ } else if (!(current->acl->mode & GR_POVERRIDE) && |
22029 |
++ !(current->role->roletype & GR_ROLE_GOD) && |
22030 |
++ (current->acl != task->acl)) { |
22031 |
++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task); |
22032 |
++ return 1; |
22033 |
++ } |
22034 |
++ |
22035 |
++ return 0; |
22036 |
++} |
22037 |
++ |
22038 |
++static int is_writable_mmap(const struct file *filp) |
22039 |
++{ |
22040 |
++ struct task_struct *task = current; |
22041 |
++ struct acl_object_label *obj, *obj2; |
22042 |
++ |
22043 |
++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) && |
22044 |
++ !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) { |
22045 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); |
22046 |
++ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, |
22047 |
++ task->role->root_label); |
22048 |
++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) { |
22049 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt); |
22050 |
++ return 1; |
22051 |
++ } |
22052 |
++ } |
22053 |
++ return 0; |
22054 |
++} |
22055 |
++ |
22056 |
++int |
22057 |
++gr_acl_handle_mmap(const struct file *file, const unsigned long prot) |
22058 |
++{ |
22059 |
++ __u32 mode; |
22060 |
++ |
22061 |
++ if (unlikely(!file || !(prot & PROT_EXEC))) |
22062 |
++ return 1; |
22063 |
++ |
22064 |
++ if (is_writable_mmap(file)) |
22065 |
++ return 0; |
22066 |
++ |
22067 |
++ mode = |
22068 |
++ gr_search_file(file->f_dentry, |
22069 |
++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS, |
22070 |
++ file->f_vfsmnt); |
22071 |
++ |
22072 |
++ if (!gr_tpe_allow(file)) |
22073 |
++ return 0; |
22074 |
++ |
22075 |
++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) { |
22076 |
++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt); |
22077 |
++ return 0; |
22078 |
++ } else if (unlikely(!(mode & GR_EXEC))) { |
22079 |
++ return 0; |
22080 |
++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) { |
22081 |
++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt); |
22082 |
++ return 1; |
22083 |
++ } |
22084 |
++ |
22085 |
++ return 1; |
22086 |
++} |
22087 |
++ |
22088 |
++int |
22089 |
++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot) |
22090 |
++{ |
22091 |
++ __u32 mode; |
22092 |
++ |
22093 |
++ if (unlikely(!file || !(prot & PROT_EXEC))) |
22094 |
++ return 1; |
22095 |
++ |
22096 |
++ if (is_writable_mmap(file)) |
22097 |
++ return 0; |
22098 |
++ |
22099 |
++ mode = |
22100 |
++ gr_search_file(file->f_dentry, |
22101 |
++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS, |
22102 |
++ file->f_vfsmnt); |
22103 |
++ |
22104 |
++ if (!gr_tpe_allow(file)) |
22105 |
++ return 0; |
22106 |
++ |
22107 |
++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) { |
22108 |
++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt); |
22109 |
++ return 0; |
22110 |
++ } else if (unlikely(!(mode & GR_EXEC))) { |
22111 |
++ return 0; |
22112 |
++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) { |
22113 |
++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt); |
22114 |
++ return 1; |
22115 |
++ } |
22116 |
++ |
22117 |
++ return 1; |
22118 |
++} |
22119 |
++ |
22120 |
++void |
22121 |
++gr_acl_handle_psacct(struct task_struct *task, const long code) |
22122 |
++{ |
22123 |
++ unsigned long runtime; |
22124 |
++ unsigned long cputime; |
22125 |
++ unsigned int wday, cday; |
22126 |
++ __u8 whr, chr; |
22127 |
++ __u8 wmin, cmin; |
22128 |
++ __u8 wsec, csec; |
22129 |
++ struct timespec timeval; |
22130 |
++ |
22131 |
++ if (unlikely(!(gr_status & GR_READY) || !task->acl || |
22132 |
++ !(task->acl->mode & GR_PROCACCT))) |
22133 |
++ return; |
22134 |
++ |
22135 |
++ do_posix_clock_monotonic_gettime(&timeval); |
22136 |
++ runtime = timeval.tv_sec - task->start_time.tv_sec; |
22137 |
++ wday = runtime / (3600 * 24); |
22138 |
++ runtime -= wday * (3600 * 24); |
22139 |
++ whr = runtime / 3600; |
22140 |
++ runtime -= whr * 3600; |
22141 |
++ wmin = runtime / 60; |
22142 |
++ runtime -= wmin * 60; |
22143 |
++ wsec = runtime; |
22144 |
++ |
22145 |
++ cputime = (task->utime + task->stime) / HZ; |
22146 |
++ cday = cputime / (3600 * 24); |
22147 |
++ cputime -= cday * (3600 * 24); |
22148 |
++ chr = cputime / 3600; |
22149 |
++ cputime -= chr * 3600; |
22150 |
++ cmin = cputime / 60; |
22151 |
++ cputime -= cmin * 60; |
22152 |
++ csec = cputime; |
22153 |
++ |
22154 |
++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code); |
22155 |
++ |
22156 |
++ return; |
22157 |
++} |
22158 |
++ |
22159 |
++void gr_set_kernel_label(struct task_struct *task) |
22160 |
++{ |
22161 |
++ if (gr_status & GR_READY) { |
22162 |
++ task->role = kernel_role; |
22163 |
++ task->acl = kernel_role->root_label; |
22164 |
++ } |
22165 |
++ return; |
22166 |
++} |
22167 |
++ |
22168 |
++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino) |
22169 |
++{ |
22170 |
++ struct task_struct *task = current; |
22171 |
++ struct dentry *dentry = file->f_dentry; |
22172 |
++ struct vfsmount *mnt = file->f_vfsmnt; |
22173 |
++ struct acl_object_label *obj, *tmp; |
22174 |
++ struct acl_subject_label *subj; |
22175 |
++ unsigned int bufsize; |
22176 |
++ int is_not_root; |
22177 |
++ char *path; |
22178 |
++ |
22179 |
++ if (unlikely(!(gr_status & GR_READY))) |
22180 |
++ return 1; |
22181 |
++ |
22182 |
++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN)) |
22183 |
++ return 1; |
22184 |
++ |
22185 |
++ /* ignore Eric Biederman */ |
22186 |
++ if (IS_PRIVATE(dentry->d_inode)) |
22187 |
++ return 1; |
22188 |
++ |
22189 |
++ subj = task->acl; |
22190 |
++ do { |
22191 |
++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj); |
22192 |
++ if (obj != NULL) |
22193 |
++ return (obj->mode & GR_FIND) ? 1 : 0; |
22194 |
++ } while ((subj = subj->parent_subject)); |
22195 |
++ |
22196 |
++ obj = chk_obj_label(dentry, mnt, task->acl); |
22197 |
++ if (obj->globbed == NULL) |
22198 |
++ return (obj->mode & GR_FIND) ? 1 : 0; |
22199 |
++ |
22200 |
++ is_not_root = ((obj->filename[0] == '/') && |
22201 |
++ (obj->filename[1] == '\0')) ? 0 : 1; |
22202 |
++ bufsize = PAGE_SIZE - namelen - is_not_root; |
22203 |
++ |
22204 |
++ /* check bufsize > PAGE_SIZE || bufsize == 0 */ |
22205 |
++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1))) |
22206 |
++ return 1; |
22207 |
++ |
22208 |
++ preempt_disable(); |
22209 |
++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()), |
22210 |
++ bufsize); |
22211 |
++ |
22212 |
++ bufsize = strlen(path); |
22213 |
++ |
22214 |
++ /* if base is "/", don't append an additional slash */ |
22215 |
++ if (is_not_root) |
22216 |
++ *(path + bufsize) = '/'; |
22217 |
++ memcpy(path + bufsize + is_not_root, name, namelen); |
22218 |
++ *(path + bufsize + namelen + is_not_root) = '\0'; |
22219 |
++ |
22220 |
++ tmp = obj->globbed; |
22221 |
++ while (tmp) { |
22222 |
++ if (!glob_match(tmp->filename, path)) { |
22223 |
++ preempt_enable(); |
22224 |
++ return (tmp->mode & GR_FIND) ? 1 : 0; |
22225 |
++ } |
22226 |
++ tmp = tmp->next; |
22227 |
++ } |
22228 |
++ preempt_enable(); |
22229 |
++ return (obj->mode & GR_FIND) ? 1 : 0; |
22230 |
++} |
22231 |
++ |
22232 |
++EXPORT_SYMBOL(gr_learn_resource); |
22233 |
++EXPORT_SYMBOL(gr_set_kernel_label); |
22234 |
++#ifdef CONFIG_SECURITY |
22235 |
++EXPORT_SYMBOL(gr_check_user_change); |
22236 |
++EXPORT_SYMBOL(gr_check_group_change); |
22237 |
++#endif |
22238 |
++ |
22239 |
+diff -urNp linux-2.6.24.4/grsecurity/gracl_cap.c linux-2.6.24.4/grsecurity/gracl_cap.c |
22240 |
+--- linux-2.6.24.4/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500 |
22241 |
++++ linux-2.6.24.4/grsecurity/gracl_cap.c 2008-03-26 17:56:56.000000000 -0400 |
22242 |
+@@ -0,0 +1,112 @@ |
22243 |
++#include <linux/kernel.h> |
22244 |
++#include <linux/module.h> |
22245 |
++#include <linux/sched.h> |
22246 |
++#include <linux/capability.h> |
22247 |
++#include <linux/gracl.h> |
22248 |
++#include <linux/grsecurity.h> |
22249 |
++#include <linux/grinternal.h> |
22250 |
++ |
22251 |
++static const char *captab_log[] = { |
22252 |
++ "CAP_CHOWN", |
22253 |
++ "CAP_DAC_OVERRIDE", |
22254 |
++ "CAP_DAC_READ_SEARCH", |
22255 |
++ "CAP_FOWNER", |
22256 |
++ "CAP_FSETID", |
22257 |
++ "CAP_KILL", |
22258 |
++ "CAP_SETGID", |
22259 |
++ "CAP_SETUID", |
22260 |
++ "CAP_SETPCAP", |
22261 |
++ "CAP_LINUX_IMMUTABLE", |
22262 |
++ "CAP_NET_BIND_SERVICE", |
22263 |
++ "CAP_NET_BROADCAST", |
22264 |
++ "CAP_NET_ADMIN", |
22265 |
++ "CAP_NET_RAW", |
22266 |
++ "CAP_IPC_LOCK", |
22267 |
++ "CAP_IPC_OWNER", |
22268 |
++ "CAP_SYS_MODULE", |
22269 |
++ "CAP_SYS_RAWIO", |
22270 |
++ "CAP_SYS_CHROOT", |
22271 |
++ "CAP_SYS_PTRACE", |
22272 |
++ "CAP_SYS_PACCT", |
22273 |
++ "CAP_SYS_ADMIN", |
22274 |
++ "CAP_SYS_BOOT", |
22275 |
++ "CAP_SYS_NICE", |
22276 |
++ "CAP_SYS_RESOURCE", |
22277 |
++ "CAP_SYS_TIME", |
22278 |
++ "CAP_SYS_TTY_CONFIG", |
22279 |
++ "CAP_MKNOD", |
22280 |
++ "CAP_LEASE", |
22281 |
++ "CAP_AUDIT_WRITE", |
22282 |
++ "CAP_AUDIT_CONTROL" |
22283 |
++}; |
22284 |
++ |
22285 |
++EXPORT_SYMBOL(gr_task_is_capable); |
22286 |
++EXPORT_SYMBOL(gr_is_capable_nolog); |
22287 |
++ |
22288 |
++int |
22289 |
++gr_task_is_capable(struct task_struct *task, const int cap) |
22290 |
++{ |
22291 |
++ struct acl_subject_label *curracl; |
22292 |
++ __u32 cap_drop = 0, cap_mask = 0; |
22293 |
++ |
22294 |
++ if (!gr_acl_is_enabled()) |
22295 |
++ return 1; |
22296 |
++ |
22297 |
++ curracl = task->acl; |
22298 |
++ |
22299 |
++ cap_drop = curracl->cap_lower; |
22300 |
++ cap_mask = curracl->cap_mask; |
22301 |
++ |
22302 |
++ while ((curracl = curracl->parent_subject)) { |
22303 |
++ if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap))) |
22304 |
++ cap_drop |= curracl->cap_lower & (1 << cap); |
22305 |
++ cap_mask |= curracl->cap_mask; |
22306 |
++ } |
22307 |
++ |
22308 |
++ if (!cap_raised(cap_drop, cap)) |
22309 |
++ return 1; |
22310 |
++ |
22311 |
++ curracl = task->acl; |
22312 |
++ |
22313 |
++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) |
22314 |
++ && cap_raised(task->cap_effective, cap)) { |
22315 |
++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, |
22316 |
++ task->role->roletype, task->uid, |
22317 |
++ task->gid, task->exec_file ? |
22318 |
++ gr_to_filename(task->exec_file->f_dentry, |
22319 |
++ task->exec_file->f_vfsmnt) : curracl->filename, |
22320 |
++ curracl->filename, 0UL, |
22321 |
++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip)); |
22322 |
++ return 1; |
22323 |
++ } |
22324 |
++ |
22325 |
++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap)) |
22326 |
++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]); |
22327 |
++ return 0; |
22328 |
++} |
22329 |
++ |
22330 |
++int |
22331 |
++gr_is_capable_nolog(const int cap) |
22332 |
++{ |
22333 |
++ struct acl_subject_label *curracl; |
22334 |
++ __u32 cap_drop = 0, cap_mask = 0; |
22335 |
++ |
22336 |
++ if (!gr_acl_is_enabled()) |
22337 |
++ return 1; |
22338 |
++ |
22339 |
++ curracl = current->acl; |
22340 |
++ |
22341 |
++ cap_drop = curracl->cap_lower; |
22342 |
++ cap_mask = curracl->cap_mask; |
22343 |
++ |
22344 |
++ while ((curracl = curracl->parent_subject)) { |
22345 |
++ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask); |
22346 |
++ cap_mask |= curracl->cap_mask; |
22347 |
++ } |
22348 |
++ |
22349 |
++ if (!cap_raised(cap_drop, cap)) |
22350 |
++ return 1; |
22351 |
++ |
22352 |
++ return 0; |
22353 |
++} |
22354 |
++ |
22355 |
+diff -urNp linux-2.6.24.4/grsecurity/gracl_fs.c linux-2.6.24.4/grsecurity/gracl_fs.c |
22356 |
+--- linux-2.6.24.4/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500 |
22357 |
++++ linux-2.6.24.4/grsecurity/gracl_fs.c 2008-03-26 18:14:13.000000000 -0400 |
22358 |
+@@ -0,0 +1,423 @@ |
22359 |
++#include <linux/kernel.h> |
22360 |
++#include <linux/sched.h> |
22361 |
++#include <linux/types.h> |
22362 |
++#include <linux/fs.h> |
22363 |
++#include <linux/file.h> |
22364 |
++#include <linux/stat.h> |
22365 |
++#include <linux/grsecurity.h> |
22366 |
++#include <linux/grinternal.h> |
22367 |
++#include <linux/gracl.h> |
22368 |
++ |
22369 |
++__u32 |
22370 |
++gr_acl_handle_hidden_file(const struct dentry * dentry, |
22371 |
++ const struct vfsmount * mnt) |
22372 |
++{ |
22373 |
++ __u32 mode; |
22374 |
++ |
22375 |
++ if (unlikely(!dentry->d_inode)) |
22376 |
++ return GR_FIND; |
22377 |
++ |
22378 |
++ mode = |
22379 |
++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt); |
22380 |
++ |
22381 |
++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) { |
22382 |
++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt); |
22383 |
++ return mode; |
22384 |
++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) { |
22385 |
++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt); |
22386 |
++ return 0; |
22387 |
++ } else if (unlikely(!(mode & GR_FIND))) |
22388 |
++ return 0; |
22389 |
++ |
22390 |
++ return GR_FIND; |
22391 |
++} |
22392 |
++ |
22393 |
++__u32 |
22394 |
++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt, |
22395 |
++ const int fmode) |
22396 |
++{ |
22397 |
++ __u32 reqmode = GR_FIND; |
22398 |
++ __u32 mode; |
22399 |
++ |
22400 |
++ if (unlikely(!dentry->d_inode)) |
22401 |
++ return reqmode; |
22402 |
++ |
22403 |
++ if (unlikely(fmode & O_APPEND)) |
22404 |
++ reqmode |= GR_APPEND; |
22405 |
++ else if (unlikely(fmode & FMODE_WRITE)) |
22406 |
++ reqmode |= GR_WRITE; |
22407 |
++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY))) |
22408 |
++ reqmode |= GR_READ; |
22409 |
++ |
22410 |
++ mode = |
22411 |
++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, |
22412 |
++ mnt); |
22413 |
++ |
22414 |
++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { |
22415 |
++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt, |
22416 |
++ reqmode & GR_READ ? " reading" : "", |
22417 |
++ reqmode & GR_WRITE ? " writing" : reqmode & |
22418 |
++ GR_APPEND ? " appending" : ""); |
22419 |
++ return reqmode; |
22420 |
++ } else |
22421 |
++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) |
22422 |
++ { |
22423 |
++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt, |
22424 |
++ reqmode & GR_READ ? " reading" : "", |
22425 |
++ reqmode & GR_WRITE ? " writing" : reqmode & |
22426 |
++ GR_APPEND ? " appending" : ""); |
22427 |
++ return 0; |
22428 |
++ } else if (unlikely((mode & reqmode) != reqmode)) |
22429 |
++ return 0; |
22430 |
++ |
22431 |
++ return reqmode; |
22432 |
++} |
22433 |
++ |
22434 |
++__u32 |
22435 |
++gr_acl_handle_creat(const struct dentry * dentry, |
22436 |
++ const struct dentry * p_dentry, |
22437 |
++ const struct vfsmount * p_mnt, const int fmode, |
22438 |
++ const int imode) |
22439 |
++{ |
22440 |
++ __u32 reqmode = GR_WRITE | GR_CREATE; |
22441 |
++ __u32 mode; |
22442 |
++ |
22443 |
++ if (unlikely(fmode & O_APPEND)) |
22444 |
++ reqmode |= GR_APPEND; |
22445 |
++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY))) |
22446 |
++ reqmode |= GR_READ; |
22447 |
++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID)))) |
22448 |
++ reqmode |= GR_SETID; |
22449 |
++ |
22450 |
++ mode = |
22451 |
++ gr_check_create(dentry, p_dentry, p_mnt, |
22452 |
++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); |
22453 |
++ |
22454 |
++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { |
22455 |
++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt, |
22456 |
++ reqmode & GR_READ ? " reading" : "", |
22457 |
++ reqmode & GR_WRITE ? " writing" : reqmode & |
22458 |
++ GR_APPEND ? " appending" : ""); |
22459 |
++ return reqmode; |
22460 |
++ } else |
22461 |
++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) |
22462 |
++ { |
22463 |
++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt, |
22464 |
++ reqmode & GR_READ ? " reading" : "", |
22465 |
++ reqmode & GR_WRITE ? " writing" : reqmode & |
22466 |
++ GR_APPEND ? " appending" : ""); |
22467 |
++ return 0; |
22468 |
++ } else if (unlikely((mode & reqmode) != reqmode)) |
22469 |
++ return 0; |
22470 |
++ |
22471 |
++ return reqmode; |
22472 |
++} |
22473 |
++ |
22474 |
++__u32 |
22475 |
++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt, |
22476 |
++ const int fmode) |
22477 |
++{ |
22478 |
++ __u32 mode, reqmode = GR_FIND; |
22479 |
++ |
22480 |
++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode)) |
22481 |
++ reqmode |= GR_EXEC; |
22482 |
++ if (fmode & S_IWOTH) |
22483 |
++ reqmode |= GR_WRITE; |
22484 |
++ if (fmode & S_IROTH) |
22485 |
++ reqmode |= GR_READ; |
22486 |
++ |
22487 |
++ mode = |
22488 |
++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, |
22489 |
++ mnt); |
22490 |
++ |
22491 |
++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { |
22492 |
++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt, |
22493 |
++ reqmode & GR_READ ? " reading" : "", |
22494 |
++ reqmode & GR_WRITE ? " writing" : "", |
22495 |
++ reqmode & GR_EXEC ? " executing" : ""); |
22496 |
++ return reqmode; |
22497 |
++ } else |
22498 |
++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) |
22499 |
++ { |
22500 |
++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt, |
22501 |
++ reqmode & GR_READ ? " reading" : "", |
22502 |
++ reqmode & GR_WRITE ? " writing" : "", |
22503 |
++ reqmode & GR_EXEC ? " executing" : ""); |
22504 |
++ return 0; |
22505 |
++ } else if (unlikely((mode & reqmode) != reqmode)) |
22506 |
++ return 0; |
22507 |
++ |
22508 |
++ return reqmode; |
22509 |
++} |
22510 |
++ |
22511 |
++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt) |
22512 |
++{ |
22513 |
++ __u32 mode; |
22514 |
++ |
22515 |
++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); |
22516 |
++ |
22517 |
++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { |
22518 |
++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt); |
22519 |
++ return mode; |
22520 |
++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { |
22521 |
++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt); |
22522 |
++ return 0; |
22523 |
++ } else if (unlikely((mode & (reqmode)) != (reqmode))) |
22524 |
++ return 0; |
22525 |
++ |
22526 |
++ return (reqmode); |
22527 |
++} |
22528 |
++ |
22529 |
++__u32 |
22530 |
++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt) |
22531 |
++{ |
22532 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG); |
22533 |
++} |
22534 |
++ |
22535 |
++__u32 |
22536 |
++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt) |
22537 |
++{ |
22538 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG); |
22539 |
++} |
22540 |
++ |
22541 |
++__u32 |
22542 |
++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt) |
22543 |
++{ |
22544 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG); |
22545 |
++} |
22546 |
++ |
22547 |
++__u32 |
22548 |
++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt) |
22549 |
++{ |
22550 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG); |
22551 |
++} |
22552 |
++ |
22553 |
++__u32 |
22554 |
++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt, |
22555 |
++ mode_t mode) |
22556 |
++{ |
22557 |
++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode))) |
22558 |
++ return 1; |
22559 |
++ |
22560 |
++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) { |
22561 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID, |
22562 |
++ GR_FCHMOD_ACL_MSG); |
22563 |
++ } else { |
22564 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG); |
22565 |
++ } |
22566 |
++} |
22567 |
++ |
22568 |
++__u32 |
22569 |
++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt, |
22570 |
++ mode_t mode) |
22571 |
++{ |
22572 |
++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) { |
22573 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID, |
22574 |
++ GR_CHMOD_ACL_MSG); |
22575 |
++ } else { |
22576 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG); |
22577 |
++ } |
22578 |
++} |
22579 |
++ |
22580 |
++__u32 |
22581 |
++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt) |
22582 |
++{ |
22583 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG); |
22584 |
++} |
22585 |
++ |
22586 |
++__u32 |
22587 |
++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt) |
22588 |
++{ |
22589 |
++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG); |
22590 |
++} |
22591 |
++ |
22592 |
++__u32 |
22593 |
++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt) |
22594 |
++{ |
22595 |
++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE, |
22596 |
++ GR_UNIXCONNECT_ACL_MSG); |
22597 |
++} |
22598 |
++ |
22599 |
++/* hardlinks require at minimum create permission, |
22600 |
++ any additional privilege required is based on the |
22601 |
++ privilege of the file being linked to |
22602 |
++*/ |
22603 |
++__u32 |
22604 |
++gr_acl_handle_link(const struct dentry * new_dentry, |
22605 |
++ const struct dentry * parent_dentry, |
22606 |
++ const struct vfsmount * parent_mnt, |
22607 |
++ const struct dentry * old_dentry, |
22608 |
++ const struct vfsmount * old_mnt, const char *to) |
22609 |
++{ |
22610 |
++ __u32 mode; |
22611 |
++ __u32 needmode = GR_CREATE | GR_LINK; |
22612 |
++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK; |
22613 |
++ |
22614 |
++ mode = |
22615 |
++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry, |
22616 |
++ old_mnt); |
22617 |
++ |
22618 |
++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) { |
22619 |
++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to); |
22620 |
++ return mode; |
22621 |
++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) { |
22622 |
++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to); |
22623 |
++ return 0; |
22624 |
++ } else if (unlikely((mode & needmode) != needmode)) |
22625 |
++ return 0; |
22626 |
++ |
22627 |
++ return 1; |
22628 |
++} |
22629 |
++ |
22630 |
++__u32 |
22631 |
++gr_acl_handle_symlink(const struct dentry * new_dentry, |
22632 |
++ const struct dentry * parent_dentry, |
22633 |
++ const struct vfsmount * parent_mnt, const char *from) |
22634 |
++{ |
22635 |
++ __u32 needmode = GR_WRITE | GR_CREATE; |
22636 |
++ __u32 mode; |
22637 |
++ |
22638 |
++ mode = |
22639 |
++ gr_check_create(new_dentry, parent_dentry, parent_mnt, |
22640 |
++ GR_CREATE | GR_AUDIT_CREATE | |
22641 |
++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS); |
22642 |
++ |
22643 |
++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) { |
22644 |
++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt); |
22645 |
++ return mode; |
22646 |
++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) { |
22647 |
++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt); |
22648 |
++ return 0; |
22649 |
++ } else if (unlikely((mode & needmode) != needmode)) |
22650 |
++ return 0; |
22651 |
++ |
22652 |
++ return (GR_WRITE | GR_CREATE); |
22653 |
++} |
22654 |
++ |
22655 |
++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) |
22656 |
++{ |
22657 |
++ __u32 mode; |
22658 |
++ |
22659 |
++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); |
22660 |
++ |
22661 |
++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { |
22662 |
++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt); |
22663 |
++ return mode; |
22664 |
++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { |
22665 |
++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt); |
22666 |
++ return 0; |
22667 |
++ } else if (unlikely((mode & (reqmode)) != (reqmode))) |
22668 |
++ return 0; |
22669 |
++ |
22670 |
++ return (reqmode); |
22671 |
++} |
22672 |
++ |
22673 |
++__u32 |
22674 |
++gr_acl_handle_mknod(const struct dentry * new_dentry, |
22675 |
++ const struct dentry * parent_dentry, |
22676 |
++ const struct vfsmount * parent_mnt, |
22677 |
++ const int mode) |
22678 |
++{ |
22679 |
++ __u32 reqmode = GR_WRITE | GR_CREATE; |
22680 |
++ if (unlikely(mode & (S_ISUID | S_ISGID))) |
22681 |
++ reqmode |= GR_SETID; |
22682 |
++ |
22683 |
++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, |
22684 |
++ reqmode, GR_MKNOD_ACL_MSG); |
22685 |
++} |
22686 |
++ |
22687 |
++__u32 |
22688 |
++gr_acl_handle_mkdir(const struct dentry *new_dentry, |
22689 |
++ const struct dentry *parent_dentry, |
22690 |
++ const struct vfsmount *parent_mnt) |
22691 |
++{ |
22692 |
++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, |
22693 |
++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG); |
22694 |
++} |
22695 |
++ |
22696 |
++#define RENAME_CHECK_SUCCESS(old, new) \ |
22697 |
++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \ |
22698 |
++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ))) |
22699 |
++ |
22700 |
++int |
22701 |
++gr_acl_handle_rename(struct dentry *new_dentry, |
22702 |
++ struct dentry *parent_dentry, |
22703 |
++ const struct vfsmount *parent_mnt, |
22704 |
++ struct dentry *old_dentry, |
22705 |
++ struct inode *old_parent_inode, |
22706 |
++ struct vfsmount *old_mnt, const char *newname) |
22707 |
++{ |
22708 |
++ __u32 comp1, comp2; |
22709 |
++ int error = 0; |
22710 |
++ |
22711 |
++ if (unlikely(!gr_acl_is_enabled())) |
22712 |
++ return 0; |
22713 |
++ |
22714 |
++ if (!new_dentry->d_inode) { |
22715 |
++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt, |
22716 |
++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ | |
22717 |
++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS); |
22718 |
++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE | |
22719 |
++ GR_DELETE | GR_AUDIT_DELETE | |
22720 |
++ GR_AUDIT_READ | GR_AUDIT_WRITE | |
22721 |
++ GR_SUPPRESS, old_mnt); |
22722 |
++ } else { |
22723 |
++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE | |
22724 |
++ GR_CREATE | GR_DELETE | |
22725 |
++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | |
22726 |
++ GR_AUDIT_READ | GR_AUDIT_WRITE | |
22727 |
++ GR_SUPPRESS, parent_mnt); |
22728 |
++ comp2 = |
22729 |
++ gr_search_file(old_dentry, |
22730 |
++ GR_READ | GR_WRITE | GR_AUDIT_READ | |
22731 |
++ GR_DELETE | GR_AUDIT_DELETE | |
22732 |
++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt); |
22733 |
++ } |
22734 |
++ |
22735 |
++ if (RENAME_CHECK_SUCCESS(comp1, comp2) && |
22736 |
++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS))) |
22737 |
++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname); |
22738 |
++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS) |
22739 |
++ && !(comp2 & GR_SUPPRESS)) { |
22740 |
++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname); |
22741 |
++ error = -EACCES; |
22742 |
++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2))) |
22743 |
++ error = -EACCES; |
22744 |
++ |
22745 |
++ return error; |
22746 |
++} |
22747 |
++ |
22748 |
++void |
22749 |
++gr_acl_handle_exit(void) |
22750 |
++{ |
22751 |
++ u16 id; |
22752 |
++ char *rolename; |
22753 |
++ struct file *exec_file; |
22754 |
++ |
22755 |
++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) { |
22756 |
++ id = current->acl_role_id; |
22757 |
++ rolename = current->role->rolename; |
22758 |
++ gr_set_acls(1); |
22759 |
++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id); |
22760 |
++ } |
22761 |
++ |
22762 |
++ write_lock(&grsec_exec_file_lock); |
22763 |
++ exec_file = current->exec_file; |
22764 |
++ current->exec_file = NULL; |
22765 |
++ write_unlock(&grsec_exec_file_lock); |
22766 |
++ |
22767 |
++ if (exec_file) |
22768 |
++ fput(exec_file); |
22769 |
++} |
22770 |
++ |
22771 |
++int |
22772 |
++gr_acl_handle_procpidmem(const struct task_struct *task) |
22773 |
++{ |
22774 |
++ if (unlikely(!gr_acl_is_enabled())) |
22775 |
++ return 0; |
22776 |
++ |
22777 |
++ if (task != current && task->acl->mode & GR_PROTPROCFD) |
22778 |
++ return -EACCES; |
22779 |
++ |
22780 |
++ return 0; |
22781 |
++} |
22782 |
+diff -urNp linux-2.6.24.4/grsecurity/gracl_ip.c linux-2.6.24.4/grsecurity/gracl_ip.c |
22783 |
+--- linux-2.6.24.4/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500 |
22784 |
++++ linux-2.6.24.4/grsecurity/gracl_ip.c 2008-03-26 17:56:56.000000000 -0400 |
22785 |
+@@ -0,0 +1,313 @@ |
22786 |
++#include <linux/kernel.h> |
22787 |
++#include <asm/uaccess.h> |
22788 |
++#include <asm/errno.h> |
22789 |
++#include <net/sock.h> |
22790 |
++#include <linux/file.h> |
22791 |
++#include <linux/fs.h> |
22792 |
++#include <linux/net.h> |
22793 |
++#include <linux/in.h> |
22794 |
++#include <linux/skbuff.h> |
22795 |
++#include <linux/ip.h> |
22796 |
++#include <linux/udp.h> |
22797 |
++#include <linux/smp_lock.h> |
22798 |
++#include <linux/types.h> |
22799 |
++#include <linux/sched.h> |
22800 |
++#include <linux/netdevice.h> |
22801 |
++#include <linux/inetdevice.h> |
22802 |
++#include <linux/gracl.h> |
22803 |
++#include <linux/grsecurity.h> |
22804 |
++#include <linux/grinternal.h> |
22805 |
++ |
22806 |
++#define GR_BIND 0x01 |
22807 |
++#define GR_CONNECT 0x02 |
22808 |
++#define GR_INVERT 0x04 |
22809 |
++ |
22810 |
++static const char * gr_protocols[256] = { |
22811 |
++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt", |
22812 |
++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet", |
22813 |
++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1", |
22814 |
++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp", |
22815 |
++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++", |
22816 |
++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre", |
22817 |
++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile", |
22818 |
++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63", |
22819 |
++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv", |
22820 |
++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", |
22821 |
++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", |
22822 |
++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp", |
22823 |
++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim", |
22824 |
++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip", |
22825 |
++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp", |
22826 |
++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup", |
22827 |
++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135", |
22828 |
++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143", |
22829 |
++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151", |
22830 |
++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159", |
22831 |
++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167", |
22832 |
++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175", |
22833 |
++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183", |
22834 |
++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191", |
22835 |
++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199", |
22836 |
++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207", |
22837 |
++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215", |
22838 |
++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223", |
22839 |
++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231", |
22840 |
++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239", |
22841 |
++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247", |
22842 |
++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255", |
22843 |
++ }; |
22844 |
++ |
22845 |
++static const char * gr_socktypes[11] = { |
22846 |
++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", |
22847 |
++ "unknown:7", "unknown:8", "unknown:9", "packet" |
22848 |
++ }; |
22849 |
++ |
22850 |
++const char * |
22851 |
++gr_proto_to_name(unsigned char proto) |
22852 |
++{ |
22853 |
++ return gr_protocols[proto]; |
22854 |
++} |
22855 |
++ |
22856 |
++const char * |
22857 |
++gr_socktype_to_name(unsigned char type) |
22858 |
++{ |
22859 |
++ return gr_socktypes[type]; |
22860 |
++} |
22861 |
++ |
22862 |
++int |
22863 |
++gr_search_socket(const int domain, const int type, const int protocol) |
22864 |
++{ |
22865 |
++ struct acl_subject_label *curr; |
22866 |
++ |
22867 |
++ if (unlikely(!gr_acl_is_enabled())) |
22868 |
++ goto exit; |
22869 |
++ |
22870 |
++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET) |
22871 |
++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255)) |
22872 |
++ goto exit; // let the kernel handle it |
22873 |
++ |
22874 |
++ curr = current->acl; |
22875 |
++ |
22876 |
++ if (!curr->ips) |
22877 |
++ goto exit; |
22878 |
++ |
22879 |
++ if ((curr->ip_type & (1 << type)) && |
22880 |
++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32)))) |
22881 |
++ goto exit; |
22882 |
++ |
22883 |
++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) { |
22884 |
++ /* we don't place acls on raw sockets , and sometimes |
22885 |
++ dgram/ip sockets are opened for ioctl and not |
22886 |
++ bind/connect, so we'll fake a bind learn log */ |
22887 |
++ if (type == SOCK_RAW || type == SOCK_PACKET) { |
22888 |
++ __u32 fakeip = 0; |
22889 |
++ security_learn(GR_IP_LEARN_MSG, current->role->rolename, |
22890 |
++ current->role->roletype, current->uid, |
22891 |
++ current->gid, current->exec_file ? |
22892 |
++ gr_to_filename(current->exec_file->f_dentry, |
22893 |
++ current->exec_file->f_vfsmnt) : |
22894 |
++ curr->filename, curr->filename, |
22895 |
++ NIPQUAD(fakeip), 0, type, |
22896 |
++ protocol, GR_CONNECT, |
22897 |
++NIPQUAD(current->signal->curr_ip)); |
22898 |
++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) { |
22899 |
++ __u32 fakeip = 0; |
22900 |
++ security_learn(GR_IP_LEARN_MSG, current->role->rolename, |
22901 |
++ current->role->roletype, current->uid, |
22902 |
++ current->gid, current->exec_file ? |
22903 |
++ gr_to_filename(current->exec_file->f_dentry, |
22904 |
++ current->exec_file->f_vfsmnt) : |
22905 |
++ curr->filename, curr->filename, |
22906 |
++ NIPQUAD(fakeip), 0, type, |
22907 |
++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip)); |
22908 |
++ } |
22909 |
++ /* we'll log when they use connect or bind */ |
22910 |
++ goto exit; |
22911 |
++ } |
22912 |
++ |
22913 |
++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", |
22914 |
++ gr_socktype_to_name(type), gr_proto_to_name(protocol)); |
22915 |
++ |
22916 |
++ return 0; |
22917 |
++ exit: |
22918 |
++ return 1; |
22919 |
++} |
22920 |
++ |
22921 |
++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) |
22922 |
++{ |
22923 |
++ if ((ip->mode & mode) && |
22924 |
++ (ip_port >= ip->low) && |
22925 |
++ (ip_port <= ip->high) && |
22926 |
++ ((ntohl(ip_addr) & our_netmask) == |
22927 |
++ (ntohl(our_addr) & our_netmask)) |
22928 |
++ && (ip->proto[protocol / 32] & (1 << (protocol % 32))) |
22929 |
++ && (ip->type & (1 << type))) { |
22930 |
++ if (ip->mode & GR_INVERT) |
22931 |
++ return 2; // specifically denied |
22932 |
++ else |
22933 |
++ return 1; // allowed |
22934 |
++ } |
22935 |
++ |
22936 |
++ return 0; // not specifically allowed, may continue parsing |
22937 |
++} |
22938 |
++ |
22939 |
++static int |
22940 |
++gr_search_connectbind(const int mode, const struct sock *sk, |
22941 |
++ const struct sockaddr_in *addr, const int type) |
22942 |
++{ |
22943 |
++ char iface[IFNAMSIZ] = {0}; |
22944 |
++ struct acl_subject_label *curr; |
22945 |
++ struct acl_ip_label *ip; |
22946 |
++ struct net_device *dev; |
22947 |
++ struct in_device *idev; |
22948 |
++ unsigned long i; |
22949 |
++ int ret; |
22950 |
++ __u32 ip_addr = 0; |
22951 |
++ __u32 our_addr; |
22952 |
++ __u32 our_netmask; |
22953 |
++ char *p; |
22954 |
++ __u16 ip_port = 0; |
22955 |
++ |
22956 |
++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET)) |
22957 |
++ return 1; |
22958 |
++ |
22959 |
++ curr = current->acl; |
22960 |
++ |
22961 |
++ if (!curr->ips) |
22962 |
++ return 1; |
22963 |
++ |
22964 |
++ ip_addr = addr->sin_addr.s_addr; |
22965 |
++ ip_port = ntohs(addr->sin_port); |
22966 |
++ |
22967 |
++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) { |
22968 |
++ security_learn(GR_IP_LEARN_MSG, current->role->rolename, |
22969 |
++ current->role->roletype, current->uid, |
22970 |
++ current->gid, current->exec_file ? |
22971 |
++ gr_to_filename(current->exec_file->f_dentry, |
22972 |
++ current->exec_file->f_vfsmnt) : |
22973 |
++ curr->filename, curr->filename, |
22974 |
++ NIPQUAD(ip_addr), ip_port, type, |
22975 |
++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip)); |
22976 |
++ return 1; |
22977 |
++ } |
22978 |
++ |
22979 |
++ for (i = 0; i < curr->ip_num; i++) { |
22980 |
++ ip = *(curr->ips + i); |
22981 |
++ if (ip->iface != NULL) { |
22982 |
++ strncpy(iface, ip->iface, IFNAMSIZ - 1); |
22983 |
++ p = strchr(iface, ':'); |
22984 |
++ if (p != NULL) |
22985 |
++ *p = '\0'; |
22986 |
++ dev = dev_get_by_name(sk->sk_net, iface); |
22987 |
++ if (dev == NULL) |
22988 |
++ continue; |
22989 |
++ idev = in_dev_get(dev); |
22990 |
++ if (idev == NULL) { |
22991 |
++ dev_put(dev); |
22992 |
++ continue; |
22993 |
++ } |
22994 |
++ rcu_read_lock(); |
22995 |
++ for_ifa(idev) { |
22996 |
++ if (!strcmp(ip->iface, ifa->ifa_label)) { |
22997 |
++ our_addr = ifa->ifa_address; |
22998 |
++ our_netmask = 0xffffffff; |
22999 |
++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask); |
23000 |
++ if (ret == 1) { |
23001 |
++ rcu_read_unlock(); |
23002 |
++ in_dev_put(idev); |
23003 |
++ dev_put(dev); |
23004 |
++ return 1; |
23005 |
++ } else if (ret == 2) { |
23006 |
++ rcu_read_unlock(); |
23007 |
++ in_dev_put(idev); |
23008 |
++ dev_put(dev); |
23009 |
++ goto denied; |
23010 |
++ } |
23011 |
++ } |
23012 |
++ } endfor_ifa(idev); |
23013 |
++ rcu_read_unlock(); |
23014 |
++ in_dev_put(idev); |
23015 |
++ dev_put(dev); |
23016 |
++ } else { |
23017 |
++ our_addr = ip->addr; |
23018 |
++ our_netmask = ip->netmask; |
23019 |
++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask); |
23020 |
++ if (ret == 1) |
23021 |
++ return 1; |
23022 |
++ else if (ret == 2) |
23023 |
++ goto denied; |
23024 |
++ } |
23025 |
++ } |
23026 |
++ |
23027 |
++denied: |
23028 |
++ if (mode == GR_BIND) |
23029 |
++ 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)); |
23030 |
++ else if (mode == GR_CONNECT) |
23031 |
++ 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)); |
23032 |
++ |
23033 |
++ return 0; |
23034 |
++} |
23035 |
++ |
23036 |
++int |
23037 |
++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr) |
23038 |
++{ |
23039 |
++ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type); |
23040 |
++} |
23041 |
++ |
23042 |
++int |
23043 |
++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr) |
23044 |
++{ |
23045 |
++ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type); |
23046 |
++} |
23047 |
++ |
23048 |
++int gr_search_listen(const struct socket *sock) |
23049 |
++{ |
23050 |
++ struct sock *sk = sock->sk; |
23051 |
++ struct sockaddr_in addr; |
23052 |
++ |
23053 |
++ addr.sin_addr.s_addr = inet_sk(sk)->saddr; |
23054 |
++ addr.sin_port = inet_sk(sk)->sport; |
23055 |
++ |
23056 |
++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type); |
23057 |
++} |
23058 |
++ |
23059 |
++int gr_search_accept(const struct socket *sock) |
23060 |
++{ |
23061 |
++ struct sock *sk = sock->sk; |
23062 |
++ struct sockaddr_in addr; |
23063 |
++ |
23064 |
++ addr.sin_addr.s_addr = inet_sk(sk)->saddr; |
23065 |
++ addr.sin_port = inet_sk(sk)->sport; |
23066 |
++ |
23067 |
++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type); |
23068 |
++} |
23069 |
++ |
23070 |
++int |
23071 |
++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr) |
23072 |
++{ |
23073 |
++ if (addr) |
23074 |
++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM); |
23075 |
++ else { |
23076 |
++ struct sockaddr_in sin; |
23077 |
++ const struct inet_sock *inet = inet_sk(sk); |
23078 |
++ |
23079 |
++ sin.sin_addr.s_addr = inet->daddr; |
23080 |
++ sin.sin_port = inet->dport; |
23081 |
++ |
23082 |
++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM); |
23083 |
++ } |
23084 |
++} |
23085 |
++ |
23086 |
++int |
23087 |
++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb) |
23088 |
++{ |
23089 |
++ struct sockaddr_in sin; |
23090 |
++ |
23091 |
++ if (unlikely(skb->len < sizeof (struct udphdr))) |
23092 |
++ return 1; // skip this packet |
23093 |
++ |
23094 |
++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr; |
23095 |
++ sin.sin_port = udp_hdr(skb)->source; |
23096 |
++ |
23097 |
++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM); |
23098 |
++} |
23099 |
+diff -urNp linux-2.6.24.4/grsecurity/gracl_learn.c linux-2.6.24.4/grsecurity/gracl_learn.c |
23100 |
+--- linux-2.6.24.4/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500 |
23101 |
++++ linux-2.6.24.4/grsecurity/gracl_learn.c 2008-03-26 17:56:56.000000000 -0400 |
23102 |
+@@ -0,0 +1,211 @@ |
23103 |
++#include <linux/kernel.h> |
23104 |
++#include <linux/mm.h> |
23105 |
++#include <linux/sched.h> |
23106 |
++#include <linux/poll.h> |
23107 |
++#include <linux/smp_lock.h> |
23108 |
++#include <linux/string.h> |
23109 |
++#include <linux/file.h> |
23110 |
++#include <linux/types.h> |
23111 |
++#include <linux/vmalloc.h> |
23112 |
++#include <linux/grinternal.h> |
23113 |
++ |
23114 |
++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf, |
23115 |
++ size_t count, loff_t *ppos); |
23116 |
++extern int gr_acl_is_enabled(void); |
23117 |
++ |
23118 |
++static DECLARE_WAIT_QUEUE_HEAD(learn_wait); |
23119 |
++static int gr_learn_attached; |
23120 |
++ |
23121 |
++/* use a 512k buffer */ |
23122 |
++#define LEARN_BUFFER_SIZE (512 * 1024) |
23123 |
++ |
23124 |
++static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED; |
23125 |
++static DECLARE_MUTEX(gr_learn_user_sem); |
23126 |
++ |
23127 |
++/* we need to maintain two buffers, so that the kernel context of grlearn |
23128 |
++ uses a semaphore around the userspace copying, and the other kernel contexts |
23129 |
++ use a spinlock when copying into the buffer, since they cannot sleep |
23130 |
++*/ |
23131 |
++static char *learn_buffer; |
23132 |
++static char *learn_buffer_user; |
23133 |
++static int learn_buffer_len; |
23134 |
++static int learn_buffer_user_len; |
23135 |
++ |
23136 |
++static ssize_t |
23137 |
++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos) |
23138 |
++{ |
23139 |
++ DECLARE_WAITQUEUE(wait, current); |
23140 |
++ ssize_t retval = 0; |
23141 |
++ |
23142 |
++ add_wait_queue(&learn_wait, &wait); |
23143 |
++ set_current_state(TASK_INTERRUPTIBLE); |
23144 |
++ do { |
23145 |
++ down(&gr_learn_user_sem); |
23146 |
++ spin_lock(&gr_learn_lock); |
23147 |
++ if (learn_buffer_len) |
23148 |
++ break; |
23149 |
++ spin_unlock(&gr_learn_lock); |
23150 |
++ up(&gr_learn_user_sem); |
23151 |
++ if (file->f_flags & O_NONBLOCK) { |
23152 |
++ retval = -EAGAIN; |
23153 |
++ goto out; |
23154 |
++ } |
23155 |
++ if (signal_pending(current)) { |
23156 |
++ retval = -ERESTARTSYS; |
23157 |
++ goto out; |
23158 |
++ } |
23159 |
++ |
23160 |
++ schedule(); |
23161 |
++ } while (1); |
23162 |
++ |
23163 |
++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len); |
23164 |
++ learn_buffer_user_len = learn_buffer_len; |
23165 |
++ retval = learn_buffer_len; |
23166 |
++ learn_buffer_len = 0; |
23167 |
++ |
23168 |
++ spin_unlock(&gr_learn_lock); |
23169 |
++ |
23170 |
++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len)) |
23171 |
++ retval = -EFAULT; |
23172 |
++ |
23173 |
++ up(&gr_learn_user_sem); |
23174 |
++out: |
23175 |
++ set_current_state(TASK_RUNNING); |
23176 |
++ remove_wait_queue(&learn_wait, &wait); |
23177 |
++ return retval; |
23178 |
++} |
23179 |
++ |
23180 |
++static unsigned int |
23181 |
++poll_learn(struct file * file, poll_table * wait) |
23182 |
++{ |
23183 |
++ poll_wait(file, &learn_wait, wait); |
23184 |
++ |
23185 |
++ if (learn_buffer_len) |
23186 |
++ return (POLLIN | POLLRDNORM); |
23187 |
++ |
23188 |
++ return 0; |
23189 |
++} |
23190 |
++ |
23191 |
++void |
23192 |
++gr_clear_learn_entries(void) |
23193 |
++{ |
23194 |
++ char *tmp; |
23195 |
++ |
23196 |
++ down(&gr_learn_user_sem); |
23197 |
++ if (learn_buffer != NULL) { |
23198 |
++ spin_lock(&gr_learn_lock); |
23199 |
++ tmp = learn_buffer; |
23200 |
++ learn_buffer = NULL; |
23201 |
++ spin_unlock(&gr_learn_lock); |
23202 |
++ vfree(learn_buffer); |
23203 |
++ } |
23204 |
++ if (learn_buffer_user != NULL) { |
23205 |
++ vfree(learn_buffer_user); |
23206 |
++ learn_buffer_user = NULL; |
23207 |
++ } |
23208 |
++ learn_buffer_len = 0; |
23209 |
++ up(&gr_learn_user_sem); |
23210 |
++ |
23211 |
++ return; |
23212 |
++} |
23213 |
++ |
23214 |
++void |
23215 |
++gr_add_learn_entry(const char *fmt, ...) |
23216 |
++{ |
23217 |
++ va_list args; |
23218 |
++ unsigned int len; |
23219 |
++ |
23220 |
++ if (!gr_learn_attached) |
23221 |
++ return; |
23222 |
++ |
23223 |
++ spin_lock(&gr_learn_lock); |
23224 |
++ |
23225 |
++ /* leave a gap at the end so we know when it's "full" but don't have to |
23226 |
++ compute the exact length of the string we're trying to append |
23227 |
++ */ |
23228 |
++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) { |
23229 |
++ spin_unlock(&gr_learn_lock); |
23230 |
++ wake_up_interruptible(&learn_wait); |
23231 |
++ return; |
23232 |
++ } |
23233 |
++ if (learn_buffer == NULL) { |
23234 |
++ spin_unlock(&gr_learn_lock); |
23235 |
++ return; |
23236 |
++ } |
23237 |
++ |
23238 |
++ va_start(args, fmt); |
23239 |
++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args); |
23240 |
++ va_end(args); |
23241 |
++ |
23242 |
++ learn_buffer_len += len + 1; |
23243 |
++ |
23244 |
++ spin_unlock(&gr_learn_lock); |
23245 |
++ wake_up_interruptible(&learn_wait); |
23246 |
++ |
23247 |
++ return; |
23248 |
++} |
23249 |
++ |
23250 |
++static int |
23251 |
++open_learn(struct inode *inode, struct file *file) |
23252 |
++{ |
23253 |
++ if (file->f_mode & FMODE_READ && gr_learn_attached) |
23254 |
++ return -EBUSY; |
23255 |
++ if (file->f_mode & FMODE_READ) { |
23256 |
++ int retval = 0; |
23257 |
++ down(&gr_learn_user_sem); |
23258 |
++ if (learn_buffer == NULL) |
23259 |
++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE); |
23260 |
++ if (learn_buffer_user == NULL) |
23261 |
++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE); |
23262 |
++ if (learn_buffer == NULL) { |
23263 |
++ retval = -ENOMEM; |
23264 |
++ goto out_error; |
23265 |
++ } |
23266 |
++ if (learn_buffer_user == NULL) { |
23267 |
++ retval = -ENOMEM; |
23268 |
++ goto out_error; |
23269 |
++ } |
23270 |
++ learn_buffer_len = 0; |
23271 |
++ learn_buffer_user_len = 0; |
23272 |
++ gr_learn_attached = 1; |
23273 |
++out_error: |
23274 |
++ up(&gr_learn_user_sem); |
23275 |
++ return retval; |
23276 |
++ } |
23277 |
++ return 0; |
23278 |
++} |
23279 |
++ |
23280 |
++static int |
23281 |
++close_learn(struct inode *inode, struct file *file) |
23282 |
++{ |
23283 |
++ char *tmp; |
23284 |
++ |
23285 |
++ if (file->f_mode & FMODE_READ) { |
23286 |
++ down(&gr_learn_user_sem); |
23287 |
++ if (learn_buffer != NULL) { |
23288 |
++ spin_lock(&gr_learn_lock); |
23289 |
++ tmp = learn_buffer; |
23290 |
++ learn_buffer = NULL; |
23291 |
++ spin_unlock(&gr_learn_lock); |
23292 |
++ vfree(tmp); |
23293 |
++ } |
23294 |
++ if (learn_buffer_user != NULL) { |
23295 |
++ vfree(learn_buffer_user); |
23296 |
++ learn_buffer_user = NULL; |
23297 |
++ } |
23298 |
++ learn_buffer_len = 0; |
23299 |
++ learn_buffer_user_len = 0; |
23300 |
++ gr_learn_attached = 0; |
23301 |
++ up(&gr_learn_user_sem); |
23302 |
++ } |
23303 |
++ |
23304 |
++ return 0; |
23305 |
++} |
23306 |
++ |
23307 |
++struct file_operations grsec_fops = { |
23308 |
++ .read = read_learn, |
23309 |
++ .write = write_grsec_handler, |
23310 |
++ .open = open_learn, |
23311 |
++ .release = close_learn, |
23312 |
++ .poll = poll_learn, |
23313 |
++}; |
23314 |
+diff -urNp linux-2.6.24.4/grsecurity/gracl_res.c linux-2.6.24.4/grsecurity/gracl_res.c |
23315 |
+--- linux-2.6.24.4/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500 |
23316 |
++++ linux-2.6.24.4/grsecurity/gracl_res.c 2008-03-26 17:56:56.000000000 -0400 |
23317 |
+@@ -0,0 +1,45 @@ |
23318 |
++#include <linux/kernel.h> |
23319 |
++#include <linux/sched.h> |
23320 |
++#include <linux/gracl.h> |
23321 |
++#include <linux/grinternal.h> |
23322 |
++ |
23323 |
++static const char *restab_log[] = { |
23324 |
++ [RLIMIT_CPU] = "RLIMIT_CPU", |
23325 |
++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE", |
23326 |
++ [RLIMIT_DATA] = "RLIMIT_DATA", |
23327 |
++ [RLIMIT_STACK] = "RLIMIT_STACK", |
23328 |
++ [RLIMIT_CORE] = "RLIMIT_CORE", |
23329 |
++ [RLIMIT_RSS] = "RLIMIT_RSS", |
23330 |
++ [RLIMIT_NPROC] = "RLIMIT_NPROC", |
23331 |
++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE", |
23332 |
++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK", |
23333 |
++ [RLIMIT_AS] = "RLIMIT_AS", |
23334 |
++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS", |
23335 |
++ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH" |
23336 |
++}; |
23337 |
++ |
23338 |
++void |
23339 |
++gr_log_resource(const struct task_struct *task, |
23340 |
++ const int res, const unsigned long wanted, const int gt) |
23341 |
++{ |
23342 |
++ if (res == RLIMIT_NPROC && |
23343 |
++ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || |
23344 |
++ cap_raised(task->cap_effective, CAP_SYS_RESOURCE))) |
23345 |
++ return; |
23346 |
++ else if (res == RLIMIT_MEMLOCK && |
23347 |
++ cap_raised(task->cap_effective, CAP_IPC_LOCK)) |
23348 |
++ return; |
23349 |
++ |
23350 |
++ if (!gr_acl_is_enabled() && !grsec_resource_logging) |
23351 |
++ return; |
23352 |
++ |
23353 |
++ preempt_disable(); |
23354 |
++ |
23355 |
++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) || |
23356 |
++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) && |
23357 |
++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY)) |
23358 |
++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur); |
23359 |
++ preempt_enable_no_resched(); |
23360 |
++ |
23361 |
++ return; |
23362 |
++} |
23363 |
+diff -urNp linux-2.6.24.4/grsecurity/gracl_segv.c linux-2.6.24.4/grsecurity/gracl_segv.c |
23364 |
+--- linux-2.6.24.4/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500 |
23365 |
++++ linux-2.6.24.4/grsecurity/gracl_segv.c 2008-03-26 17:56:56.000000000 -0400 |
23366 |
+@@ -0,0 +1,301 @@ |
23367 |
++#include <linux/kernel.h> |
23368 |
++#include <linux/mm.h> |
23369 |
++#include <asm/uaccess.h> |
23370 |
++#include <asm/errno.h> |
23371 |
++#include <asm/mman.h> |
23372 |
++#include <net/sock.h> |
23373 |
++#include <linux/file.h> |
23374 |
++#include <linux/fs.h> |
23375 |
++#include <linux/net.h> |
23376 |
++#include <linux/in.h> |
23377 |
++#include <linux/smp_lock.h> |
23378 |
++#include <linux/slab.h> |
23379 |
++#include <linux/types.h> |
23380 |
++#include <linux/sched.h> |
23381 |
++#include <linux/timer.h> |
23382 |
++#include <linux/gracl.h> |
23383 |
++#include <linux/grsecurity.h> |
23384 |
++#include <linux/grinternal.h> |
23385 |
++ |
23386 |
++static struct crash_uid *uid_set; |
23387 |
++static unsigned short uid_used; |
23388 |
++static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED; |
23389 |
++extern rwlock_t gr_inode_lock; |
23390 |
++extern struct acl_subject_label * |
23391 |
++ lookup_acl_subj_label(const ino_t inode, const dev_t dev, |
23392 |
++ struct acl_role_label *role); |
23393 |
++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t); |
23394 |
++ |
23395 |
++int |
23396 |
++gr_init_uidset(void) |
23397 |
++{ |
23398 |
++ uid_set = |
23399 |
++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL); |
23400 |
++ uid_used = 0; |
23401 |
++ |
23402 |
++ return uid_set ? 1 : 0; |
23403 |
++} |
23404 |
++ |
23405 |
++void |
23406 |
++gr_free_uidset(void) |
23407 |
++{ |
23408 |
++ if (uid_set) |
23409 |
++ kfree(uid_set); |
23410 |
++ |
23411 |
++ return; |
23412 |
++} |
23413 |
++ |
23414 |
++int |
23415 |
++gr_find_uid(const uid_t uid) |
23416 |
++{ |
23417 |
++ struct crash_uid *tmp = uid_set; |
23418 |
++ uid_t buid; |
23419 |
++ int low = 0, high = uid_used - 1, mid; |
23420 |
++ |
23421 |
++ while (high >= low) { |
23422 |
++ mid = (low + high) >> 1; |
23423 |
++ buid = tmp[mid].uid; |
23424 |
++ if (buid == uid) |
23425 |
++ return mid; |
23426 |
++ if (buid > uid) |
23427 |
++ high = mid - 1; |
23428 |
++ if (buid < uid) |
23429 |
++ low = mid + 1; |
23430 |
++ } |
23431 |
++ |
23432 |
++ return -1; |
23433 |
++} |
23434 |
++ |
23435 |
++static __inline__ void |
23436 |
++gr_insertsort(void) |
23437 |
++{ |
23438 |
++ unsigned short i, j; |
23439 |
++ struct crash_uid index; |
23440 |
++ |
23441 |
++ for (i = 1; i < uid_used; i++) { |
23442 |
++ index = uid_set[i]; |
23443 |
++ j = i; |
23444 |
++ while ((j > 0) && uid_set[j - 1].uid > index.uid) { |
23445 |
++ uid_set[j] = uid_set[j - 1]; |
23446 |
++ j--; |
23447 |
++ } |
23448 |
++ uid_set[j] = index; |
23449 |
++ } |
23450 |
++ |
23451 |
++ return; |
23452 |
++} |
23453 |
++ |
23454 |
++static __inline__ void |
23455 |
++gr_insert_uid(const uid_t uid, const unsigned long expires) |
23456 |
++{ |
23457 |
++ int loc; |
23458 |
++ |
23459 |
++ if (uid_used == GR_UIDTABLE_MAX) |
23460 |
++ return; |
23461 |
++ |
23462 |
++ loc = gr_find_uid(uid); |
23463 |
++ |
23464 |
++ if (loc >= 0) { |
23465 |
++ uid_set[loc].expires = expires; |
23466 |
++ return; |
23467 |
++ } |
23468 |
++ |
23469 |
++ uid_set[uid_used].uid = uid; |
23470 |
++ uid_set[uid_used].expires = expires; |
23471 |
++ uid_used++; |
23472 |
++ |
23473 |
++ gr_insertsort(); |
23474 |
++ |
23475 |
++ return; |
23476 |
++} |
23477 |
++ |
23478 |
++void |
23479 |
++gr_remove_uid(const unsigned short loc) |
23480 |
++{ |
23481 |
++ unsigned short i; |
23482 |
++ |
23483 |
++ for (i = loc + 1; i < uid_used; i++) |
23484 |
++ uid_set[i - 1] = uid_set[i]; |
23485 |
++ |
23486 |
++ uid_used--; |
23487 |
++ |
23488 |
++ return; |
23489 |
++} |
23490 |
++ |
23491 |
++int |
23492 |
++gr_check_crash_uid(const uid_t uid) |
23493 |
++{ |
23494 |
++ int loc; |
23495 |
++ int ret = 0; |
23496 |
++ |
23497 |
++ if (unlikely(!gr_acl_is_enabled())) |
23498 |
++ return 0; |
23499 |
++ |
23500 |
++ spin_lock(&gr_uid_lock); |
23501 |
++ loc = gr_find_uid(uid); |
23502 |
++ |
23503 |
++ if (loc < 0) |
23504 |
++ goto out_unlock; |
23505 |
++ |
23506 |
++ if (time_before_eq(uid_set[loc].expires, get_seconds())) |
23507 |
++ gr_remove_uid(loc); |
23508 |
++ else |
23509 |
++ ret = 1; |
23510 |
++ |
23511 |
++out_unlock: |
23512 |
++ spin_unlock(&gr_uid_lock); |
23513 |
++ return ret; |
23514 |
++} |
23515 |
++ |
23516 |
++static __inline__ int |
23517 |
++proc_is_setxid(const struct task_struct *task) |
23518 |
++{ |
23519 |
++ if (task->uid != task->euid || task->uid != task->suid || |
23520 |
++ task->uid != task->fsuid) |
23521 |
++ return 1; |
23522 |
++ if (task->gid != task->egid || task->gid != task->sgid || |
23523 |
++ task->gid != task->fsgid) |
23524 |
++ return 1; |
23525 |
++ |
23526 |
++ return 0; |
23527 |
++} |
23528 |
++static __inline__ int |
23529 |
++gr_fake_force_sig(int sig, struct task_struct *t) |
23530 |
++{ |
23531 |
++ unsigned long int flags; |
23532 |
++ int ret, blocked, ignored; |
23533 |
++ struct k_sigaction *action; |
23534 |
++ |
23535 |
++ spin_lock_irqsave(&t->sighand->siglock, flags); |
23536 |
++ action = &t->sighand->action[sig-1]; |
23537 |
++ ignored = action->sa.sa_handler == SIG_IGN; |
23538 |
++ blocked = sigismember(&t->blocked, sig); |
23539 |
++ if (blocked || ignored) { |
23540 |
++ action->sa.sa_handler = SIG_DFL; |
23541 |
++ if (blocked) { |
23542 |
++ sigdelset(&t->blocked, sig); |
23543 |
++ recalc_sigpending_and_wake(t); |
23544 |
++ } |
23545 |
++ } |
23546 |
++ ret = specific_send_sig_info(sig, (void*)1L, t); |
23547 |
++ spin_unlock_irqrestore(&t->sighand->siglock, flags); |
23548 |
++ |
23549 |
++ return ret; |
23550 |
++} |
23551 |
++ |
23552 |
++void |
23553 |
++gr_handle_crash(struct task_struct *task, const int sig) |
23554 |
++{ |
23555 |
++ struct acl_subject_label *curr; |
23556 |
++ struct acl_subject_label *curr2; |
23557 |
++ struct task_struct *tsk, *tsk2; |
23558 |
++ |
23559 |
++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL) |
23560 |
++ return; |
23561 |
++ |
23562 |
++ if (unlikely(!gr_acl_is_enabled())) |
23563 |
++ return; |
23564 |
++ |
23565 |
++ curr = task->acl; |
23566 |
++ |
23567 |
++ if (!(curr->resmask & (1 << GR_CRASH_RES))) |
23568 |
++ return; |
23569 |
++ |
23570 |
++ if (time_before_eq(curr->expires, get_seconds())) { |
23571 |
++ curr->expires = 0; |
23572 |
++ curr->crashes = 0; |
23573 |
++ } |
23574 |
++ |
23575 |
++ curr->crashes++; |
23576 |
++ |
23577 |
++ if (!curr->expires) |
23578 |
++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max; |
23579 |
++ |
23580 |
++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) && |
23581 |
++ time_after(curr->expires, get_seconds())) { |
23582 |
++ if (task->uid && proc_is_setxid(task)) { |
23583 |
++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max); |
23584 |
++ spin_lock(&gr_uid_lock); |
23585 |
++ gr_insert_uid(task->uid, curr->expires); |
23586 |
++ spin_unlock(&gr_uid_lock); |
23587 |
++ curr->expires = 0; |
23588 |
++ curr->crashes = 0; |
23589 |
++ read_lock(&tasklist_lock); |
23590 |
++ do_each_thread(tsk2, tsk) { |
23591 |
++ if (tsk != task && tsk->uid == task->uid) |
23592 |
++ gr_fake_force_sig(SIGKILL, tsk); |
23593 |
++ } while_each_thread(tsk2, tsk); |
23594 |
++ read_unlock(&tasklist_lock); |
23595 |
++ } else { |
23596 |
++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max); |
23597 |
++ read_lock(&tasklist_lock); |
23598 |
++ do_each_thread(tsk2, tsk) { |
23599 |
++ if (likely(tsk != task)) { |
23600 |
++ curr2 = tsk->acl; |
23601 |
++ |
23602 |
++ if (curr2->device == curr->device && |
23603 |
++ curr2->inode == curr->inode) |
23604 |
++ gr_fake_force_sig(SIGKILL, tsk); |
23605 |
++ } |
23606 |
++ } while_each_thread(tsk2, tsk); |
23607 |
++ read_unlock(&tasklist_lock); |
23608 |
++ } |
23609 |
++ } |
23610 |
++ |
23611 |
++ return; |
23612 |
++} |
23613 |
++ |
23614 |
++int |
23615 |
++gr_check_crash_exec(const struct file *filp) |
23616 |
++{ |
23617 |
++ struct acl_subject_label *curr; |
23618 |
++ |
23619 |
++ if (unlikely(!gr_acl_is_enabled())) |
23620 |
++ return 0; |
23621 |
++ |
23622 |
++ read_lock(&gr_inode_lock); |
23623 |
++ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino, |
23624 |
++ filp->f_dentry->d_inode->i_sb->s_dev, |
23625 |
++ current->role); |
23626 |
++ read_unlock(&gr_inode_lock); |
23627 |
++ |
23628 |
++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) || |
23629 |
++ (!curr->crashes && !curr->expires)) |
23630 |
++ return 0; |
23631 |
++ |
23632 |
++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) && |
23633 |
++ time_after(curr->expires, get_seconds())) |
23634 |
++ return 1; |
23635 |
++ else if (time_before_eq(curr->expires, get_seconds())) { |
23636 |
++ curr->crashes = 0; |
23637 |
++ curr->expires = 0; |
23638 |
++ } |
23639 |
++ |
23640 |
++ return 0; |
23641 |
++} |
23642 |
++ |
23643 |
++void |
23644 |
++gr_handle_alertkill(struct task_struct *task) |
23645 |
++{ |
23646 |
++ struct acl_subject_label *curracl; |
23647 |
++ __u32 curr_ip; |
23648 |
++ struct task_struct *p, *p2; |
23649 |
++ |
23650 |
++ if (unlikely(!gr_acl_is_enabled())) |
23651 |
++ return; |
23652 |
++ |
23653 |
++ curracl = task->acl; |
23654 |
++ curr_ip = task->signal->curr_ip; |
23655 |
++ |
23656 |
++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) { |
23657 |
++ read_lock(&tasklist_lock); |
23658 |
++ do_each_thread(p2, p) { |
23659 |
++ if (p->signal->curr_ip == curr_ip) |
23660 |
++ gr_fake_force_sig(SIGKILL, p); |
23661 |
++ } while_each_thread(p2, p); |
23662 |
++ read_unlock(&tasklist_lock); |
23663 |
++ } else if (curracl->mode & GR_KILLPROC) |
23664 |
++ gr_fake_force_sig(SIGKILL, task); |
23665 |
++ |
23666 |
++ return; |
23667 |
++} |
23668 |
+diff -urNp linux-2.6.24.4/grsecurity/gracl_shm.c linux-2.6.24.4/grsecurity/gracl_shm.c |
23669 |
+--- linux-2.6.24.4/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500 |
23670 |
++++ linux-2.6.24.4/grsecurity/gracl_shm.c 2008-03-26 17:56:56.000000000 -0400 |
23671 |
+@@ -0,0 +1,33 @@ |
23672 |
++#include <linux/kernel.h> |
23673 |
++#include <linux/mm.h> |
23674 |
++#include <linux/sched.h> |
23675 |
++#include <linux/file.h> |
23676 |
++#include <linux/ipc.h> |
23677 |
++#include <linux/gracl.h> |
23678 |
++#include <linux/grsecurity.h> |
23679 |
++#include <linux/grinternal.h> |
23680 |
++ |
23681 |
++int |
23682 |
++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, |
23683 |
++ const time_t shm_createtime, const uid_t cuid, const int shmid) |
23684 |
++{ |
23685 |
++ struct task_struct *task; |
23686 |
++ |
23687 |
++ if (!gr_acl_is_enabled()) |
23688 |
++ return 1; |
23689 |
++ |
23690 |
++ task = find_task_by_pid(shm_cprid); |
23691 |
++ |
23692 |
++ if (unlikely(!task)) |
23693 |
++ task = find_task_by_pid(shm_lapid); |
23694 |
++ |
23695 |
++ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) || |
23696 |
++ (task->pid == shm_lapid)) && |
23697 |
++ (task->acl->mode & GR_PROTSHM) && |
23698 |
++ (task->acl != current->acl))) { |
23699 |
++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid); |
23700 |
++ return 0; |
23701 |
++ } |
23702 |
++ |
23703 |
++ return 1; |
23704 |
++} |
23705 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_chdir.c linux-2.6.24.4/grsecurity/grsec_chdir.c |
23706 |
+--- linux-2.6.24.4/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500 |
23707 |
++++ linux-2.6.24.4/grsecurity/grsec_chdir.c 2008-03-26 17:56:56.000000000 -0400 |
23708 |
+@@ -0,0 +1,19 @@ |
23709 |
++#include <linux/kernel.h> |
23710 |
++#include <linux/sched.h> |
23711 |
++#include <linux/fs.h> |
23712 |
++#include <linux/file.h> |
23713 |
++#include <linux/grsecurity.h> |
23714 |
++#include <linux/grinternal.h> |
23715 |
++ |
23716 |
++void |
23717 |
++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt) |
23718 |
++{ |
23719 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR |
23720 |
++ if ((grsec_enable_chdir && grsec_enable_group && |
23721 |
++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir && |
23722 |
++ !grsec_enable_group)) { |
23723 |
++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt); |
23724 |
++ } |
23725 |
++#endif |
23726 |
++ return; |
23727 |
++} |
23728 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_chroot.c linux-2.6.24.4/grsecurity/grsec_chroot.c |
23729 |
+--- linux-2.6.24.4/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500 |
23730 |
++++ linux-2.6.24.4/grsecurity/grsec_chroot.c 2008-03-26 17:56:56.000000000 -0400 |
23731 |
+@@ -0,0 +1,335 @@ |
23732 |
++#include <linux/kernel.h> |
23733 |
++#include <linux/module.h> |
23734 |
++#include <linux/sched.h> |
23735 |
++#include <linux/file.h> |
23736 |
++#include <linux/fs.h> |
23737 |
++#include <linux/mount.h> |
23738 |
++#include <linux/types.h> |
23739 |
++#include <linux/pid_namespace.h> |
23740 |
++#include <linux/grsecurity.h> |
23741 |
++#include <linux/grinternal.h> |
23742 |
++ |
23743 |
++int |
23744 |
++gr_handle_chroot_unix(const pid_t pid) |
23745 |
++{ |
23746 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX |
23747 |
++ struct pid *spid = NULL; |
23748 |
++ |
23749 |
++ if (unlikely(!grsec_enable_chroot_unix)) |
23750 |
++ return 1; |
23751 |
++ |
23752 |
++ if (likely(!proc_is_chrooted(current))) |
23753 |
++ return 1; |
23754 |
++ |
23755 |
++ read_lock(&tasklist_lock); |
23756 |
++ |
23757 |
++ spid = find_pid(pid); |
23758 |
++ if (spid) { |
23759 |
++ struct task_struct *p; |
23760 |
++ p = pid_task(spid, PIDTYPE_PID); |
23761 |
++ task_lock(p); |
23762 |
++ if (unlikely(!have_same_root(current, p))) { |
23763 |
++ task_unlock(p); |
23764 |
++ read_unlock(&tasklist_lock); |
23765 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG); |
23766 |
++ return 0; |
23767 |
++ } |
23768 |
++ task_unlock(p); |
23769 |
++ } |
23770 |
++ read_unlock(&tasklist_lock); |
23771 |
++#endif |
23772 |
++ return 1; |
23773 |
++} |
23774 |
++ |
23775 |
++int |
23776 |
++gr_handle_chroot_nice(void) |
23777 |
++{ |
23778 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE |
23779 |
++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) { |
23780 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG); |
23781 |
++ return -EPERM; |
23782 |
++ } |
23783 |
++#endif |
23784 |
++ return 0; |
23785 |
++} |
23786 |
++ |
23787 |
++int |
23788 |
++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval) |
23789 |
++{ |
23790 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE |
23791 |
++ if (grsec_enable_chroot_nice && (niceval < task_nice(p)) |
23792 |
++ && proc_is_chrooted(current)) { |
23793 |
++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid); |
23794 |
++ return -EACCES; |
23795 |
++ } |
23796 |
++#endif |
23797 |
++ return 0; |
23798 |
++} |
23799 |
++ |
23800 |
++int |
23801 |
++gr_handle_chroot_rawio(const struct inode *inode) |
23802 |
++{ |
23803 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS |
23804 |
++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) && |
23805 |
++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO)) |
23806 |
++ return 1; |
23807 |
++#endif |
23808 |
++ return 0; |
23809 |
++} |
23810 |
++ |
23811 |
++int |
23812 |
++gr_pid_is_chrooted(struct task_struct *p) |
23813 |
++{ |
23814 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK |
23815 |
++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL) |
23816 |
++ return 0; |
23817 |
++ |
23818 |
++ task_lock(p); |
23819 |
++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) || |
23820 |
++ !have_same_root(current, p)) { |
23821 |
++ task_unlock(p); |
23822 |
++ return 1; |
23823 |
++ } |
23824 |
++ task_unlock(p); |
23825 |
++#endif |
23826 |
++ return 0; |
23827 |
++} |
23828 |
++ |
23829 |
++EXPORT_SYMBOL(gr_pid_is_chrooted); |
23830 |
++ |
23831 |
++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR) |
23832 |
++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt) |
23833 |
++{ |
23834 |
++ struct dentry *dentry = (struct dentry *)u_dentry; |
23835 |
++ struct vfsmount *mnt = (struct vfsmount *)u_mnt; |
23836 |
++ struct dentry *realroot; |
23837 |
++ struct vfsmount *realrootmnt; |
23838 |
++ struct dentry *currentroot; |
23839 |
++ struct vfsmount *currentmnt; |
23840 |
++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper; |
23841 |
++ int ret = 1; |
23842 |
++ |
23843 |
++ read_lock(&reaper->fs->lock); |
23844 |
++ realrootmnt = mntget(reaper->fs->rootmnt); |
23845 |
++ realroot = dget(reaper->fs->root); |
23846 |
++ read_unlock(&reaper->fs->lock); |
23847 |
++ |
23848 |
++ read_lock(¤t->fs->lock); |
23849 |
++ currentmnt = mntget(current->fs->rootmnt); |
23850 |
++ currentroot = dget(current->fs->root); |
23851 |
++ read_unlock(¤t->fs->lock); |
23852 |
++ |
23853 |
++ spin_lock(&dcache_lock); |
23854 |
++ for (;;) { |
23855 |
++ if (unlikely((dentry == realroot && mnt == realrootmnt) |
23856 |
++ || (dentry == currentroot && mnt == currentmnt))) |
23857 |
++ break; |
23858 |
++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) { |
23859 |
++ if (mnt->mnt_parent == mnt) |
23860 |
++ break; |
23861 |
++ dentry = mnt->mnt_mountpoint; |
23862 |
++ mnt = mnt->mnt_parent; |
23863 |
++ continue; |
23864 |
++ } |
23865 |
++ dentry = dentry->d_parent; |
23866 |
++ } |
23867 |
++ spin_unlock(&dcache_lock); |
23868 |
++ |
23869 |
++ dput(currentroot); |
23870 |
++ mntput(currentmnt); |
23871 |
++ |
23872 |
++ /* access is outside of chroot */ |
23873 |
++ if (dentry == realroot && mnt == realrootmnt) |
23874 |
++ ret = 0; |
23875 |
++ |
23876 |
++ dput(realroot); |
23877 |
++ mntput(realrootmnt); |
23878 |
++ return ret; |
23879 |
++} |
23880 |
++#endif |
23881 |
++ |
23882 |
++int |
23883 |
++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt) |
23884 |
++{ |
23885 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR |
23886 |
++ if (!grsec_enable_chroot_fchdir) |
23887 |
++ return 1; |
23888 |
++ |
23889 |
++ if (!proc_is_chrooted(current)) |
23890 |
++ return 1; |
23891 |
++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) { |
23892 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt); |
23893 |
++ return 0; |
23894 |
++ } |
23895 |
++#endif |
23896 |
++ return 1; |
23897 |
++} |
23898 |
++ |
23899 |
++int |
23900 |
++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid, |
23901 |
++ const time_t shm_createtime) |
23902 |
++{ |
23903 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT |
23904 |
++ struct pid *pid = NULL; |
23905 |
++ time_t starttime; |
23906 |
++ |
23907 |
++ if (unlikely(!grsec_enable_chroot_shmat)) |
23908 |
++ return 1; |
23909 |
++ |
23910 |
++ if (likely(!proc_is_chrooted(current))) |
23911 |
++ return 1; |
23912 |
++ |
23913 |
++ read_lock(&tasklist_lock); |
23914 |
++ |
23915 |
++ pid = find_pid(shm_cprid); |
23916 |
++ if (pid) { |
23917 |
++ struct task_struct *p; |
23918 |
++ p = pid_task(pid, PIDTYPE_PID); |
23919 |
++ task_lock(p); |
23920 |
++ starttime = p->start_time.tv_sec; |
23921 |
++ if (unlikely(!have_same_root(current, p) && |
23922 |
++ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) { |
23923 |
++ task_unlock(p); |
23924 |
++ read_unlock(&tasklist_lock); |
23925 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG); |
23926 |
++ return 0; |
23927 |
++ } |
23928 |
++ task_unlock(p); |
23929 |
++ } else { |
23930 |
++ pid = find_pid(shm_lapid); |
23931 |
++ if (pid) { |
23932 |
++ struct task_struct *p; |
23933 |
++ p = pid_task(pid, PIDTYPE_PID); |
23934 |
++ task_lock(p); |
23935 |
++ if (unlikely(!have_same_root(current, p))) { |
23936 |
++ task_unlock(p); |
23937 |
++ read_unlock(&tasklist_lock); |
23938 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG); |
23939 |
++ return 0; |
23940 |
++ } |
23941 |
++ task_unlock(p); |
23942 |
++ } |
23943 |
++ } |
23944 |
++ |
23945 |
++ read_unlock(&tasklist_lock); |
23946 |
++#endif |
23947 |
++ return 1; |
23948 |
++} |
23949 |
++ |
23950 |
++void |
23951 |
++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt) |
23952 |
++{ |
23953 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG |
23954 |
++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current)) |
23955 |
++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt); |
23956 |
++#endif |
23957 |
++ return; |
23958 |
++} |
23959 |
++ |
23960 |
++int |
23961 |
++gr_handle_chroot_mknod(const struct dentry *dentry, |
23962 |
++ const struct vfsmount *mnt, const int mode) |
23963 |
++{ |
23964 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD |
23965 |
++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && |
23966 |
++ proc_is_chrooted(current)) { |
23967 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt); |
23968 |
++ return -EPERM; |
23969 |
++ } |
23970 |
++#endif |
23971 |
++ return 0; |
23972 |
++} |
23973 |
++ |
23974 |
++int |
23975 |
++gr_handle_chroot_mount(const struct dentry *dentry, |
23976 |
++ const struct vfsmount *mnt, const char *dev_name) |
23977 |
++{ |
23978 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT |
23979 |
++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) { |
23980 |
++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt); |
23981 |
++ return -EPERM; |
23982 |
++ } |
23983 |
++#endif |
23984 |
++ return 0; |
23985 |
++} |
23986 |
++ |
23987 |
++int |
23988 |
++gr_handle_chroot_pivot(void) |
23989 |
++{ |
23990 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT |
23991 |
++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) { |
23992 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG); |
23993 |
++ return -EPERM; |
23994 |
++ } |
23995 |
++#endif |
23996 |
++ return 0; |
23997 |
++} |
23998 |
++ |
23999 |
++int |
24000 |
++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt) |
24001 |
++{ |
24002 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE |
24003 |
++ if (grsec_enable_chroot_double && proc_is_chrooted(current) && |
24004 |
++ !gr_is_outside_chroot(dentry, mnt)) { |
24005 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt); |
24006 |
++ return -EPERM; |
24007 |
++ } |
24008 |
++#endif |
24009 |
++ return 0; |
24010 |
++} |
24011 |
++ |
24012 |
++void |
24013 |
++gr_handle_chroot_caps(struct task_struct *task) |
24014 |
++{ |
24015 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS |
24016 |
++ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) { |
24017 |
++ task->cap_permitted = |
24018 |
++ cap_drop(task->cap_permitted, GR_CHROOT_CAPS); |
24019 |
++ task->cap_inheritable = |
24020 |
++ cap_drop(task->cap_inheritable, GR_CHROOT_CAPS); |
24021 |
++ task->cap_effective = |
24022 |
++ cap_drop(task->cap_effective, GR_CHROOT_CAPS); |
24023 |
++ } |
24024 |
++#endif |
24025 |
++ return; |
24026 |
++} |
24027 |
++ |
24028 |
++int |
24029 |
++gr_handle_chroot_sysctl(const int op) |
24030 |
++{ |
24031 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL |
24032 |
++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current) |
24033 |
++ && (op & 002)) |
24034 |
++ return -EACCES; |
24035 |
++#endif |
24036 |
++ return 0; |
24037 |
++} |
24038 |
++ |
24039 |
++void |
24040 |
++gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt) |
24041 |
++{ |
24042 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR |
24043 |
++ if (grsec_enable_chroot_chdir) |
24044 |
++ set_fs_pwd(current->fs, mnt, dentry); |
24045 |
++#endif |
24046 |
++ return; |
24047 |
++} |
24048 |
++ |
24049 |
++int |
24050 |
++gr_handle_chroot_chmod(const struct dentry *dentry, |
24051 |
++ const struct vfsmount *mnt, const int mode) |
24052 |
++{ |
24053 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD |
24054 |
++ if (grsec_enable_chroot_chmod && |
24055 |
++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) && |
24056 |
++ proc_is_chrooted(current)) { |
24057 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt); |
24058 |
++ return -EPERM; |
24059 |
++ } |
24060 |
++#endif |
24061 |
++ return 0; |
24062 |
++} |
24063 |
++ |
24064 |
++#ifdef CONFIG_SECURITY |
24065 |
++EXPORT_SYMBOL(gr_handle_chroot_caps); |
24066 |
++#endif |
24067 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_disabled.c linux-2.6.24.4/grsecurity/grsec_disabled.c |
24068 |
+--- linux-2.6.24.4/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500 |
24069 |
++++ linux-2.6.24.4/grsecurity/grsec_disabled.c 2008-03-26 17:56:56.000000000 -0400 |
24070 |
+@@ -0,0 +1,418 @@ |
24071 |
++#include <linux/kernel.h> |
24072 |
++#include <linux/module.h> |
24073 |
++#include <linux/sched.h> |
24074 |
++#include <linux/file.h> |
24075 |
++#include <linux/fs.h> |
24076 |
++#include <linux/kdev_t.h> |
24077 |
++#include <linux/net.h> |
24078 |
++#include <linux/in.h> |
24079 |
++#include <linux/ip.h> |
24080 |
++#include <linux/skbuff.h> |
24081 |
++#include <linux/sysctl.h> |
24082 |
++ |
24083 |
++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS |
24084 |
++void |
24085 |
++pax_set_initial_flags(struct linux_binprm *bprm) |
24086 |
++{ |
24087 |
++ return; |
24088 |
++} |
24089 |
++#endif |
24090 |
++ |
24091 |
++#ifdef CONFIG_SYSCTL |
24092 |
++__u32 |
24093 |
++gr_handle_sysctl(const struct ctl_table * table, const int op) |
24094 |
++{ |
24095 |
++ return 0; |
24096 |
++} |
24097 |
++#endif |
24098 |
++ |
24099 |
++int |
24100 |
++gr_acl_is_enabled(void) |
24101 |
++{ |
24102 |
++ return 0; |
24103 |
++} |
24104 |
++ |
24105 |
++int |
24106 |
++gr_handle_rawio(const struct inode *inode) |
24107 |
++{ |
24108 |
++ return 0; |
24109 |
++} |
24110 |
++ |
24111 |
++void |
24112 |
++gr_acl_handle_psacct(struct task_struct *task, const long code) |
24113 |
++{ |
24114 |
++ return; |
24115 |
++} |
24116 |
++ |
24117 |
++int |
24118 |
++gr_handle_ptrace(struct task_struct *task, const long request) |
24119 |
++{ |
24120 |
++ return 0; |
24121 |
++} |
24122 |
++ |
24123 |
++int |
24124 |
++gr_handle_proc_ptrace(struct task_struct *task) |
24125 |
++{ |
24126 |
++ return 0; |
24127 |
++} |
24128 |
++ |
24129 |
++void |
24130 |
++gr_learn_resource(const struct task_struct *task, |
24131 |
++ const int res, const unsigned long wanted, const int gt) |
24132 |
++{ |
24133 |
++ return; |
24134 |
++} |
24135 |
++ |
24136 |
++int |
24137 |
++gr_set_acls(const int type) |
24138 |
++{ |
24139 |
++ return 0; |
24140 |
++} |
24141 |
++ |
24142 |
++int |
24143 |
++gr_check_hidden_task(const struct task_struct *tsk) |
24144 |
++{ |
24145 |
++ return 0; |
24146 |
++} |
24147 |
++ |
24148 |
++int |
24149 |
++gr_check_protected_task(const struct task_struct *task) |
24150 |
++{ |
24151 |
++ return 0; |
24152 |
++} |
24153 |
++ |
24154 |
++void |
24155 |
++gr_copy_label(struct task_struct *tsk) |
24156 |
++{ |
24157 |
++ return; |
24158 |
++} |
24159 |
++ |
24160 |
++void |
24161 |
++gr_set_pax_flags(struct task_struct *task) |
24162 |
++{ |
24163 |
++ return; |
24164 |
++} |
24165 |
++ |
24166 |
++int |
24167 |
++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt) |
24168 |
++{ |
24169 |
++ return 0; |
24170 |
++} |
24171 |
++ |
24172 |
++void |
24173 |
++gr_handle_delete(const ino_t ino, const dev_t dev) |
24174 |
++{ |
24175 |
++ return; |
24176 |
++} |
24177 |
++ |
24178 |
++void |
24179 |
++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt) |
24180 |
++{ |
24181 |
++ return; |
24182 |
++} |
24183 |
++ |
24184 |
++void |
24185 |
++gr_handle_crash(struct task_struct *task, const int sig) |
24186 |
++{ |
24187 |
++ return; |
24188 |
++} |
24189 |
++ |
24190 |
++int |
24191 |
++gr_check_crash_exec(const struct file *filp) |
24192 |
++{ |
24193 |
++ return 0; |
24194 |
++} |
24195 |
++ |
24196 |
++int |
24197 |
++gr_check_crash_uid(const uid_t uid) |
24198 |
++{ |
24199 |
++ return 0; |
24200 |
++} |
24201 |
++ |
24202 |
++void |
24203 |
++gr_handle_rename(struct inode *old_dir, struct inode *new_dir, |
24204 |
++ struct dentry *old_dentry, |
24205 |
++ struct dentry *new_dentry, |
24206 |
++ struct vfsmount *mnt, const __u8 replace) |
24207 |
++{ |
24208 |
++ return; |
24209 |
++} |
24210 |
++ |
24211 |
++int |
24212 |
++gr_search_socket(const int family, const int type, const int protocol) |
24213 |
++{ |
24214 |
++ return 1; |
24215 |
++} |
24216 |
++ |
24217 |
++int |
24218 |
++gr_search_connectbind(const int mode, const struct socket *sock, |
24219 |
++ const struct sockaddr_in *addr) |
24220 |
++{ |
24221 |
++ return 1; |
24222 |
++} |
24223 |
++ |
24224 |
++int |
24225 |
++gr_task_is_capable(struct task_struct *task, const int cap) |
24226 |
++{ |
24227 |
++ return 1; |
24228 |
++} |
24229 |
++ |
24230 |
++int |
24231 |
++gr_is_capable_nolog(const int cap) |
24232 |
++{ |
24233 |
++ return 1; |
24234 |
++} |
24235 |
++ |
24236 |
++void |
24237 |
++gr_handle_alertkill(struct task_struct *task) |
24238 |
++{ |
24239 |
++ return; |
24240 |
++} |
24241 |
++ |
24242 |
++__u32 |
24243 |
++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt) |
24244 |
++{ |
24245 |
++ return 1; |
24246 |
++} |
24247 |
++ |
24248 |
++__u32 |
24249 |
++gr_acl_handle_hidden_file(const struct dentry * dentry, |
24250 |
++ const struct vfsmount * mnt) |
24251 |
++{ |
24252 |
++ return 1; |
24253 |
++} |
24254 |
++ |
24255 |
++__u32 |
24256 |
++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt, |
24257 |
++ const int fmode) |
24258 |
++{ |
24259 |
++ return 1; |
24260 |
++} |
24261 |
++ |
24262 |
++__u32 |
24263 |
++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt) |
24264 |
++{ |
24265 |
++ return 1; |
24266 |
++} |
24267 |
++ |
24268 |
++__u32 |
24269 |
++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt) |
24270 |
++{ |
24271 |
++ return 1; |
24272 |
++} |
24273 |
++ |
24274 |
++int |
24275 |
++gr_acl_handle_mmap(const struct file *file, const unsigned long prot, |
24276 |
++ unsigned int *vm_flags) |
24277 |
++{ |
24278 |
++ return 1; |
24279 |
++} |
24280 |
++ |
24281 |
++__u32 |
24282 |
++gr_acl_handle_truncate(const struct dentry * dentry, |
24283 |
++ const struct vfsmount * mnt) |
24284 |
++{ |
24285 |
++ return 1; |
24286 |
++} |
24287 |
++ |
24288 |
++__u32 |
24289 |
++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt) |
24290 |
++{ |
24291 |
++ return 1; |
24292 |
++} |
24293 |
++ |
24294 |
++__u32 |
24295 |
++gr_acl_handle_access(const struct dentry * dentry, |
24296 |
++ const struct vfsmount * mnt, const int fmode) |
24297 |
++{ |
24298 |
++ return 1; |
24299 |
++} |
24300 |
++ |
24301 |
++__u32 |
24302 |
++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt, |
24303 |
++ mode_t mode) |
24304 |
++{ |
24305 |
++ return 1; |
24306 |
++} |
24307 |
++ |
24308 |
++__u32 |
24309 |
++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt, |
24310 |
++ mode_t mode) |
24311 |
++{ |
24312 |
++ return 1; |
24313 |
++} |
24314 |
++ |
24315 |
++__u32 |
24316 |
++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt) |
24317 |
++{ |
24318 |
++ return 1; |
24319 |
++} |
24320 |
++ |
24321 |
++void |
24322 |
++grsecurity_init(void) |
24323 |
++{ |
24324 |
++ return; |
24325 |
++} |
24326 |
++ |
24327 |
++__u32 |
24328 |
++gr_acl_handle_mknod(const struct dentry * new_dentry, |
24329 |
++ const struct dentry * parent_dentry, |
24330 |
++ const struct vfsmount * parent_mnt, |
24331 |
++ const int mode) |
24332 |
++{ |
24333 |
++ return 1; |
24334 |
++} |
24335 |
++ |
24336 |
++__u32 |
24337 |
++gr_acl_handle_mkdir(const struct dentry * new_dentry, |
24338 |
++ const struct dentry * parent_dentry, |
24339 |
++ const struct vfsmount * parent_mnt) |
24340 |
++{ |
24341 |
++ return 1; |
24342 |
++} |
24343 |
++ |
24344 |
++__u32 |
24345 |
++gr_acl_handle_symlink(const struct dentry * new_dentry, |
24346 |
++ const struct dentry * parent_dentry, |
24347 |
++ const struct vfsmount * parent_mnt, const char *from) |
24348 |
++{ |
24349 |
++ return 1; |
24350 |
++} |
24351 |
++ |
24352 |
++__u32 |
24353 |
++gr_acl_handle_link(const struct dentry * new_dentry, |
24354 |
++ const struct dentry * parent_dentry, |
24355 |
++ const struct vfsmount * parent_mnt, |
24356 |
++ const struct dentry * old_dentry, |
24357 |
++ const struct vfsmount * old_mnt, const char *to) |
24358 |
++{ |
24359 |
++ return 1; |
24360 |
++} |
24361 |
++ |
24362 |
++int |
24363 |
++gr_acl_handle_rename(const struct dentry *new_dentry, |
24364 |
++ const struct dentry *parent_dentry, |
24365 |
++ const struct vfsmount *parent_mnt, |
24366 |
++ const struct dentry *old_dentry, |
24367 |
++ const struct inode *old_parent_inode, |
24368 |
++ const struct vfsmount *old_mnt, const char *newname) |
24369 |
++{ |
24370 |
++ return 0; |
24371 |
++} |
24372 |
++ |
24373 |
++int |
24374 |
++gr_acl_handle_filldir(const struct file *file, const char *name, |
24375 |
++ const int namelen, const ino_t ino) |
24376 |
++{ |
24377 |
++ return 1; |
24378 |
++} |
24379 |
++ |
24380 |
++int |
24381 |
++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, |
24382 |
++ const time_t shm_createtime, const uid_t cuid, const int shmid) |
24383 |
++{ |
24384 |
++ return 1; |
24385 |
++} |
24386 |
++ |
24387 |
++int |
24388 |
++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr) |
24389 |
++{ |
24390 |
++ return 1; |
24391 |
++} |
24392 |
++ |
24393 |
++int |
24394 |
++gr_search_accept(const struct socket *sock) |
24395 |
++{ |
24396 |
++ return 1; |
24397 |
++} |
24398 |
++ |
24399 |
++int |
24400 |
++gr_search_listen(const struct socket *sock) |
24401 |
++{ |
24402 |
++ return 1; |
24403 |
++} |
24404 |
++ |
24405 |
++int |
24406 |
++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr) |
24407 |
++{ |
24408 |
++ return 1; |
24409 |
++} |
24410 |
++ |
24411 |
++__u32 |
24412 |
++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt) |
24413 |
++{ |
24414 |
++ return 1; |
24415 |
++} |
24416 |
++ |
24417 |
++__u32 |
24418 |
++gr_acl_handle_creat(const struct dentry * dentry, |
24419 |
++ const struct dentry * p_dentry, |
24420 |
++ const struct vfsmount * p_mnt, const int fmode, |
24421 |
++ const int imode) |
24422 |
++{ |
24423 |
++ return 1; |
24424 |
++} |
24425 |
++ |
24426 |
++void |
24427 |
++gr_acl_handle_exit(void) |
24428 |
++{ |
24429 |
++ return; |
24430 |
++} |
24431 |
++ |
24432 |
++int |
24433 |
++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot) |
24434 |
++{ |
24435 |
++ return 1; |
24436 |
++} |
24437 |
++ |
24438 |
++void |
24439 |
++gr_set_role_label(const uid_t uid, const gid_t gid) |
24440 |
++{ |
24441 |
++ return; |
24442 |
++} |
24443 |
++ |
24444 |
++int |
24445 |
++gr_acl_handle_procpidmem(const struct task_struct *task) |
24446 |
++{ |
24447 |
++ return 0; |
24448 |
++} |
24449 |
++ |
24450 |
++int |
24451 |
++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb) |
24452 |
++{ |
24453 |
++ return 1; |
24454 |
++} |
24455 |
++ |
24456 |
++int |
24457 |
++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr) |
24458 |
++{ |
24459 |
++ return 1; |
24460 |
++} |
24461 |
++ |
24462 |
++void |
24463 |
++gr_set_kernel_label(struct task_struct *task) |
24464 |
++{ |
24465 |
++ return; |
24466 |
++} |
24467 |
++ |
24468 |
++int |
24469 |
++gr_check_user_change(int real, int effective, int fs) |
24470 |
++{ |
24471 |
++ return 0; |
24472 |
++} |
24473 |
++ |
24474 |
++int |
24475 |
++gr_check_group_change(int real, int effective, int fs) |
24476 |
++{ |
24477 |
++ return 0; |
24478 |
++} |
24479 |
++ |
24480 |
++ |
24481 |
++EXPORT_SYMBOL(gr_task_is_capable); |
24482 |
++EXPORT_SYMBOL(gr_is_capable_nolog); |
24483 |
++EXPORT_SYMBOL(gr_learn_resource); |
24484 |
++EXPORT_SYMBOL(gr_set_kernel_label); |
24485 |
++#ifdef CONFIG_SECURITY |
24486 |
++EXPORT_SYMBOL(gr_check_user_change); |
24487 |
++EXPORT_SYMBOL(gr_check_group_change); |
24488 |
++#endif |
24489 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_exec.c linux-2.6.24.4/grsecurity/grsec_exec.c |
24490 |
+--- linux-2.6.24.4/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500 |
24491 |
++++ linux-2.6.24.4/grsecurity/grsec_exec.c 2008-03-26 17:56:56.000000000 -0400 |
24492 |
+@@ -0,0 +1,88 @@ |
24493 |
++#include <linux/kernel.h> |
24494 |
++#include <linux/sched.h> |
24495 |
++#include <linux/file.h> |
24496 |
++#include <linux/binfmts.h> |
24497 |
++#include <linux/smp_lock.h> |
24498 |
++#include <linux/fs.h> |
24499 |
++#include <linux/types.h> |
24500 |
++#include <linux/grdefs.h> |
24501 |
++#include <linux/grinternal.h> |
24502 |
++#include <linux/capability.h> |
24503 |
++ |
24504 |
++#include <asm/uaccess.h> |
24505 |
++ |
24506 |
++#ifdef CONFIG_GRKERNSEC_EXECLOG |
24507 |
++static char gr_exec_arg_buf[132]; |
24508 |
++static DECLARE_MUTEX(gr_exec_arg_sem); |
24509 |
++#endif |
24510 |
++ |
24511 |
++int |
24512 |
++gr_handle_nproc(void) |
24513 |
++{ |
24514 |
++#ifdef CONFIG_GRKERNSEC_EXECVE |
24515 |
++ if (grsec_enable_execve && current->user && |
24516 |
++ (atomic_read(¤t->user->processes) > |
24517 |
++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) && |
24518 |
++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) { |
24519 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG); |
24520 |
++ return -EAGAIN; |
24521 |
++ } |
24522 |
++#endif |
24523 |
++ return 0; |
24524 |
++} |
24525 |
++ |
24526 |
++void |
24527 |
++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv) |
24528 |
++{ |
24529 |
++#ifdef CONFIG_GRKERNSEC_EXECLOG |
24530 |
++ char *grarg = gr_exec_arg_buf; |
24531 |
++ unsigned int i, x, execlen = 0; |
24532 |
++ char c; |
24533 |
++ |
24534 |
++ if (!((grsec_enable_execlog && grsec_enable_group && |
24535 |
++ in_group_p(grsec_audit_gid)) |
24536 |
++ || (grsec_enable_execlog && !grsec_enable_group))) |
24537 |
++ return; |
24538 |
++ |
24539 |
++ down(&gr_exec_arg_sem); |
24540 |
++ memset(grarg, 0, sizeof(gr_exec_arg_buf)); |
24541 |
++ |
24542 |
++ if (unlikely(argv == NULL)) |
24543 |
++ goto log; |
24544 |
++ |
24545 |
++ for (i = 0; i < bprm->argc && execlen < 128; i++) { |
24546 |
++ const char __user *p; |
24547 |
++ unsigned int len; |
24548 |
++ |
24549 |
++ if (copy_from_user(&p, argv + i, sizeof(p))) |
24550 |
++ goto log; |
24551 |
++ if (!p) |
24552 |
++ goto log; |
24553 |
++ len = strnlen_user(p, 128 - execlen); |
24554 |
++ if (len > 128 - execlen) |
24555 |
++ len = 128 - execlen; |
24556 |
++ else if (len > 0) |
24557 |
++ len--; |
24558 |
++ if (copy_from_user(grarg + execlen, p, len)) |
24559 |
++ goto log; |
24560 |
++ |
24561 |
++ /* rewrite unprintable characters */ |
24562 |
++ for (x = 0; x < len; x++) { |
24563 |
++ c = *(grarg + execlen + x); |
24564 |
++ if (c < 32 || c > 126) |
24565 |
++ *(grarg + execlen + x) = ' '; |
24566 |
++ } |
24567 |
++ |
24568 |
++ execlen += len; |
24569 |
++ *(grarg + execlen) = ' '; |
24570 |
++ *(grarg + execlen + 1) = '\0'; |
24571 |
++ execlen++; |
24572 |
++ } |
24573 |
++ |
24574 |
++ log: |
24575 |
++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry, |
24576 |
++ bprm->file->f_vfsmnt, grarg); |
24577 |
++ up(&gr_exec_arg_sem); |
24578 |
++#endif |
24579 |
++ return; |
24580 |
++} |
24581 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_fifo.c linux-2.6.24.4/grsecurity/grsec_fifo.c |
24582 |
+--- linux-2.6.24.4/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500 |
24583 |
++++ linux-2.6.24.4/grsecurity/grsec_fifo.c 2008-03-26 17:56:56.000000000 -0400 |
24584 |
+@@ -0,0 +1,22 @@ |
24585 |
++#include <linux/kernel.h> |
24586 |
++#include <linux/sched.h> |
24587 |
++#include <linux/fs.h> |
24588 |
++#include <linux/file.h> |
24589 |
++#include <linux/grinternal.h> |
24590 |
++ |
24591 |
++int |
24592 |
++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt, |
24593 |
++ const struct dentry *dir, const int flag, const int acc_mode) |
24594 |
++{ |
24595 |
++#ifdef CONFIG_GRKERNSEC_FIFO |
24596 |
++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) && |
24597 |
++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) && |
24598 |
++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) && |
24599 |
++ (current->fsuid != dentry->d_inode->i_uid)) { |
24600 |
++ if (!generic_permission(dentry->d_inode, acc_mode, NULL)) |
24601 |
++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid); |
24602 |
++ return -EACCES; |
24603 |
++ } |
24604 |
++#endif |
24605 |
++ return 0; |
24606 |
++} |
24607 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_fork.c linux-2.6.24.4/grsecurity/grsec_fork.c |
24608 |
+--- linux-2.6.24.4/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500 |
24609 |
++++ linux-2.6.24.4/grsecurity/grsec_fork.c 2008-03-26 17:56:56.000000000 -0400 |
24610 |
+@@ -0,0 +1,15 @@ |
24611 |
++#include <linux/kernel.h> |
24612 |
++#include <linux/sched.h> |
24613 |
++#include <linux/grsecurity.h> |
24614 |
++#include <linux/grinternal.h> |
24615 |
++#include <linux/errno.h> |
24616 |
++ |
24617 |
++void |
24618 |
++gr_log_forkfail(const int retval) |
24619 |
++{ |
24620 |
++#ifdef CONFIG_GRKERNSEC_FORKFAIL |
24621 |
++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR) |
24622 |
++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval); |
24623 |
++#endif |
24624 |
++ return; |
24625 |
++} |
24626 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_init.c linux-2.6.24.4/grsecurity/grsec_init.c |
24627 |
+--- linux-2.6.24.4/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500 |
24628 |
++++ linux-2.6.24.4/grsecurity/grsec_init.c 2008-03-26 17:56:56.000000000 -0400 |
24629 |
+@@ -0,0 +1,226 @@ |
24630 |
++#include <linux/kernel.h> |
24631 |
++#include <linux/sched.h> |
24632 |
++#include <linux/mm.h> |
24633 |
++#include <linux/smp_lock.h> |
24634 |
++#include <linux/gracl.h> |
24635 |
++#include <linux/slab.h> |
24636 |
++#include <linux/vmalloc.h> |
24637 |
++#include <linux/percpu.h> |
24638 |
++ |
24639 |
++int grsec_enable_link; |
24640 |
++int grsec_enable_dmesg; |
24641 |
++int grsec_enable_fifo; |
24642 |
++int grsec_enable_execve; |
24643 |
++int grsec_enable_execlog; |
24644 |
++int grsec_enable_signal; |
24645 |
++int grsec_enable_forkfail; |
24646 |
++int grsec_enable_time; |
24647 |
++int grsec_enable_audit_textrel; |
24648 |
++int grsec_enable_group; |
24649 |
++int grsec_audit_gid; |
24650 |
++int grsec_enable_chdir; |
24651 |
++int grsec_enable_audit_ipc; |
24652 |
++int grsec_enable_mount; |
24653 |
++int grsec_enable_chroot_findtask; |
24654 |
++int grsec_enable_chroot_mount; |
24655 |
++int grsec_enable_chroot_shmat; |
24656 |
++int grsec_enable_chroot_fchdir; |
24657 |
++int grsec_enable_chroot_double; |
24658 |
++int grsec_enable_chroot_pivot; |
24659 |
++int grsec_enable_chroot_chdir; |
24660 |
++int grsec_enable_chroot_chmod; |
24661 |
++int grsec_enable_chroot_mknod; |
24662 |
++int grsec_enable_chroot_nice; |
24663 |
++int grsec_enable_chroot_execlog; |
24664 |
++int grsec_enable_chroot_caps; |
24665 |
++int grsec_enable_chroot_sysctl; |
24666 |
++int grsec_enable_chroot_unix; |
24667 |
++int grsec_enable_tpe; |
24668 |
++int grsec_tpe_gid; |
24669 |
++int grsec_enable_tpe_all; |
24670 |
++int grsec_enable_socket_all; |
24671 |
++int grsec_socket_all_gid; |
24672 |
++int grsec_enable_socket_client; |
24673 |
++int grsec_socket_client_gid; |
24674 |
++int grsec_enable_socket_server; |
24675 |
++int grsec_socket_server_gid; |
24676 |
++int grsec_resource_logging; |
24677 |
++int grsec_lock; |
24678 |
++ |
24679 |
++spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED; |
24680 |
++unsigned long grsec_alert_wtime = 0; |
24681 |
++unsigned long grsec_alert_fyet = 0; |
24682 |
++ |
24683 |
++spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED; |
24684 |
++ |
24685 |
++rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED; |
24686 |
++ |
24687 |
++char *gr_shared_page[4]; |
24688 |
++ |
24689 |
++char *gr_alert_log_fmt; |
24690 |
++char *gr_audit_log_fmt; |
24691 |
++char *gr_alert_log_buf; |
24692 |
++char *gr_audit_log_buf; |
24693 |
++ |
24694 |
++extern struct gr_arg *gr_usermode; |
24695 |
++extern unsigned char *gr_system_salt; |
24696 |
++extern unsigned char *gr_system_sum; |
24697 |
++ |
24698 |
++void |
24699 |
++grsecurity_init(void) |
24700 |
++{ |
24701 |
++ int j; |
24702 |
++ /* create the per-cpu shared pages */ |
24703 |
++ |
24704 |
++ for (j = 0; j < 4; j++) { |
24705 |
++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE); |
24706 |
++ if (gr_shared_page[j] == NULL) { |
24707 |
++ panic("Unable to allocate grsecurity shared page"); |
24708 |
++ return; |
24709 |
++ } |
24710 |
++ } |
24711 |
++ |
24712 |
++ /* allocate log buffers */ |
24713 |
++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL); |
24714 |
++ if (!gr_alert_log_fmt) { |
24715 |
++ panic("Unable to allocate grsecurity alert log format buffer"); |
24716 |
++ return; |
24717 |
++ } |
24718 |
++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL); |
24719 |
++ if (!gr_audit_log_fmt) { |
24720 |
++ panic("Unable to allocate grsecurity audit log format buffer"); |
24721 |
++ return; |
24722 |
++ } |
24723 |
++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL); |
24724 |
++ if (!gr_alert_log_buf) { |
24725 |
++ panic("Unable to allocate grsecurity alert log buffer"); |
24726 |
++ return; |
24727 |
++ } |
24728 |
++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL); |
24729 |
++ if (!gr_audit_log_buf) { |
24730 |
++ panic("Unable to allocate grsecurity audit log buffer"); |
24731 |
++ return; |
24732 |
++ } |
24733 |
++ |
24734 |
++ /* allocate memory for authentication structure */ |
24735 |
++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL); |
24736 |
++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL); |
24737 |
++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL); |
24738 |
++ |
24739 |
++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) { |
24740 |
++ panic("Unable to allocate grsecurity authentication structure"); |
24741 |
++ return; |
24742 |
++ } |
24743 |
++ |
24744 |
++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON) |
24745 |
++#ifndef CONFIG_GRKERNSEC_SYSCTL |
24746 |
++ grsec_lock = 1; |
24747 |
++#endif |
24748 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL |
24749 |
++ grsec_enable_audit_textrel = 1; |
24750 |
++#endif |
24751 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP |
24752 |
++ grsec_enable_group = 1; |
24753 |
++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID; |
24754 |
++#endif |
24755 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR |
24756 |
++ grsec_enable_chdir = 1; |
24757 |
++#endif |
24758 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
24759 |
++ grsec_enable_audit_ipc = 1; |
24760 |
++#endif |
24761 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT |
24762 |
++ grsec_enable_mount = 1; |
24763 |
++#endif |
24764 |
++#ifdef CONFIG_GRKERNSEC_LINK |
24765 |
++ grsec_enable_link = 1; |
24766 |
++#endif |
24767 |
++#ifdef CONFIG_GRKERNSEC_DMESG |
24768 |
++ grsec_enable_dmesg = 1; |
24769 |
++#endif |
24770 |
++#ifdef CONFIG_GRKERNSEC_FIFO |
24771 |
++ grsec_enable_fifo = 1; |
24772 |
++#endif |
24773 |
++#ifdef CONFIG_GRKERNSEC_EXECVE |
24774 |
++ grsec_enable_execve = 1; |
24775 |
++#endif |
24776 |
++#ifdef CONFIG_GRKERNSEC_EXECLOG |
24777 |
++ grsec_enable_execlog = 1; |
24778 |
++#endif |
24779 |
++#ifdef CONFIG_GRKERNSEC_SIGNAL |
24780 |
++ grsec_enable_signal = 1; |
24781 |
++#endif |
24782 |
++#ifdef CONFIG_GRKERNSEC_FORKFAIL |
24783 |
++ grsec_enable_forkfail = 1; |
24784 |
++#endif |
24785 |
++#ifdef CONFIG_GRKERNSEC_TIME |
24786 |
++ grsec_enable_time = 1; |
24787 |
++#endif |
24788 |
++#ifdef CONFIG_GRKERNSEC_RESLOG |
24789 |
++ grsec_resource_logging = 1; |
24790 |
++#endif |
24791 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK |
24792 |
++ grsec_enable_chroot_findtask = 1; |
24793 |
++#endif |
24794 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX |
24795 |
++ grsec_enable_chroot_unix = 1; |
24796 |
++#endif |
24797 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT |
24798 |
++ grsec_enable_chroot_mount = 1; |
24799 |
++#endif |
24800 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR |
24801 |
++ grsec_enable_chroot_fchdir = 1; |
24802 |
++#endif |
24803 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT |
24804 |
++ grsec_enable_chroot_shmat = 1; |
24805 |
++#endif |
24806 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE |
24807 |
++ grsec_enable_chroot_double = 1; |
24808 |
++#endif |
24809 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT |
24810 |
++ grsec_enable_chroot_pivot = 1; |
24811 |
++#endif |
24812 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR |
24813 |
++ grsec_enable_chroot_chdir = 1; |
24814 |
++#endif |
24815 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD |
24816 |
++ grsec_enable_chroot_chmod = 1; |
24817 |
++#endif |
24818 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD |
24819 |
++ grsec_enable_chroot_mknod = 1; |
24820 |
++#endif |
24821 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE |
24822 |
++ grsec_enable_chroot_nice = 1; |
24823 |
++#endif |
24824 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG |
24825 |
++ grsec_enable_chroot_execlog = 1; |
24826 |
++#endif |
24827 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS |
24828 |
++ grsec_enable_chroot_caps = 1; |
24829 |
++#endif |
24830 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL |
24831 |
++ grsec_enable_chroot_sysctl = 1; |
24832 |
++#endif |
24833 |
++#ifdef CONFIG_GRKERNSEC_TPE |
24834 |
++ grsec_enable_tpe = 1; |
24835 |
++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID; |
24836 |
++#ifdef CONFIG_GRKERNSEC_TPE_ALL |
24837 |
++ grsec_enable_tpe_all = 1; |
24838 |
++#endif |
24839 |
++#endif |
24840 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL |
24841 |
++ grsec_enable_socket_all = 1; |
24842 |
++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID; |
24843 |
++#endif |
24844 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT |
24845 |
++ grsec_enable_socket_client = 1; |
24846 |
++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID; |
24847 |
++#endif |
24848 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER |
24849 |
++ grsec_enable_socket_server = 1; |
24850 |
++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID; |
24851 |
++#endif |
24852 |
++#endif |
24853 |
++ |
24854 |
++ return; |
24855 |
++} |
24856 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_ipc.c linux-2.6.24.4/grsecurity/grsec_ipc.c |
24857 |
+--- linux-2.6.24.4/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500 |
24858 |
++++ linux-2.6.24.4/grsecurity/grsec_ipc.c 2008-03-26 17:56:56.000000000 -0400 |
24859 |
+@@ -0,0 +1,81 @@ |
24860 |
++#include <linux/kernel.h> |
24861 |
++#include <linux/sched.h> |
24862 |
++#include <linux/types.h> |
24863 |
++#include <linux/ipc.h> |
24864 |
++#include <linux/grsecurity.h> |
24865 |
++#include <linux/grinternal.h> |
24866 |
++ |
24867 |
++void |
24868 |
++gr_log_msgget(const int ret, const int msgflg) |
24869 |
++{ |
24870 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
24871 |
++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) && |
24872 |
++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc && |
24873 |
++ !grsec_enable_group)) && (ret >= 0) |
24874 |
++ && (msgflg & IPC_CREAT)) |
24875 |
++ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG); |
24876 |
++#endif |
24877 |
++ return; |
24878 |
++} |
24879 |
++ |
24880 |
++void |
24881 |
++gr_log_msgrm(const uid_t uid, const uid_t cuid) |
24882 |
++{ |
24883 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
24884 |
++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) && |
24885 |
++ grsec_enable_audit_ipc) || |
24886 |
++ (grsec_enable_audit_ipc && !grsec_enable_group)) |
24887 |
++ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid); |
24888 |
++#endif |
24889 |
++ return; |
24890 |
++} |
24891 |
++ |
24892 |
++void |
24893 |
++gr_log_semget(const int err, const int semflg) |
24894 |
++{ |
24895 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
24896 |
++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) && |
24897 |
++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc && |
24898 |
++ !grsec_enable_group)) && (err >= 0) |
24899 |
++ && (semflg & IPC_CREAT)) |
24900 |
++ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG); |
24901 |
++#endif |
24902 |
++ return; |
24903 |
++} |
24904 |
++ |
24905 |
++void |
24906 |
++gr_log_semrm(const uid_t uid, const uid_t cuid) |
24907 |
++{ |
24908 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
24909 |
++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) && |
24910 |
++ grsec_enable_audit_ipc) || |
24911 |
++ (grsec_enable_audit_ipc && !grsec_enable_group)) |
24912 |
++ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid); |
24913 |
++#endif |
24914 |
++ return; |
24915 |
++} |
24916 |
++ |
24917 |
++void |
24918 |
++gr_log_shmget(const int err, const int shmflg, const size_t size) |
24919 |
++{ |
24920 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
24921 |
++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) && |
24922 |
++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc && |
24923 |
++ !grsec_enable_group)) && (err >= 0) |
24924 |
++ && (shmflg & IPC_CREAT)) |
24925 |
++ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size); |
24926 |
++#endif |
24927 |
++ return; |
24928 |
++} |
24929 |
++ |
24930 |
++void |
24931 |
++gr_log_shmrm(const uid_t uid, const uid_t cuid) |
24932 |
++{ |
24933 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
24934 |
++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) && |
24935 |
++ grsec_enable_audit_ipc) || |
24936 |
++ (grsec_enable_audit_ipc && !grsec_enable_group)) |
24937 |
++ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid); |
24938 |
++#endif |
24939 |
++ return; |
24940 |
++} |
24941 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_link.c linux-2.6.24.4/grsecurity/grsec_link.c |
24942 |
+--- linux-2.6.24.4/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500 |
24943 |
++++ linux-2.6.24.4/grsecurity/grsec_link.c 2008-03-26 17:56:56.000000000 -0400 |
24944 |
+@@ -0,0 +1,39 @@ |
24945 |
++#include <linux/kernel.h> |
24946 |
++#include <linux/sched.h> |
24947 |
++#include <linux/fs.h> |
24948 |
++#include <linux/file.h> |
24949 |
++#include <linux/grinternal.h> |
24950 |
++ |
24951 |
++int |
24952 |
++gr_handle_follow_link(const struct inode *parent, |
24953 |
++ const struct inode *inode, |
24954 |
++ const struct dentry *dentry, const struct vfsmount *mnt) |
24955 |
++{ |
24956 |
++#ifdef CONFIG_GRKERNSEC_LINK |
24957 |
++ if (grsec_enable_link && S_ISLNK(inode->i_mode) && |
24958 |
++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) && |
24959 |
++ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) { |
24960 |
++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid); |
24961 |
++ return -EACCES; |
24962 |
++ } |
24963 |
++#endif |
24964 |
++ return 0; |
24965 |
++} |
24966 |
++ |
24967 |
++int |
24968 |
++gr_handle_hardlink(const struct dentry *dentry, |
24969 |
++ const struct vfsmount *mnt, |
24970 |
++ struct inode *inode, const int mode, const char *to) |
24971 |
++{ |
24972 |
++#ifdef CONFIG_GRKERNSEC_LINK |
24973 |
++ if (grsec_enable_link && current->fsuid != inode->i_uid && |
24974 |
++ (!S_ISREG(mode) || (mode & S_ISUID) || |
24975 |
++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) || |
24976 |
++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) && |
24977 |
++ !capable(CAP_FOWNER) && current->uid) { |
24978 |
++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to); |
24979 |
++ return -EPERM; |
24980 |
++ } |
24981 |
++#endif |
24982 |
++ return 0; |
24983 |
++} |
24984 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_log.c linux-2.6.24.4/grsecurity/grsec_log.c |
24985 |
+--- linux-2.6.24.4/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500 |
24986 |
++++ linux-2.6.24.4/grsecurity/grsec_log.c 2008-03-26 17:56:56.000000000 -0400 |
24987 |
+@@ -0,0 +1,269 @@ |
24988 |
++#include <linux/kernel.h> |
24989 |
++#include <linux/sched.h> |
24990 |
++#include <linux/file.h> |
24991 |
++#include <linux/tty.h> |
24992 |
++#include <linux/fs.h> |
24993 |
++#include <linux/grinternal.h> |
24994 |
++ |
24995 |
++#define BEGIN_LOCKS(x) \ |
24996 |
++ read_lock(&tasklist_lock); \ |
24997 |
++ read_lock(&grsec_exec_file_lock); \ |
24998 |
++ if (x != GR_DO_AUDIT) \ |
24999 |
++ spin_lock(&grsec_alert_lock); \ |
25000 |
++ else \ |
25001 |
++ spin_lock(&grsec_audit_lock) |
25002 |
++ |
25003 |
++#define END_LOCKS(x) \ |
25004 |
++ if (x != GR_DO_AUDIT) \ |
25005 |
++ spin_unlock(&grsec_alert_lock); \ |
25006 |
++ else \ |
25007 |
++ spin_unlock(&grsec_audit_lock); \ |
25008 |
++ read_unlock(&grsec_exec_file_lock); \ |
25009 |
++ read_unlock(&tasklist_lock); \ |
25010 |
++ if (x == GR_DONT_AUDIT) \ |
25011 |
++ gr_handle_alertkill(current) |
25012 |
++ |
25013 |
++enum { |
25014 |
++ FLOODING, |
25015 |
++ NO_FLOODING |
25016 |
++}; |
25017 |
++ |
25018 |
++extern char *gr_alert_log_fmt; |
25019 |
++extern char *gr_audit_log_fmt; |
25020 |
++extern char *gr_alert_log_buf; |
25021 |
++extern char *gr_audit_log_buf; |
25022 |
++ |
25023 |
++static int gr_log_start(int audit) |
25024 |
++{ |
25025 |
++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT; |
25026 |
++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt; |
25027 |
++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; |
25028 |
++ |
25029 |
++ if (audit == GR_DO_AUDIT) |
25030 |
++ goto set_fmt; |
25031 |
++ |
25032 |
++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { |
25033 |
++ grsec_alert_wtime = jiffies; |
25034 |
++ grsec_alert_fyet = 0; |
25035 |
++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { |
25036 |
++ grsec_alert_fyet++; |
25037 |
++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { |
25038 |
++ grsec_alert_wtime = jiffies; |
25039 |
++ grsec_alert_fyet++; |
25040 |
++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); |
25041 |
++ return FLOODING; |
25042 |
++ } else return FLOODING; |
25043 |
++ |
25044 |
++set_fmt: |
25045 |
++ memset(buf, 0, PAGE_SIZE); |
25046 |
++ if (current->signal->curr_ip && gr_acl_is_enabled()) { |
25047 |
++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) "); |
25048 |
++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename); |
25049 |
++ } else if (current->signal->curr_ip) { |
25050 |
++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: "); |
25051 |
++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip)); |
25052 |
++ } else if (gr_acl_is_enabled()) { |
25053 |
++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) "); |
25054 |
++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename); |
25055 |
++ } else { |
25056 |
++ sprintf(fmt, "%s%s", loglevel, "grsec: "); |
25057 |
++ strcpy(buf, fmt); |
25058 |
++ } |
25059 |
++ |
25060 |
++ return NO_FLOODING; |
25061 |
++} |
25062 |
++ |
25063 |
++static void gr_log_middle(int audit, const char *msg, va_list ap) |
25064 |
++{ |
25065 |
++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; |
25066 |
++ unsigned int len = strlen(buf); |
25067 |
++ |
25068 |
++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap); |
25069 |
++ |
25070 |
++ return; |
25071 |
++} |
25072 |
++ |
25073 |
++static void gr_log_middle_varargs(int audit, const char *msg, ...) |
25074 |
++{ |
25075 |
++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; |
25076 |
++ unsigned int len = strlen(buf); |
25077 |
++ va_list ap; |
25078 |
++ |
25079 |
++ va_start(ap, msg); |
25080 |
++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap); |
25081 |
++ va_end(ap); |
25082 |
++ |
25083 |
++ return; |
25084 |
++} |
25085 |
++ |
25086 |
++static void gr_log_end(int audit) |
25087 |
++{ |
25088 |
++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; |
25089 |
++ unsigned int len = strlen(buf); |
25090 |
++ |
25091 |
++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current)); |
25092 |
++ printk("%s\n", buf); |
25093 |
++ |
25094 |
++ return; |
25095 |
++} |
25096 |
++ |
25097 |
++void gr_log_varargs(int audit, const char *msg, int argtypes, ...) |
25098 |
++{ |
25099 |
++ int logtype; |
25100 |
++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied"; |
25101 |
++ char *str1, *str2, *str3; |
25102 |
++ int num1, num2; |
25103 |
++ unsigned long ulong1, ulong2; |
25104 |
++ struct dentry *dentry; |
25105 |
++ struct vfsmount *mnt; |
25106 |
++ struct file *file; |
25107 |
++ struct task_struct *task; |
25108 |
++ va_list ap; |
25109 |
++ |
25110 |
++ BEGIN_LOCKS(audit); |
25111 |
++ logtype = gr_log_start(audit); |
25112 |
++ if (logtype == FLOODING) { |
25113 |
++ END_LOCKS(audit); |
25114 |
++ return; |
25115 |
++ } |
25116 |
++ va_start(ap, argtypes); |
25117 |
++ switch (argtypes) { |
25118 |
++ case GR_TTYSNIFF: |
25119 |
++ task = va_arg(ap, struct task_struct *); |
25120 |
++ 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); |
25121 |
++ break; |
25122 |
++ case GR_SYSCTL_HIDDEN: |
25123 |
++ str1 = va_arg(ap, char *); |
25124 |
++ gr_log_middle_varargs(audit, msg, result, str1); |
25125 |
++ break; |
25126 |
++ case GR_RBAC: |
25127 |
++ dentry = va_arg(ap, struct dentry *); |
25128 |
++ mnt = va_arg(ap, struct vfsmount *); |
25129 |
++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt)); |
25130 |
++ break; |
25131 |
++ case GR_RBAC_STR: |
25132 |
++ dentry = va_arg(ap, struct dentry *); |
25133 |
++ mnt = va_arg(ap, struct vfsmount *); |
25134 |
++ str1 = va_arg(ap, char *); |
25135 |
++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1); |
25136 |
++ break; |
25137 |
++ case GR_STR_RBAC: |
25138 |
++ str1 = va_arg(ap, char *); |
25139 |
++ dentry = va_arg(ap, struct dentry *); |
25140 |
++ mnt = va_arg(ap, struct vfsmount *); |
25141 |
++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt)); |
25142 |
++ break; |
25143 |
++ case GR_RBAC_MODE2: |
25144 |
++ dentry = va_arg(ap, struct dentry *); |
25145 |
++ mnt = va_arg(ap, struct vfsmount *); |
25146 |
++ str1 = va_arg(ap, char *); |
25147 |
++ str2 = va_arg(ap, char *); |
25148 |
++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2); |
25149 |
++ break; |
25150 |
++ case GR_RBAC_MODE3: |
25151 |
++ dentry = va_arg(ap, struct dentry *); |
25152 |
++ mnt = va_arg(ap, struct vfsmount *); |
25153 |
++ str1 = va_arg(ap, char *); |
25154 |
++ str2 = va_arg(ap, char *); |
25155 |
++ str3 = va_arg(ap, char *); |
25156 |
++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3); |
25157 |
++ break; |
25158 |
++ case GR_FILENAME: |
25159 |
++ dentry = va_arg(ap, struct dentry *); |
25160 |
++ mnt = va_arg(ap, struct vfsmount *); |
25161 |
++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt)); |
25162 |
++ break; |
25163 |
++ case GR_STR_FILENAME: |
25164 |
++ str1 = va_arg(ap, char *); |
25165 |
++ dentry = va_arg(ap, struct dentry *); |
25166 |
++ mnt = va_arg(ap, struct vfsmount *); |
25167 |
++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt)); |
25168 |
++ break; |
25169 |
++ case GR_FILENAME_STR: |
25170 |
++ dentry = va_arg(ap, struct dentry *); |
25171 |
++ mnt = va_arg(ap, struct vfsmount *); |
25172 |
++ str1 = va_arg(ap, char *); |
25173 |
++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1); |
25174 |
++ break; |
25175 |
++ case GR_FILENAME_TWO_INT: |
25176 |
++ dentry = va_arg(ap, struct dentry *); |
25177 |
++ mnt = va_arg(ap, struct vfsmount *); |
25178 |
++ num1 = va_arg(ap, int); |
25179 |
++ num2 = va_arg(ap, int); |
25180 |
++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2); |
25181 |
++ break; |
25182 |
++ case GR_FILENAME_TWO_INT_STR: |
25183 |
++ dentry = va_arg(ap, struct dentry *); |
25184 |
++ mnt = va_arg(ap, struct vfsmount *); |
25185 |
++ num1 = va_arg(ap, int); |
25186 |
++ num2 = va_arg(ap, int); |
25187 |
++ str1 = va_arg(ap, char *); |
25188 |
++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1); |
25189 |
++ break; |
25190 |
++ case GR_TEXTREL: |
25191 |
++ file = va_arg(ap, struct file *); |
25192 |
++ ulong1 = va_arg(ap, unsigned long); |
25193 |
++ ulong2 = va_arg(ap, unsigned long); |
25194 |
++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2); |
25195 |
++ break; |
25196 |
++ case GR_PTRACE: |
25197 |
++ task = va_arg(ap, struct task_struct *); |
25198 |
++ 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); |
25199 |
++ break; |
25200 |
++ case GR_RESOURCE: |
25201 |
++ task = va_arg(ap, struct task_struct *); |
25202 |
++ ulong1 = va_arg(ap, unsigned long); |
25203 |
++ str1 = va_arg(ap, char *); |
25204 |
++ ulong2 = va_arg(ap, unsigned long); |
25205 |
++ 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); |
25206 |
++ break; |
25207 |
++ case GR_CAP: |
25208 |
++ task = va_arg(ap, struct task_struct *); |
25209 |
++ str1 = va_arg(ap, char *); |
25210 |
++ 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); |
25211 |
++ break; |
25212 |
++ case GR_SIG: |
25213 |
++ task = va_arg(ap, struct task_struct *); |
25214 |
++ num1 = va_arg(ap, int); |
25215 |
++ 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); |
25216 |
++ break; |
25217 |
++ case GR_CRASH1: |
25218 |
++ task = va_arg(ap, struct task_struct *); |
25219 |
++ ulong1 = va_arg(ap, unsigned long); |
25220 |
++ 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); |
25221 |
++ break; |
25222 |
++ case GR_CRASH2: |
25223 |
++ task = va_arg(ap, struct task_struct *); |
25224 |
++ ulong1 = va_arg(ap, unsigned long); |
25225 |
++ 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); |
25226 |
++ break; |
25227 |
++ case GR_PSACCT: |
25228 |
++ { |
25229 |
++ unsigned int wday, cday; |
25230 |
++ __u8 whr, chr; |
25231 |
++ __u8 wmin, cmin; |
25232 |
++ __u8 wsec, csec; |
25233 |
++ char cur_tty[64] = { 0 }; |
25234 |
++ char parent_tty[64] = { 0 }; |
25235 |
++ |
25236 |
++ task = va_arg(ap, struct task_struct *); |
25237 |
++ wday = va_arg(ap, unsigned int); |
25238 |
++ cday = va_arg(ap, unsigned int); |
25239 |
++ whr = va_arg(ap, int); |
25240 |
++ chr = va_arg(ap, int); |
25241 |
++ wmin = va_arg(ap, int); |
25242 |
++ cmin = va_arg(ap, int); |
25243 |
++ wsec = va_arg(ap, int); |
25244 |
++ csec = va_arg(ap, int); |
25245 |
++ ulong1 = va_arg(ap, unsigned long); |
25246 |
++ |
25247 |
++ 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); |
25248 |
++ } |
25249 |
++ break; |
25250 |
++ default: |
25251 |
++ gr_log_middle(audit, msg, ap); |
25252 |
++ } |
25253 |
++ va_end(ap); |
25254 |
++ gr_log_end(audit); |
25255 |
++ END_LOCKS(audit); |
25256 |
++} |
25257 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_mem.c linux-2.6.24.4/grsecurity/grsec_mem.c |
25258 |
+--- linux-2.6.24.4/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500 |
25259 |
++++ linux-2.6.24.4/grsecurity/grsec_mem.c 2008-03-26 17:56:56.000000000 -0400 |
25260 |
+@@ -0,0 +1,71 @@ |
25261 |
++#include <linux/kernel.h> |
25262 |
++#include <linux/sched.h> |
25263 |
++#include <linux/mm.h> |
25264 |
++#include <linux/mman.h> |
25265 |
++#include <linux/grinternal.h> |
25266 |
++ |
25267 |
++void |
25268 |
++gr_handle_ioperm(void) |
25269 |
++{ |
25270 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG); |
25271 |
++ return; |
25272 |
++} |
25273 |
++ |
25274 |
++void |
25275 |
++gr_handle_iopl(void) |
25276 |
++{ |
25277 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG); |
25278 |
++ return; |
25279 |
++} |
25280 |
++ |
25281 |
++void |
25282 |
++gr_handle_mem_write(void) |
25283 |
++{ |
25284 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG); |
25285 |
++ return; |
25286 |
++} |
25287 |
++ |
25288 |
++void |
25289 |
++gr_handle_kmem_write(void) |
25290 |
++{ |
25291 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG); |
25292 |
++ return; |
25293 |
++} |
25294 |
++ |
25295 |
++void |
25296 |
++gr_handle_open_port(void) |
25297 |
++{ |
25298 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG); |
25299 |
++ return; |
25300 |
++} |
25301 |
++ |
25302 |
++int |
25303 |
++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma) |
25304 |
++{ |
25305 |
++ unsigned long start, end; |
25306 |
++ |
25307 |
++ start = offset; |
25308 |
++ end = start + vma->vm_end - vma->vm_start; |
25309 |
++ |
25310 |
++ if (start > end) { |
25311 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG); |
25312 |
++ return -EPERM; |
25313 |
++ } |
25314 |
++ |
25315 |
++ /* allowed ranges : ISA I/O BIOS */ |
25316 |
++ if ((start >= __pa(high_memory)) |
25317 |
++#ifdef CONFIG_X86 |
25318 |
++ || (start >= 0x000a0000 && end <= 0x00100000) |
25319 |
++ || (start >= 0x00000000 && end <= 0x00001000) |
25320 |
++#endif |
25321 |
++ ) |
25322 |
++ return 0; |
25323 |
++ |
25324 |
++ if (vma->vm_flags & VM_WRITE) { |
25325 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG); |
25326 |
++ return -EPERM; |
25327 |
++ } else |
25328 |
++ vma->vm_flags &= ~VM_MAYWRITE; |
25329 |
++ |
25330 |
++ return 0; |
25331 |
++} |
25332 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_mount.c linux-2.6.24.4/grsecurity/grsec_mount.c |
25333 |
+--- linux-2.6.24.4/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500 |
25334 |
++++ linux-2.6.24.4/grsecurity/grsec_mount.c 2008-03-26 17:56:56.000000000 -0400 |
25335 |
+@@ -0,0 +1,34 @@ |
25336 |
++#include <linux/kernel.h> |
25337 |
++#include <linux/sched.h> |
25338 |
++#include <linux/grsecurity.h> |
25339 |
++#include <linux/grinternal.h> |
25340 |
++ |
25341 |
++void |
25342 |
++gr_log_remount(const char *devname, const int retval) |
25343 |
++{ |
25344 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT |
25345 |
++ if (grsec_enable_mount && (retval >= 0)) |
25346 |
++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none"); |
25347 |
++#endif |
25348 |
++ return; |
25349 |
++} |
25350 |
++ |
25351 |
++void |
25352 |
++gr_log_unmount(const char *devname, const int retval) |
25353 |
++{ |
25354 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT |
25355 |
++ if (grsec_enable_mount && (retval >= 0)) |
25356 |
++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none"); |
25357 |
++#endif |
25358 |
++ return; |
25359 |
++} |
25360 |
++ |
25361 |
++void |
25362 |
++gr_log_mount(const char *from, const char *to, const int retval) |
25363 |
++{ |
25364 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT |
25365 |
++ if (grsec_enable_mount && (retval >= 0)) |
25366 |
++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to); |
25367 |
++#endif |
25368 |
++ return; |
25369 |
++} |
25370 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_sig.c linux-2.6.24.4/grsecurity/grsec_sig.c |
25371 |
+--- linux-2.6.24.4/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500 |
25372 |
++++ linux-2.6.24.4/grsecurity/grsec_sig.c 2008-03-26 17:56:56.000000000 -0400 |
25373 |
+@@ -0,0 +1,58 @@ |
25374 |
++#include <linux/kernel.h> |
25375 |
++#include <linux/sched.h> |
25376 |
++#include <linux/delay.h> |
25377 |
++#include <linux/grsecurity.h> |
25378 |
++#include <linux/grinternal.h> |
25379 |
++ |
25380 |
++void |
25381 |
++gr_log_signal(const int sig, const struct task_struct *t) |
25382 |
++{ |
25383 |
++#ifdef CONFIG_GRKERNSEC_SIGNAL |
25384 |
++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) || |
25385 |
++ (sig == SIGABRT) || (sig == SIGBUS))) { |
25386 |
++ if (t->pid == current->pid) { |
25387 |
++ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig); |
25388 |
++ } else { |
25389 |
++ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig); |
25390 |
++ } |
25391 |
++ } |
25392 |
++#endif |
25393 |
++ return; |
25394 |
++} |
25395 |
++ |
25396 |
++int |
25397 |
++gr_handle_signal(const struct task_struct *p, const int sig) |
25398 |
++{ |
25399 |
++#ifdef CONFIG_GRKERNSEC |
25400 |
++ if (current->pid > 1 && gr_check_protected_task(p)) { |
25401 |
++ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig); |
25402 |
++ return -EPERM; |
25403 |
++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) { |
25404 |
++ return -EPERM; |
25405 |
++ } |
25406 |
++#endif |
25407 |
++ return 0; |
25408 |
++} |
25409 |
++ |
25410 |
++void gr_handle_brute_attach(struct task_struct *p) |
25411 |
++{ |
25412 |
++#ifdef CONFIG_GRKERNSEC_BRUTE |
25413 |
++ read_lock(&tasklist_lock); |
25414 |
++ read_lock(&grsec_exec_file_lock); |
25415 |
++ if (p->parent && p->parent->exec_file == p->exec_file) |
25416 |
++ p->parent->brute = 1; |
25417 |
++ read_unlock(&grsec_exec_file_lock); |
25418 |
++ read_unlock(&tasklist_lock); |
25419 |
++#endif |
25420 |
++ return; |
25421 |
++} |
25422 |
++ |
25423 |
++void gr_handle_brute_check(void) |
25424 |
++{ |
25425 |
++#ifdef CONFIG_GRKERNSEC_BRUTE |
25426 |
++ if (current->brute) |
25427 |
++ msleep(30 * 1000); |
25428 |
++#endif |
25429 |
++ return; |
25430 |
++} |
25431 |
++ |
25432 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_sock.c linux-2.6.24.4/grsecurity/grsec_sock.c |
25433 |
+--- linux-2.6.24.4/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500 |
25434 |
++++ linux-2.6.24.4/grsecurity/grsec_sock.c 2008-03-26 17:56:56.000000000 -0400 |
25435 |
+@@ -0,0 +1,274 @@ |
25436 |
++#include <linux/kernel.h> |
25437 |
++#include <linux/module.h> |
25438 |
++#include <linux/sched.h> |
25439 |
++#include <linux/file.h> |
25440 |
++#include <linux/net.h> |
25441 |
++#include <linux/in.h> |
25442 |
++#include <linux/ip.h> |
25443 |
++#include <net/sock.h> |
25444 |
++#include <net/inet_sock.h> |
25445 |
++#include <linux/grsecurity.h> |
25446 |
++#include <linux/grinternal.h> |
25447 |
++#include <linux/gracl.h> |
25448 |
++ |
25449 |
++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE) |
25450 |
++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif); |
25451 |
++EXPORT_SYMBOL(udp_v4_lookup); |
25452 |
++#endif |
25453 |
++ |
25454 |
++__u32 gr_cap_rtnetlink(struct sock *sock); |
25455 |
++EXPORT_SYMBOL(gr_cap_rtnetlink); |
25456 |
++ |
25457 |
++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb); |
25458 |
++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr); |
25459 |
++ |
25460 |
++EXPORT_SYMBOL(gr_search_udp_recvmsg); |
25461 |
++EXPORT_SYMBOL(gr_search_udp_sendmsg); |
25462 |
++ |
25463 |
++#ifdef CONFIG_UNIX_MODULE |
25464 |
++EXPORT_SYMBOL(gr_acl_handle_unix); |
25465 |
++EXPORT_SYMBOL(gr_acl_handle_mknod); |
25466 |
++EXPORT_SYMBOL(gr_handle_chroot_unix); |
25467 |
++EXPORT_SYMBOL(gr_handle_create); |
25468 |
++#endif |
25469 |
++ |
25470 |
++#ifdef CONFIG_GRKERNSEC |
25471 |
++#define gr_conn_table_size 32749 |
25472 |
++struct conn_table_entry { |
25473 |
++ struct conn_table_entry *next; |
25474 |
++ struct signal_struct *sig; |
25475 |
++}; |
25476 |
++ |
25477 |
++struct conn_table_entry *gr_conn_table[gr_conn_table_size]; |
25478 |
++spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED; |
25479 |
++ |
25480 |
++extern const char * gr_socktype_to_name(unsigned char type); |
25481 |
++extern const char * gr_proto_to_name(unsigned char proto); |
25482 |
++ |
25483 |
++static __inline__ int |
25484 |
++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size) |
25485 |
++{ |
25486 |
++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size); |
25487 |
++} |
25488 |
++ |
25489 |
++static __inline__ int |
25490 |
++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, |
25491 |
++ __u16 sport, __u16 dport) |
25492 |
++{ |
25493 |
++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr && |
25494 |
++ sig->gr_sport == sport && sig->gr_dport == dport)) |
25495 |
++ return 1; |
25496 |
++ else |
25497 |
++ return 0; |
25498 |
++} |
25499 |
++ |
25500 |
++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent) |
25501 |
++{ |
25502 |
++ struct conn_table_entry **match; |
25503 |
++ unsigned int index; |
25504 |
++ |
25505 |
++ index = conn_hash(sig->gr_saddr, sig->gr_daddr, |
25506 |
++ sig->gr_sport, sig->gr_dport, |
25507 |
++ gr_conn_table_size); |
25508 |
++ |
25509 |
++ newent->sig = sig; |
25510 |
++ |
25511 |
++ match = &gr_conn_table[index]; |
25512 |
++ newent->next = *match; |
25513 |
++ *match = newent; |
25514 |
++ |
25515 |
++ return; |
25516 |
++} |
25517 |
++ |
25518 |
++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig) |
25519 |
++{ |
25520 |
++ struct conn_table_entry *match, *last = NULL; |
25521 |
++ unsigned int index; |
25522 |
++ |
25523 |
++ index = conn_hash(sig->gr_saddr, sig->gr_daddr, |
25524 |
++ sig->gr_sport, sig->gr_dport, |
25525 |
++ gr_conn_table_size); |
25526 |
++ |
25527 |
++ match = gr_conn_table[index]; |
25528 |
++ while (match && !conn_match(match->sig, |
25529 |
++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport, |
25530 |
++ sig->gr_dport)) { |
25531 |
++ last = match; |
25532 |
++ match = match->next; |
25533 |
++ } |
25534 |
++ |
25535 |
++ if (match) { |
25536 |
++ if (last) |
25537 |
++ last->next = match->next; |
25538 |
++ else |
25539 |
++ gr_conn_table[index] = NULL; |
25540 |
++ kfree(match); |
25541 |
++ } |
25542 |
++ |
25543 |
++ return; |
25544 |
++} |
25545 |
++ |
25546 |
++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr, |
25547 |
++ __u16 sport, __u16 dport) |
25548 |
++{ |
25549 |
++ struct conn_table_entry *match; |
25550 |
++ unsigned int index; |
25551 |
++ |
25552 |
++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size); |
25553 |
++ |
25554 |
++ match = gr_conn_table[index]; |
25555 |
++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport)) |
25556 |
++ match = match->next; |
25557 |
++ |
25558 |
++ if (match) |
25559 |
++ return match->sig; |
25560 |
++ else |
25561 |
++ return NULL; |
25562 |
++} |
25563 |
++ |
25564 |
++#endif |
25565 |
++ |
25566 |
++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet) |
25567 |
++{ |
25568 |
++#ifdef CONFIG_GRKERNSEC |
25569 |
++ struct signal_struct *sig = task->signal; |
25570 |
++ struct conn_table_entry *newent; |
25571 |
++ |
25572 |
++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC); |
25573 |
++ if (newent == NULL) |
25574 |
++ return; |
25575 |
++ /* no bh lock needed since we are called with bh disabled */ |
25576 |
++ spin_lock(&gr_conn_table_lock); |
25577 |
++ gr_del_task_from_ip_table_nolock(sig); |
25578 |
++ sig->gr_saddr = inet->rcv_saddr; |
25579 |
++ sig->gr_daddr = inet->daddr; |
25580 |
++ sig->gr_sport = inet->sport; |
25581 |
++ sig->gr_dport = inet->dport; |
25582 |
++ gr_add_to_task_ip_table_nolock(sig, newent); |
25583 |
++ spin_unlock(&gr_conn_table_lock); |
25584 |
++#endif |
25585 |
++ return; |
25586 |
++} |
25587 |
++ |
25588 |
++void gr_del_task_from_ip_table(struct task_struct *task) |
25589 |
++{ |
25590 |
++#ifdef CONFIG_GRKERNSEC |
25591 |
++ spin_lock(&gr_conn_table_lock); |
25592 |
++ gr_del_task_from_ip_table_nolock(task->signal); |
25593 |
++ spin_unlock(&gr_conn_table_lock); |
25594 |
++#endif |
25595 |
++ return; |
25596 |
++} |
25597 |
++ |
25598 |
++void |
25599 |
++gr_attach_curr_ip(const struct sock *sk) |
25600 |
++{ |
25601 |
++#ifdef CONFIG_GRKERNSEC |
25602 |
++ struct signal_struct *p, *set; |
25603 |
++ const struct inet_sock *inet = inet_sk(sk); |
25604 |
++ |
25605 |
++ if (unlikely(sk->sk_protocol != IPPROTO_TCP)) |
25606 |
++ return; |
25607 |
++ |
25608 |
++ set = current->signal; |
25609 |
++ |
25610 |
++ spin_lock_bh(&gr_conn_table_lock); |
25611 |
++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr, |
25612 |
++ inet->dport, inet->sport); |
25613 |
++ if (unlikely(p != NULL)) { |
25614 |
++ set->curr_ip = p->curr_ip; |
25615 |
++ set->used_accept = 1; |
25616 |
++ gr_del_task_from_ip_table_nolock(p); |
25617 |
++ spin_unlock_bh(&gr_conn_table_lock); |
25618 |
++ return; |
25619 |
++ } |
25620 |
++ spin_unlock_bh(&gr_conn_table_lock); |
25621 |
++ |
25622 |
++ set->curr_ip = inet->daddr; |
25623 |
++ set->used_accept = 1; |
25624 |
++#endif |
25625 |
++ return; |
25626 |
++} |
25627 |
++ |
25628 |
++int |
25629 |
++gr_handle_sock_all(const int family, const int type, const int protocol) |
25630 |
++{ |
25631 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL |
25632 |
++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) && |
25633 |
++ (family != AF_UNIX) && (family != AF_LOCAL)) { |
25634 |
++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol)); |
25635 |
++ return -EACCES; |
25636 |
++ } |
25637 |
++#endif |
25638 |
++ return 0; |
25639 |
++} |
25640 |
++ |
25641 |
++int |
25642 |
++gr_handle_sock_server(const struct sockaddr *sck) |
25643 |
++{ |
25644 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER |
25645 |
++ if (grsec_enable_socket_server && |
25646 |
++ in_group_p(grsec_socket_server_gid) && |
25647 |
++ sck && (sck->sa_family != AF_UNIX) && |
25648 |
++ (sck->sa_family != AF_LOCAL)) { |
25649 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG); |
25650 |
++ return -EACCES; |
25651 |
++ } |
25652 |
++#endif |
25653 |
++ return 0; |
25654 |
++} |
25655 |
++ |
25656 |
++int |
25657 |
++gr_handle_sock_server_other(const struct sock *sck) |
25658 |
++{ |
25659 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER |
25660 |
++ if (grsec_enable_socket_server && |
25661 |
++ in_group_p(grsec_socket_server_gid) && |
25662 |
++ sck && (sck->sk_family != AF_UNIX) && |
25663 |
++ (sck->sk_family != AF_LOCAL)) { |
25664 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG); |
25665 |
++ return -EACCES; |
25666 |
++ } |
25667 |
++#endif |
25668 |
++ return 0; |
25669 |
++} |
25670 |
++ |
25671 |
++int |
25672 |
++gr_handle_sock_client(const struct sockaddr *sck) |
25673 |
++{ |
25674 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT |
25675 |
++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) && |
25676 |
++ sck && (sck->sa_family != AF_UNIX) && |
25677 |
++ (sck->sa_family != AF_LOCAL)) { |
25678 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG); |
25679 |
++ return -EACCES; |
25680 |
++ } |
25681 |
++#endif |
25682 |
++ return 0; |
25683 |
++} |
25684 |
++ |
25685 |
++__u32 |
25686 |
++gr_cap_rtnetlink(struct sock *sock) |
25687 |
++{ |
25688 |
++#ifdef CONFIG_GRKERNSEC |
25689 |
++ if (!gr_acl_is_enabled()) |
25690 |
++ return current->cap_effective; |
25691 |
++ else if (sock->sk_protocol == NETLINK_ISCSI && |
25692 |
++ cap_raised(current->cap_effective, CAP_SYS_ADMIN) && |
25693 |
++ gr_task_is_capable(current, CAP_SYS_ADMIN)) |
25694 |
++ return current->cap_effective; |
25695 |
++ else if (sock->sk_protocol == NETLINK_AUDIT && |
25696 |
++ cap_raised(current->cap_effective, CAP_AUDIT_WRITE) && |
25697 |
++ gr_task_is_capable(current, CAP_AUDIT_WRITE) && |
25698 |
++ cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) && |
25699 |
++ gr_task_is_capable(current, CAP_AUDIT_CONTROL)) |
25700 |
++ return current->cap_effective; |
25701 |
++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) && |
25702 |
++ gr_task_is_capable(current, CAP_NET_ADMIN)) |
25703 |
++ return current->cap_effective; |
25704 |
++ else |
25705 |
++ return 0; |
25706 |
++#else |
25707 |
++ return current->cap_effective; |
25708 |
++#endif |
25709 |
++} |
25710 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_sysctl.c linux-2.6.24.4/grsecurity/grsec_sysctl.c |
25711 |
+--- linux-2.6.24.4/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500 |
25712 |
++++ linux-2.6.24.4/grsecurity/grsec_sysctl.c 2008-03-26 17:56:56.000000000 -0400 |
25713 |
+@@ -0,0 +1,435 @@ |
25714 |
++#include <linux/kernel.h> |
25715 |
++#include <linux/sched.h> |
25716 |
++#include <linux/sysctl.h> |
25717 |
++#include <linux/grsecurity.h> |
25718 |
++#include <linux/grinternal.h> |
25719 |
++ |
25720 |
++#ifdef CONFIG_GRKERNSEC_MODSTOP |
25721 |
++int grsec_modstop; |
25722 |
++#endif |
25723 |
++ |
25724 |
++int |
25725 |
++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op) |
25726 |
++{ |
25727 |
++#ifdef CONFIG_GRKERNSEC_SYSCTL |
25728 |
++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) { |
25729 |
++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name); |
25730 |
++ return -EACCES; |
25731 |
++ } |
25732 |
++#endif |
25733 |
++#ifdef CONFIG_GRKERNSEC_MODSTOP |
25734 |
++ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") && |
25735 |
++ grsec_modstop && (op & 002)) { |
25736 |
++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name); |
25737 |
++ return -EACCES; |
25738 |
++ } |
25739 |
++#endif |
25740 |
++ return 0; |
25741 |
++} |
25742 |
++ |
25743 |
++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP) |
25744 |
++ctl_table grsecurity_table[] = { |
25745 |
++#ifdef CONFIG_GRKERNSEC_SYSCTL |
25746 |
++#ifdef CONFIG_GRKERNSEC_LINK |
25747 |
++ { |
25748 |
++ .ctl_name = CTL_UNNUMBERED, |
25749 |
++ .procname = "linking_restrictions", |
25750 |
++ .data = &grsec_enable_link, |
25751 |
++ .maxlen = sizeof(int), |
25752 |
++ .mode = 0600, |
25753 |
++ .proc_handler = &proc_dointvec, |
25754 |
++ }, |
25755 |
++#endif |
25756 |
++#ifdef CONFIG_GRKERNSEC_FIFO |
25757 |
++ { |
25758 |
++ .ctl_name = CTL_UNNUMBERED, |
25759 |
++ .procname = "fifo_restrictions", |
25760 |
++ .data = &grsec_enable_fifo, |
25761 |
++ .maxlen = sizeof(int), |
25762 |
++ .mode = 0600, |
25763 |
++ .proc_handler = &proc_dointvec, |
25764 |
++ }, |
25765 |
++#endif |
25766 |
++#ifdef CONFIG_GRKERNSEC_EXECVE |
25767 |
++ { |
25768 |
++ .ctl_name = CTL_UNNUMBERED, |
25769 |
++ .procname = "execve_limiting", |
25770 |
++ .data = &grsec_enable_execve, |
25771 |
++ .maxlen = sizeof(int), |
25772 |
++ .mode = 0600, |
25773 |
++ .proc_handler = &proc_dointvec, |
25774 |
++ }, |
25775 |
++#endif |
25776 |
++#ifdef CONFIG_GRKERNSEC_EXECLOG |
25777 |
++ { |
25778 |
++ .ctl_name = CTL_UNNUMBERED, |
25779 |
++ .procname = "exec_logging", |
25780 |
++ .data = &grsec_enable_execlog, |
25781 |
++ .maxlen = sizeof(int), |
25782 |
++ .mode = 0600, |
25783 |
++ .proc_handler = &proc_dointvec, |
25784 |
++ }, |
25785 |
++#endif |
25786 |
++#ifdef CONFIG_GRKERNSEC_SIGNAL |
25787 |
++ { |
25788 |
++ .ctl_name = CTL_UNNUMBERED, |
25789 |
++ .procname = "signal_logging", |
25790 |
++ .data = &grsec_enable_signal, |
25791 |
++ .maxlen = sizeof(int), |
25792 |
++ .mode = 0600, |
25793 |
++ .proc_handler = &proc_dointvec, |
25794 |
++ }, |
25795 |
++#endif |
25796 |
++#ifdef CONFIG_GRKERNSEC_FORKFAIL |
25797 |
++ { |
25798 |
++ .ctl_name = CTL_UNNUMBERED, |
25799 |
++ .procname = "forkfail_logging", |
25800 |
++ .data = &grsec_enable_forkfail, |
25801 |
++ .maxlen = sizeof(int), |
25802 |
++ .mode = 0600, |
25803 |
++ .proc_handler = &proc_dointvec, |
25804 |
++ }, |
25805 |
++#endif |
25806 |
++#ifdef CONFIG_GRKERNSEC_TIME |
25807 |
++ { |
25808 |
++ .ctl_name = CTL_UNNUMBERED, |
25809 |
++ .procname = "timechange_logging", |
25810 |
++ .data = &grsec_enable_time, |
25811 |
++ .maxlen = sizeof(int), |
25812 |
++ .mode = 0600, |
25813 |
++ .proc_handler = &proc_dointvec, |
25814 |
++ }, |
25815 |
++#endif |
25816 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT |
25817 |
++ { |
25818 |
++ .ctl_name = CTL_UNNUMBERED, |
25819 |
++ .procname = "chroot_deny_shmat", |
25820 |
++ .data = &grsec_enable_chroot_shmat, |
25821 |
++ .maxlen = sizeof(int), |
25822 |
++ .mode = 0600, |
25823 |
++ .proc_handler = &proc_dointvec, |
25824 |
++ }, |
25825 |
++#endif |
25826 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX |
25827 |
++ { |
25828 |
++ .ctl_name = CTL_UNNUMBERED, |
25829 |
++ .procname = "chroot_deny_unix", |
25830 |
++ .data = &grsec_enable_chroot_unix, |
25831 |
++ .maxlen = sizeof(int), |
25832 |
++ .mode = 0600, |
25833 |
++ .proc_handler = &proc_dointvec, |
25834 |
++ }, |
25835 |
++#endif |
25836 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT |
25837 |
++ { |
25838 |
++ .ctl_name = CTL_UNNUMBERED, |
25839 |
++ .procname = "chroot_deny_mount", |
25840 |
++ .data = &grsec_enable_chroot_mount, |
25841 |
++ .maxlen = sizeof(int), |
25842 |
++ .mode = 0600, |
25843 |
++ .proc_handler = &proc_dointvec, |
25844 |
++ }, |
25845 |
++#endif |
25846 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR |
25847 |
++ { |
25848 |
++ .ctl_name = CTL_UNNUMBERED, |
25849 |
++ .procname = "chroot_deny_fchdir", |
25850 |
++ .data = &grsec_enable_chroot_fchdir, |
25851 |
++ .maxlen = sizeof(int), |
25852 |
++ .mode = 0600, |
25853 |
++ .proc_handler = &proc_dointvec, |
25854 |
++ }, |
25855 |
++#endif |
25856 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE |
25857 |
++ { |
25858 |
++ .ctl_name = CTL_UNNUMBERED, |
25859 |
++ .procname = "chroot_deny_chroot", |
25860 |
++ .data = &grsec_enable_chroot_double, |
25861 |
++ .maxlen = sizeof(int), |
25862 |
++ .mode = 0600, |
25863 |
++ .proc_handler = &proc_dointvec, |
25864 |
++ }, |
25865 |
++#endif |
25866 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT |
25867 |
++ { |
25868 |
++ .ctl_name = CTL_UNNUMBERED, |
25869 |
++ .procname = "chroot_deny_pivot", |
25870 |
++ .data = &grsec_enable_chroot_pivot, |
25871 |
++ .maxlen = sizeof(int), |
25872 |
++ .mode = 0600, |
25873 |
++ .proc_handler = &proc_dointvec, |
25874 |
++ }, |
25875 |
++#endif |
25876 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR |
25877 |
++ { |
25878 |
++ .ctl_name = CTL_UNNUMBERED, |
25879 |
++ .procname = "chroot_enforce_chdir", |
25880 |
++ .data = &grsec_enable_chroot_chdir, |
25881 |
++ .maxlen = sizeof(int), |
25882 |
++ .mode = 0600, |
25883 |
++ .proc_handler = &proc_dointvec, |
25884 |
++ }, |
25885 |
++#endif |
25886 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD |
25887 |
++ { |
25888 |
++ .ctl_name = CTL_UNNUMBERED, |
25889 |
++ .procname = "chroot_deny_chmod", |
25890 |
++ .data = &grsec_enable_chroot_chmod, |
25891 |
++ .maxlen = sizeof(int), |
25892 |
++ .mode = 0600, |
25893 |
++ .proc_handler = &proc_dointvec, |
25894 |
++ }, |
25895 |
++#endif |
25896 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD |
25897 |
++ { |
25898 |
++ .ctl_name = CTL_UNNUMBERED, |
25899 |
++ .procname = "chroot_deny_mknod", |
25900 |
++ .data = &grsec_enable_chroot_mknod, |
25901 |
++ .maxlen = sizeof(int), |
25902 |
++ .mode = 0600, |
25903 |
++ .proc_handler = &proc_dointvec, |
25904 |
++ }, |
25905 |
++#endif |
25906 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE |
25907 |
++ { |
25908 |
++ .ctl_name = CTL_UNNUMBERED, |
25909 |
++ .procname = "chroot_restrict_nice", |
25910 |
++ .data = &grsec_enable_chroot_nice, |
25911 |
++ .maxlen = sizeof(int), |
25912 |
++ .mode = 0600, |
25913 |
++ .proc_handler = &proc_dointvec, |
25914 |
++ }, |
25915 |
++#endif |
25916 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG |
25917 |
++ { |
25918 |
++ .ctl_name = CTL_UNNUMBERED, |
25919 |
++ .procname = "chroot_execlog", |
25920 |
++ .data = &grsec_enable_chroot_execlog, |
25921 |
++ .maxlen = sizeof(int), |
25922 |
++ .mode = 0600, |
25923 |
++ .proc_handler = &proc_dointvec, |
25924 |
++ }, |
25925 |
++#endif |
25926 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS |
25927 |
++ { |
25928 |
++ .ctl_name = CTL_UNNUMBERED, |
25929 |
++ .procname = "chroot_caps", |
25930 |
++ .data = &grsec_enable_chroot_caps, |
25931 |
++ .maxlen = sizeof(int), |
25932 |
++ .mode = 0600, |
25933 |
++ .proc_handler = &proc_dointvec, |
25934 |
++ }, |
25935 |
++#endif |
25936 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL |
25937 |
++ { |
25938 |
++ .ctl_name = CTL_UNNUMBERED, |
25939 |
++ .procname = "chroot_deny_sysctl", |
25940 |
++ .data = &grsec_enable_chroot_sysctl, |
25941 |
++ .maxlen = sizeof(int), |
25942 |
++ .mode = 0600, |
25943 |
++ .proc_handler = &proc_dointvec, |
25944 |
++ }, |
25945 |
++#endif |
25946 |
++#ifdef CONFIG_GRKERNSEC_TPE |
25947 |
++ { |
25948 |
++ .ctl_name = CTL_UNNUMBERED, |
25949 |
++ .procname = "tpe", |
25950 |
++ .data = &grsec_enable_tpe, |
25951 |
++ .maxlen = sizeof(int), |
25952 |
++ .mode = 0600, |
25953 |
++ .proc_handler = &proc_dointvec, |
25954 |
++ }, |
25955 |
++ { |
25956 |
++ .ctl_name = CTL_UNNUMBERED, |
25957 |
++ .procname = "tpe_gid", |
25958 |
++ .data = &grsec_tpe_gid, |
25959 |
++ .maxlen = sizeof(int), |
25960 |
++ .mode = 0600, |
25961 |
++ .proc_handler = &proc_dointvec, |
25962 |
++ }, |
25963 |
++#endif |
25964 |
++#ifdef CONFIG_GRKERNSEC_TPE_ALL |
25965 |
++ { |
25966 |
++ .ctl_name = CTL_UNNUMBERED, |
25967 |
++ .procname = "tpe_restrict_all", |
25968 |
++ .data = &grsec_enable_tpe_all, |
25969 |
++ .maxlen = sizeof(int), |
25970 |
++ .mode = 0600, |
25971 |
++ .proc_handler = &proc_dointvec, |
25972 |
++ }, |
25973 |
++#endif |
25974 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL |
25975 |
++ { |
25976 |
++ .ctl_name = CTL_UNNUMBERED, |
25977 |
++ .procname = "socket_all", |
25978 |
++ .data = &grsec_enable_socket_all, |
25979 |
++ .maxlen = sizeof(int), |
25980 |
++ .mode = 0600, |
25981 |
++ .proc_handler = &proc_dointvec, |
25982 |
++ }, |
25983 |
++ { |
25984 |
++ .ctl_name = CTL_UNNUMBERED, |
25985 |
++ .procname = "socket_all_gid", |
25986 |
++ .data = &grsec_socket_all_gid, |
25987 |
++ .maxlen = sizeof(int), |
25988 |
++ .mode = 0600, |
25989 |
++ .proc_handler = &proc_dointvec, |
25990 |
++ }, |
25991 |
++#endif |
25992 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT |
25993 |
++ { |
25994 |
++ .ctl_name = CTL_UNNUMBERED, |
25995 |
++ .procname = "socket_client", |
25996 |
++ .data = &grsec_enable_socket_client, |
25997 |
++ .maxlen = sizeof(int), |
25998 |
++ .mode = 0600, |
25999 |
++ .proc_handler = &proc_dointvec, |
26000 |
++ }, |
26001 |
++ { |
26002 |
++ .ctl_name = CTL_UNNUMBERED, |
26003 |
++ .procname = "socket_client_gid", |
26004 |
++ .data = &grsec_socket_client_gid, |
26005 |
++ .maxlen = sizeof(int), |
26006 |
++ .mode = 0600, |
26007 |
++ .proc_handler = &proc_dointvec, |
26008 |
++ }, |
26009 |
++#endif |
26010 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER |
26011 |
++ { |
26012 |
++ .ctl_name = CTL_UNNUMBERED, |
26013 |
++ .procname = "socket_server", |
26014 |
++ .data = &grsec_enable_socket_server, |
26015 |
++ .maxlen = sizeof(int), |
26016 |
++ .mode = 0600, |
26017 |
++ .proc_handler = &proc_dointvec, |
26018 |
++ }, |
26019 |
++ { |
26020 |
++ .ctl_name = CTL_UNNUMBERED, |
26021 |
++ .procname = "socket_server_gid", |
26022 |
++ .data = &grsec_socket_server_gid, |
26023 |
++ .maxlen = sizeof(int), |
26024 |
++ .mode = 0600, |
26025 |
++ .proc_handler = &proc_dointvec, |
26026 |
++ }, |
26027 |
++#endif |
26028 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP |
26029 |
++ { |
26030 |
++ .ctl_name = CTL_UNNUMBERED, |
26031 |
++ .procname = "audit_group", |
26032 |
++ .data = &grsec_enable_group, |
26033 |
++ .maxlen = sizeof(int), |
26034 |
++ .mode = 0600, |
26035 |
++ .proc_handler = &proc_dointvec, |
26036 |
++ }, |
26037 |
++ { |
26038 |
++ .ctl_name = CTL_UNNUMBERED, |
26039 |
++ .procname = "audit_gid", |
26040 |
++ .data = &grsec_audit_gid, |
26041 |
++ .maxlen = sizeof(int), |
26042 |
++ .mode = 0600, |
26043 |
++ .proc_handler = &proc_dointvec, |
26044 |
++ }, |
26045 |
++#endif |
26046 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR |
26047 |
++ { |
26048 |
++ .ctl_name = CTL_UNNUMBERED, |
26049 |
++ .procname = "audit_chdir", |
26050 |
++ .data = &grsec_enable_chdir, |
26051 |
++ .maxlen = sizeof(int), |
26052 |
++ .mode = 0600, |
26053 |
++ .proc_handler = &proc_dointvec, |
26054 |
++ }, |
26055 |
++#endif |
26056 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT |
26057 |
++ { |
26058 |
++ .ctl_name = CTL_UNNUMBERED, |
26059 |
++ .procname = "audit_mount", |
26060 |
++ .data = &grsec_enable_mount, |
26061 |
++ .maxlen = sizeof(int), |
26062 |
++ .mode = 0600, |
26063 |
++ .proc_handler = &proc_dointvec, |
26064 |
++ }, |
26065 |
++#endif |
26066 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
26067 |
++ { |
26068 |
++ .ctl_name = CTL_UNNUMBERED, |
26069 |
++ .procname = "audit_ipc", |
26070 |
++ .data = &grsec_enable_audit_ipc, |
26071 |
++ .maxlen = sizeof(int), |
26072 |
++ .mode = 0600, |
26073 |
++ .proc_handler = &proc_dointvec, |
26074 |
++ }, |
26075 |
++#endif |
26076 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL |
26077 |
++ { |
26078 |
++ .ctl_name = CTL_UNNUMBERED, |
26079 |
++ .procname = "audit_textrel", |
26080 |
++ .data = &grsec_enable_audit_textrel, |
26081 |
++ .maxlen = sizeof(int), |
26082 |
++ .mode = 0600, |
26083 |
++ .proc_handler = &proc_dointvec, |
26084 |
++ }, |
26085 |
++#endif |
26086 |
++#ifdef CONFIG_GRKERNSEC_DMESG |
26087 |
++ { |
26088 |
++ .ctl_name = CTL_UNNUMBERED, |
26089 |
++ .procname = "dmesg", |
26090 |
++ .data = &grsec_enable_dmesg, |
26091 |
++ .maxlen = sizeof(int), |
26092 |
++ .mode = 0600, |
26093 |
++ .proc_handler = &proc_dointvec, |
26094 |
++ }, |
26095 |
++#endif |
26096 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK |
26097 |
++ { |
26098 |
++ .ctl_name = CTL_UNNUMBERED, |
26099 |
++ .procname = "chroot_findtask", |
26100 |
++ .data = &grsec_enable_chroot_findtask, |
26101 |
++ .maxlen = sizeof(int), |
26102 |
++ .mode = 0600, |
26103 |
++ .proc_handler = &proc_dointvec, |
26104 |
++ }, |
26105 |
++#endif |
26106 |
++#ifdef CONFIG_GRKERNSEC_RESLOG |
26107 |
++ { |
26108 |
++ .ctl_name = CTL_UNNUMBERED, |
26109 |
++ .procname = "resource_logging", |
26110 |
++ .data = &grsec_resource_logging, |
26111 |
++ .maxlen = sizeof(int), |
26112 |
++ .mode = 0600, |
26113 |
++ .proc_handler = &proc_dointvec, |
26114 |
++ }, |
26115 |
++#endif |
26116 |
++ { |
26117 |
++ .ctl_name = CTL_UNNUMBERED, |
26118 |
++ .procname = "grsec_lock", |
26119 |
++ .data = &grsec_lock, |
26120 |
++ .maxlen = sizeof(int), |
26121 |
++ .mode = 0600, |
26122 |
++ .proc_handler = &proc_dointvec, |
26123 |
++ }, |
26124 |
++#endif |
26125 |
++#ifdef CONFIG_GRKERNSEC_MODSTOP |
26126 |
++ { |
26127 |
++ .ctl_name = CTL_UNNUMBERED, |
26128 |
++ .procname = "disable_modules", |
26129 |
++ .data = &grsec_modstop, |
26130 |
++ .maxlen = sizeof(int), |
26131 |
++ .mode = 0600, |
26132 |
++ .proc_handler = &proc_dointvec, |
26133 |
++ }, |
26134 |
++#endif |
26135 |
++ { .ctl_name = 0 } |
26136 |
++}; |
26137 |
++#endif |
26138 |
++ |
26139 |
++int gr_check_modstop(void) |
26140 |
++{ |
26141 |
++#ifdef CONFIG_GRKERNSEC_MODSTOP |
26142 |
++ if (grsec_modstop == 1) { |
26143 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG); |
26144 |
++ return 1; |
26145 |
++ } |
26146 |
++#endif |
26147 |
++ return 0; |
26148 |
++} |
26149 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_textrel.c linux-2.6.24.4/grsecurity/grsec_textrel.c |
26150 |
+--- linux-2.6.24.4/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500 |
26151 |
++++ linux-2.6.24.4/grsecurity/grsec_textrel.c 2008-03-26 17:56:56.000000000 -0400 |
26152 |
+@@ -0,0 +1,16 @@ |
26153 |
++#include <linux/kernel.h> |
26154 |
++#include <linux/sched.h> |
26155 |
++#include <linux/mm.h> |
26156 |
++#include <linux/file.h> |
26157 |
++#include <linux/grinternal.h> |
26158 |
++#include <linux/grsecurity.h> |
26159 |
++ |
26160 |
++void |
26161 |
++gr_log_textrel(struct vm_area_struct * vma) |
26162 |
++{ |
26163 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL |
26164 |
++ if (grsec_enable_audit_textrel) |
26165 |
++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff); |
26166 |
++#endif |
26167 |
++ return; |
26168 |
++} |
26169 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_time.c linux-2.6.24.4/grsecurity/grsec_time.c |
26170 |
+--- linux-2.6.24.4/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500 |
26171 |
++++ linux-2.6.24.4/grsecurity/grsec_time.c 2008-03-26 17:56:56.000000000 -0400 |
26172 |
+@@ -0,0 +1,13 @@ |
26173 |
++#include <linux/kernel.h> |
26174 |
++#include <linux/sched.h> |
26175 |
++#include <linux/grinternal.h> |
26176 |
++ |
26177 |
++void |
26178 |
++gr_log_timechange(void) |
26179 |
++{ |
26180 |
++#ifdef CONFIG_GRKERNSEC_TIME |
26181 |
++ if (grsec_enable_time) |
26182 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG); |
26183 |
++#endif |
26184 |
++ return; |
26185 |
++} |
26186 |
+diff -urNp linux-2.6.24.4/grsecurity/grsec_tpe.c linux-2.6.24.4/grsecurity/grsec_tpe.c |
26187 |
+--- linux-2.6.24.4/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500 |
26188 |
++++ linux-2.6.24.4/grsecurity/grsec_tpe.c 2008-03-26 17:56:56.000000000 -0400 |
26189 |
+@@ -0,0 +1,37 @@ |
26190 |
++#include <linux/kernel.h> |
26191 |
++#include <linux/sched.h> |
26192 |
++#include <linux/file.h> |
26193 |
++#include <linux/fs.h> |
26194 |
++#include <linux/grinternal.h> |
26195 |
++ |
26196 |
++extern int gr_acl_tpe_check(void); |
26197 |
++ |
26198 |
++int |
26199 |
++gr_tpe_allow(const struct file *file) |
26200 |
++{ |
26201 |
++#ifdef CONFIG_GRKERNSEC |
26202 |
++ struct inode *inode = file->f_dentry->d_parent->d_inode; |
26203 |
++ |
26204 |
++ if (current->uid && ((grsec_enable_tpe && |
26205 |
++#ifdef CONFIG_GRKERNSEC_TPE_INVERT |
26206 |
++ !in_group_p(grsec_tpe_gid) |
26207 |
++#else |
26208 |
++ in_group_p(grsec_tpe_gid) |
26209 |
++#endif |
26210 |
++ ) || gr_acl_tpe_check()) && |
26211 |
++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) || |
26212 |
++ (inode->i_mode & S_IWOTH))))) { |
26213 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt); |
26214 |
++ return 0; |
26215 |
++ } |
26216 |
++#ifdef CONFIG_GRKERNSEC_TPE_ALL |
26217 |
++ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all && |
26218 |
++ ((inode->i_uid && (inode->i_uid != current->uid)) || |
26219 |
++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) { |
26220 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt); |
26221 |
++ return 0; |
26222 |
++ } |
26223 |
++#endif |
26224 |
++#endif |
26225 |
++ return 1; |
26226 |
++} |
26227 |
+diff -urNp linux-2.6.24.4/grsecurity/grsum.c linux-2.6.24.4/grsecurity/grsum.c |
26228 |
+--- linux-2.6.24.4/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500 |
26229 |
++++ linux-2.6.24.4/grsecurity/grsum.c 2008-03-26 17:56:56.000000000 -0400 |
26230 |
+@@ -0,0 +1,59 @@ |
26231 |
++#include <linux/err.h> |
26232 |
++#include <linux/kernel.h> |
26233 |
++#include <linux/sched.h> |
26234 |
++#include <linux/mm.h> |
26235 |
++#include <linux/scatterlist.h> |
26236 |
++#include <linux/crypto.h> |
26237 |
++#include <linux/gracl.h> |
26238 |
++ |
26239 |
++ |
26240 |
++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE) |
26241 |
++#error "crypto and sha256 must be built into the kernel" |
26242 |
++#endif |
26243 |
++ |
26244 |
++int |
26245 |
++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum) |
26246 |
++{ |
26247 |
++ char *p; |
26248 |
++ struct crypto_hash *tfm; |
26249 |
++ struct hash_desc desc; |
26250 |
++ struct scatterlist sg; |
26251 |
++ unsigned char temp_sum[GR_SHA_LEN]; |
26252 |
++ volatile int retval = 0; |
26253 |
++ volatile int dummy = 0; |
26254 |
++ unsigned int i; |
26255 |
++ |
26256 |
++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC); |
26257 |
++ if (IS_ERR(tfm)) { |
26258 |
++ /* should never happen, since sha256 should be built in */ |
26259 |
++ return 1; |
26260 |
++ } |
26261 |
++ |
26262 |
++ desc.tfm = tfm; |
26263 |
++ desc.flags = 0; |
26264 |
++ |
26265 |
++ crypto_hash_init(&desc); |
26266 |
++ |
26267 |
++ p = salt; |
26268 |
++ sg_set_buf(&sg, p, GR_SALT_LEN); |
26269 |
++ crypto_hash_update(&desc, &sg, sg.length); |
26270 |
++ |
26271 |
++ p = entry->pw; |
26272 |
++ sg_set_buf(&sg, p, strlen(p)); |
26273 |
++ |
26274 |
++ crypto_hash_update(&desc, &sg, sg.length); |
26275 |
++ |
26276 |
++ crypto_hash_final(&desc, temp_sum); |
26277 |
++ |
26278 |
++ memset(entry->pw, 0, GR_PW_LEN); |
26279 |
++ |
26280 |
++ for (i = 0; i < GR_SHA_LEN; i++) |
26281 |
++ if (sum[i] != temp_sum[i]) |
26282 |
++ retval = 1; |
26283 |
++ else |
26284 |
++ dummy = 1; // waste a cycle |
26285 |
++ |
26286 |
++ crypto_free_hash(tfm); |
26287 |
++ |
26288 |
++ return retval; |
26289 |
++} |
26290 |
+diff -urNp linux-2.6.24.4/grsecurity/Kconfig linux-2.6.24.4/grsecurity/Kconfig |
26291 |
+--- linux-2.6.24.4/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500 |
26292 |
++++ linux-2.6.24.4/grsecurity/Kconfig 2008-03-26 17:56:56.000000000 -0400 |
26293 |
+@@ -0,0 +1,861 @@ |
26294 |
++# |
26295 |
++# grecurity configuration |
26296 |
++# |
26297 |
++ |
26298 |
++menu "Grsecurity" |
26299 |
++ |
26300 |
++config GRKERNSEC |
26301 |
++ bool "Grsecurity" |
26302 |
++ select CRYPTO |
26303 |
++ select CRYPTO_SHA256 |
26304 |
++ select SECURITY |
26305 |
++ select SECURITY_CAPABILITIES |
26306 |
++ help |
26307 |
++ If you say Y here, you will be able to configure many features |
26308 |
++ that will enhance the security of your system. It is highly |
26309 |
++ recommended that you say Y here and read through the help |
26310 |
++ for each option so that you fully understand the features and |
26311 |
++ can evaluate their usefulness for your machine. |
26312 |
++ |
26313 |
++choice |
26314 |
++ prompt "Security Level" |
26315 |
++ depends on GRKERNSEC |
26316 |
++ default GRKERNSEC_CUSTOM |
26317 |
++ |
26318 |
++config GRKERNSEC_LOW |
26319 |
++ bool "Low" |
26320 |
++ select GRKERNSEC_LINK |
26321 |
++ select GRKERNSEC_FIFO |
26322 |
++ select GRKERNSEC_EXECVE |
26323 |
++ select GRKERNSEC_RANDNET |
26324 |
++ select GRKERNSEC_DMESG |
26325 |
++ select GRKERNSEC_CHROOT_CHDIR |
26326 |
++ select GRKERNSEC_MODSTOP if (MODULES) |
26327 |
++ |
26328 |
++ help |
26329 |
++ If you choose this option, several of the grsecurity options will |
26330 |
++ be enabled that will give you greater protection against a number |
26331 |
++ of attacks, while assuring that none of your software will have any |
26332 |
++ conflicts with the additional security measures. If you run a lot |
26333 |
++ of unusual software, or you are having problems with the higher |
26334 |
++ security levels, you should say Y here. With this option, the |
26335 |
++ following features are enabled: |
26336 |
++ |
26337 |
++ - Linking restrictions |
26338 |
++ - FIFO restrictions |
26339 |
++ - Enforcing RLIMIT_NPROC on execve |
26340 |
++ - Restricted dmesg |
26341 |
++ - Enforced chdir("/") on chroot |
26342 |
++ - Runtime module disabling |
26343 |
++ |
26344 |
++config GRKERNSEC_MEDIUM |
26345 |
++ bool "Medium" |
26346 |
++ select PAX |
26347 |
++ select PAX_EI_PAX |
26348 |
++ select PAX_PT_PAX_FLAGS |
26349 |
++ select PAX_HAVE_ACL_FLAGS |
26350 |
++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR) |
26351 |
++ select GRKERNSEC_CHROOT_SYSCTL |
26352 |
++ select GRKERNSEC_LINK |
26353 |
++ select GRKERNSEC_FIFO |
26354 |
++ select GRKERNSEC_EXECVE |
26355 |
++ select GRKERNSEC_DMESG |
26356 |
++ select GRKERNSEC_RANDNET |
26357 |
++ select GRKERNSEC_FORKFAIL |
26358 |
++ select GRKERNSEC_TIME |
26359 |
++ select GRKERNSEC_SIGNAL |
26360 |
++ select GRKERNSEC_CHROOT |
26361 |
++ select GRKERNSEC_CHROOT_UNIX |
26362 |
++ select GRKERNSEC_CHROOT_MOUNT |
26363 |
++ select GRKERNSEC_CHROOT_PIVOT |
26364 |
++ select GRKERNSEC_CHROOT_DOUBLE |
26365 |
++ select GRKERNSEC_CHROOT_CHDIR |
26366 |
++ select GRKERNSEC_CHROOT_MKNOD |
26367 |
++ select GRKERNSEC_PROC |
26368 |
++ select GRKERNSEC_PROC_USERGROUP |
26369 |
++ select GRKERNSEC_MODSTOP if (MODULES) |
26370 |
++ select PAX_RANDUSTACK |
26371 |
++ select PAX_ASLR |
26372 |
++ select PAX_RANDMMAP |
26373 |
++ |
26374 |
++ help |
26375 |
++ If you say Y here, several features in addition to those included |
26376 |
++ in the low additional security level will be enabled. These |
26377 |
++ features provide even more security to your system, though in rare |
26378 |
++ cases they may be incompatible with very old or poorly written |
26379 |
++ software. If you enable this option, make sure that your auth |
26380 |
++ service (identd) is running as gid 1001. With this option, |
26381 |
++ the following features (in addition to those provided in the |
26382 |
++ low additional security level) will be enabled: |
26383 |
++ |
26384 |
++ - Failed fork logging |
26385 |
++ - Time change logging |
26386 |
++ - Signal logging |
26387 |
++ - Deny mounts in chroot |
26388 |
++ - Deny double chrooting |
26389 |
++ - Deny sysctl writes in chroot |
26390 |
++ - Deny mknod in chroot |
26391 |
++ - Deny access to abstract AF_UNIX sockets out of chroot |
26392 |
++ - Deny pivot_root in chroot |
26393 |
++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port |
26394 |
++ - /proc restrictions with special GID set to 10 (usually wheel) |
26395 |
++ - Address Space Layout Randomization (ASLR) |
26396 |
++ |
26397 |
++config GRKERNSEC_HIGH |
26398 |
++ bool "High" |
26399 |
++ select GRKERNSEC_LINK |
26400 |
++ select GRKERNSEC_FIFO |
26401 |
++ select GRKERNSEC_EXECVE |
26402 |
++ select GRKERNSEC_DMESG |
26403 |
++ select GRKERNSEC_FORKFAIL |
26404 |
++ select GRKERNSEC_TIME |
26405 |
++ select GRKERNSEC_SIGNAL |
26406 |
++ select GRKERNSEC_CHROOT_SHMAT |
26407 |
++ select GRKERNSEC_CHROOT_UNIX |
26408 |
++ select GRKERNSEC_CHROOT_MOUNT |
26409 |
++ select GRKERNSEC_CHROOT_FCHDIR |
26410 |
++ select GRKERNSEC_CHROOT_PIVOT |
26411 |
++ select GRKERNSEC_CHROOT_DOUBLE |
26412 |
++ select GRKERNSEC_CHROOT_CHDIR |
26413 |
++ select GRKERNSEC_CHROOT_MKNOD |
26414 |
++ select GRKERNSEC_CHROOT_CAPS |
26415 |
++ select GRKERNSEC_CHROOT_SYSCTL |
26416 |
++ select GRKERNSEC_CHROOT_FINDTASK |
26417 |
++ select GRKERNSEC_PROC |
26418 |
++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR) |
26419 |
++ select GRKERNSEC_HIDESYM |
26420 |
++ select GRKERNSEC_BRUTE |
26421 |
++ select GRKERNSEC_PROC_USERGROUP |
26422 |
++ select GRKERNSEC_KMEM |
26423 |
++ select GRKERNSEC_RESLOG |
26424 |
++ select GRKERNSEC_RANDNET |
26425 |
++ select GRKERNSEC_PROC_ADD |
26426 |
++ select GRKERNSEC_CHROOT_CHMOD |
26427 |
++ select GRKERNSEC_CHROOT_NICE |
26428 |
++ select GRKERNSEC_AUDIT_MOUNT |
26429 |
++ select GRKERNSEC_MODSTOP if (MODULES) |
26430 |
++ select PAX |
26431 |
++ select PAX_RANDUSTACK |
26432 |
++ select PAX_ASLR |
26433 |
++ select PAX_RANDMMAP |
26434 |
++ select PAX_NOEXEC |
26435 |
++ select PAX_MPROTECT |
26436 |
++ select PAX_EI_PAX |
26437 |
++ select PAX_PT_PAX_FLAGS |
26438 |
++ select PAX_HAVE_ACL_FLAGS |
26439 |
++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK)) |
26440 |
++ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO) |
26441 |
++ select PAX_RANDKSTACK if (X86_TSC && !X86_64) |
26442 |
++ select PAX_SEGMEXEC if (X86 && !X86_64) |
26443 |
++ select PAX_PAGEEXEC if (!X86) |
26444 |
++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64) |
26445 |
++ select PAX_DLRESOLVE if (SPARC32 || SPARC64) |
26446 |
++ select PAX_SYSCALL if (PPC32) |
26447 |
++ select PAX_EMUTRAMP if (PARISC) |
26448 |
++ select PAX_EMUSIGRT if (PARISC) |
26449 |
++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC) |
26450 |
++ help |
26451 |
++ If you say Y here, many of the features of grsecurity will be |
26452 |
++ enabled, which will protect you against many kinds of attacks |
26453 |
++ against your system. The heightened security comes at a cost |
26454 |
++ of an increased chance of incompatibilities with rare software |
26455 |
++ on your machine. Since this security level enables PaX, you should |
26456 |
++ view <http://pax.grsecurity.net> and read about the PaX |
26457 |
++ project. While you are there, download chpax and run it on |
26458 |
++ binaries that cause problems with PaX. Also remember that |
26459 |
++ since the /proc restrictions are enabled, you must run your |
26460 |
++ identd as gid 1001. This security level enables the following |
26461 |
++ features in addition to those listed in the low and medium |
26462 |
++ security levels: |
26463 |
++ |
26464 |
++ - Additional /proc restrictions |
26465 |
++ - Chmod restrictions in chroot |
26466 |
++ - No signals, ptrace, or viewing of processes outside of chroot |
26467 |
++ - Capability restrictions in chroot |
26468 |
++ - Deny fchdir out of chroot |
26469 |
++ - Priority restrictions in chroot |
26470 |
++ - Segmentation-based implementation of PaX |
26471 |
++ - Mprotect restrictions |
26472 |
++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat] |
26473 |
++ - Kernel stack randomization |
26474 |
++ - Mount/unmount/remount logging |
26475 |
++ - Kernel symbol hiding |
26476 |
++ - Prevention of memory exhaustion-based exploits |
26477 |
++config GRKERNSEC_CUSTOM |
26478 |
++ bool "Custom" |
26479 |
++ help |
26480 |
++ If you say Y here, you will be able to configure every grsecurity |
26481 |
++ option, which allows you to enable many more features that aren't |
26482 |
++ covered in the basic security levels. These additional features |
26483 |
++ include TPE, socket restrictions, and the sysctl system for |
26484 |
++ grsecurity. It is advised that you read through the help for |
26485 |
++ each option to determine its usefulness in your situation. |
26486 |
++ |
26487 |
++endchoice |
26488 |
++ |
26489 |
++menu "Address Space Protection" |
26490 |
++depends on GRKERNSEC |
26491 |
++ |
26492 |
++config GRKERNSEC_KMEM |
26493 |
++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port" |
26494 |
++ help |
26495 |
++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to |
26496 |
++ be written to via mmap or otherwise to modify the running kernel. |
26497 |
++ /dev/port will also not be allowed to be opened. If you have module |
26498 |
++ support disabled, enabling this will close up four ways that are |
26499 |
++ currently used to insert malicious code into the running kernel. |
26500 |
++ Even with all these features enabled, we still highly recommend that |
26501 |
++ you use the RBAC system, as it is still possible for an attacker to |
26502 |
++ modify the running kernel through privileged I/O granted by ioperm/iopl. |
26503 |
++ If you are not using XFree86, you may be able to stop this additional |
26504 |
++ case by enabling the 'Disable privileged I/O' option. Though nothing |
26505 |
++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem, |
26506 |
++ but only to video memory, which is the only writing we allow in this |
26507 |
++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will |
26508 |
++ not be allowed to mprotect it with PROT_WRITE later. |
26509 |
++ It is highly recommended that you say Y here if you meet all the |
26510 |
++ conditions above. |
26511 |
++ |
26512 |
++config GRKERNSEC_IO |
26513 |
++ bool "Disable privileged I/O" |
26514 |
++ depends on X86 |
26515 |
++ select RTC |
26516 |
++ help |
26517 |
++ If you say Y here, all ioperm and iopl calls will return an error. |
26518 |
++ Ioperm and iopl can be used to modify the running kernel. |
26519 |
++ Unfortunately, some programs need this access to operate properly, |
26520 |
++ the most notable of which are XFree86 and hwclock. hwclock can be |
26521 |
++ remedied by having RTC support in the kernel, so CONFIG_RTC is |
26522 |
++ enabled if this option is enabled, to ensure that hwclock operates |
26523 |
++ correctly. XFree86 still will not operate correctly with this option |
26524 |
++ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86 |
26525 |
++ and you still want to protect your kernel against modification, |
26526 |
++ use the RBAC system. |
26527 |
++ |
26528 |
++config GRKERNSEC_PROC_MEMMAP |
26529 |
++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]" |
26530 |
++ depends on PAX_NOEXEC || PAX_ASLR |
26531 |
++ help |
26532 |
++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will |
26533 |
++ give no information about the addresses of its mappings if |
26534 |
++ PaX features that rely on random addresses are enabled on the task. |
26535 |
++ If you use PaX it is greatly recommended that you say Y here as it |
26536 |
++ closes up a hole that makes the full ASLR useless for suid |
26537 |
++ binaries. |
26538 |
++ |
26539 |
++config GRKERNSEC_BRUTE |
26540 |
++ bool "Deter exploit bruteforcing" |
26541 |
++ help |
26542 |
++ If you say Y here, attempts to bruteforce exploits against forking |
26543 |
++ daemons such as apache or sshd will be deterred. When a child of a |
26544 |
++ forking daemon is killed by PaX or crashes due to an illegal |
26545 |
++ instruction, the parent process will be delayed 30 seconds upon every |
26546 |
++ subsequent fork until the administrator is able to assess the |
26547 |
++ situation and restart the daemon. It is recommended that you also |
26548 |
++ enable signal logging in the auditing section so that logs are |
26549 |
++ generated when a process performs an illegal instruction. |
26550 |
++ |
26551 |
++config GRKERNSEC_MODSTOP |
26552 |
++ bool "Runtime module disabling" |
26553 |
++ depends on MODULES |
26554 |
++ help |
26555 |
++ If you say Y here, you will be able to disable the ability to (un)load |
26556 |
++ modules at runtime. This feature is useful if you need the ability |
26557 |
++ to load kernel modules at boot time, but do not want to allow an |
26558 |
++ attacker to load a rootkit kernel module into the system, or to remove |
26559 |
++ a loaded kernel module important to system functioning. You should |
26560 |
++ enable the /dev/mem protection feature as well, since rootkits can be |
26561 |
++ inserted into the kernel via other methods than kernel modules. Since |
26562 |
++ an untrusted module could still be loaded by modifying init scripts and |
26563 |
++ rebooting the system, it is also recommended that you enable the RBAC |
26564 |
++ system. If you enable this option, a sysctl option with name |
26565 |
++ "disable_modules" will be created. Setting this option to "1" disables |
26566 |
++ module loading. After this option is set, no further writes to it are |
26567 |
++ allowed until the system is rebooted. |
26568 |
++ |
26569 |
++config GRKERNSEC_HIDESYM |
26570 |
++ bool "Hide kernel symbols" |
26571 |
++ help |
26572 |
++ If you say Y here, getting information on loaded modules, and |
26573 |
++ displaying all kernel symbols through a syscall will be restricted |
26574 |
++ to users with CAP_SYS_MODULE. This option is only effective |
26575 |
++ provided the following conditions are met: |
26576 |
++ 1) The kernel using grsecurity is not precompiled by some distribution |
26577 |
++ 2) You are using the RBAC system and hiding other files such as your |
26578 |
++ kernel image and System.map |
26579 |
++ 3) You have the additional /proc restrictions enabled, which removes |
26580 |
++ /proc/kcore |
26581 |
++ If the above conditions are met, this option will aid to provide a |
26582 |
++ useful protection against local and remote kernel exploitation of |
26583 |
++ overflows and arbitrary read/write vulnerabilities. |
26584 |
++ |
26585 |
++endmenu |
26586 |
++menu "Role Based Access Control Options" |
26587 |
++depends on GRKERNSEC |
26588 |
++ |
26589 |
++config GRKERNSEC_ACL_HIDEKERN |
26590 |
++ bool "Hide kernel processes" |
26591 |
++ help |
26592 |
++ If you say Y here, all kernel threads will be hidden to all |
26593 |
++ processes but those whose subject has the "view hidden processes" |
26594 |
++ flag. |
26595 |
++ |
26596 |
++config GRKERNSEC_ACL_MAXTRIES |
26597 |
++ int "Maximum tries before password lockout" |
26598 |
++ default 3 |
26599 |
++ help |
26600 |
++ This option enforces the maximum number of times a user can attempt |
26601 |
++ to authorize themselves with the grsecurity RBAC system before being |
26602 |
++ denied the ability to attempt authorization again for a specified time. |
26603 |
++ The lower the number, the harder it will be to brute-force a password. |
26604 |
++ |
26605 |
++config GRKERNSEC_ACL_TIMEOUT |
26606 |
++ int "Time to wait after max password tries, in seconds" |
26607 |
++ default 30 |
26608 |
++ help |
26609 |
++ This option specifies the time the user must wait after attempting to |
26610 |
++ authorize to the RBAC system with the maximum number of invalid |
26611 |
++ passwords. The higher the number, the harder it will be to brute-force |
26612 |
++ a password. |
26613 |
++ |
26614 |
++endmenu |
26615 |
++menu "Filesystem Protections" |
26616 |
++depends on GRKERNSEC |
26617 |
++ |
26618 |
++config GRKERNSEC_PROC |
26619 |
++ bool "Proc restrictions" |
26620 |
++ help |
26621 |
++ If you say Y here, the permissions of the /proc filesystem |
26622 |
++ will be altered to enhance system security and privacy. You MUST |
26623 |
++ choose either a user only restriction or a user and group restriction. |
26624 |
++ Depending upon the option you choose, you can either restrict users to |
26625 |
++ see only the processes they themselves run, or choose a group that can |
26626 |
++ view all processes and files normally restricted to root if you choose |
26627 |
++ the "restrict to user only" option. NOTE: If you're running identd as |
26628 |
++ a non-root user, you will have to run it as the group you specify here. |
26629 |
++ |
26630 |
++config GRKERNSEC_PROC_USER |
26631 |
++ bool "Restrict /proc to user only" |
26632 |
++ depends on GRKERNSEC_PROC |
26633 |
++ help |
26634 |
++ If you say Y here, non-root users will only be able to view their own |
26635 |
++ processes, and restricts them from viewing network-related information, |
26636 |
++ and viewing kernel symbol and module information. |
26637 |
++ |
26638 |
++config GRKERNSEC_PROC_USERGROUP |
26639 |
++ bool "Allow special group" |
26640 |
++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER |
26641 |
++ help |
26642 |
++ If you say Y here, you will be able to select a group that will be |
26643 |
++ able to view all processes, network-related information, and |
26644 |
++ kernel and symbol information. This option is useful if you want |
26645 |
++ to run identd as a non-root user. |
26646 |
++ |
26647 |
++config GRKERNSEC_PROC_GID |
26648 |
++ int "GID for special group" |
26649 |
++ depends on GRKERNSEC_PROC_USERGROUP |
26650 |
++ default 1001 |
26651 |
++ |
26652 |
++config GRKERNSEC_PROC_ADD |
26653 |
++ bool "Additional restrictions" |
26654 |
++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP |
26655 |
++ help |
26656 |
++ If you say Y here, additional restrictions will be placed on |
26657 |
++ /proc that keep normal users from viewing device information and |
26658 |
++ slabinfo information that could be useful for exploits. |
26659 |
++ |
26660 |
++config GRKERNSEC_LINK |
26661 |
++ bool "Linking restrictions" |
26662 |
++ help |
26663 |
++ If you say Y here, /tmp race exploits will be prevented, since users |
26664 |
++ will no longer be able to follow symlinks owned by other users in |
26665 |
++ world-writable +t directories (i.e. /tmp), unless the owner of the |
26666 |
++ symlink is the owner of the directory. users will also not be |
26667 |
++ able to hardlink to files they do not own. If the sysctl option is |
26668 |
++ enabled, a sysctl option with name "linking_restrictions" is created. |
26669 |
++ |
26670 |
++config GRKERNSEC_FIFO |
26671 |
++ bool "FIFO restrictions" |
26672 |
++ help |
26673 |
++ If you say Y here, users will not be able to write to FIFOs they don't |
26674 |
++ own in world-writable +t directories (i.e. /tmp), unless the owner of |
26675 |
++ the FIFO is the same owner of the directory it's held in. If the sysctl |
26676 |
++ option is enabled, a sysctl option with name "fifo_restrictions" is |
26677 |
++ created. |
26678 |
++ |
26679 |
++config GRKERNSEC_CHROOT |
26680 |
++ bool "Chroot jail restrictions" |
26681 |
++ help |
26682 |
++ If you say Y here, you will be able to choose several options that will |
26683 |
++ make breaking out of a chrooted jail much more difficult. If you |
26684 |
++ encounter no software incompatibilities with the following options, it |
26685 |
++ is recommended that you enable each one. |
26686 |
++ |
26687 |
++config GRKERNSEC_CHROOT_MOUNT |
26688 |
++ bool "Deny mounts" |
26689 |
++ depends on GRKERNSEC_CHROOT |
26690 |
++ help |
26691 |
++ If you say Y here, processes inside a chroot will not be able to |
26692 |
++ mount or remount filesystems. If the sysctl option is enabled, a |
26693 |
++ sysctl option with name "chroot_deny_mount" is created. |
26694 |
++ |
26695 |
++config GRKERNSEC_CHROOT_DOUBLE |
26696 |
++ bool "Deny double-chroots" |
26697 |
++ depends on GRKERNSEC_CHROOT |
26698 |
++ help |
26699 |
++ If you say Y here, processes inside a chroot will not be able to chroot |
26700 |
++ again outside the chroot. This is a widely used method of breaking |
26701 |
++ out of a chroot jail and should not be allowed. If the sysctl |
26702 |
++ option is enabled, a sysctl option with name |
26703 |
++ "chroot_deny_chroot" is created. |
26704 |
++ |
26705 |
++config GRKERNSEC_CHROOT_PIVOT |
26706 |
++ bool "Deny pivot_root in chroot" |
26707 |
++ depends on GRKERNSEC_CHROOT |
26708 |
++ help |
26709 |
++ If you say Y here, processes inside a chroot will not be able to use |
26710 |
++ a function called pivot_root() that was introduced in Linux 2.3.41. It |
26711 |
++ works similar to chroot in that it changes the root filesystem. This |
26712 |
++ function could be misused in a chrooted process to attempt to break out |
26713 |
++ of the chroot, and therefore should not be allowed. If the sysctl |
26714 |
++ option is enabled, a sysctl option with name "chroot_deny_pivot" is |
26715 |
++ created. |
26716 |
++ |
26717 |
++config GRKERNSEC_CHROOT_CHDIR |
26718 |
++ bool "Enforce chdir(\"/\") on all chroots" |
26719 |
++ depends on GRKERNSEC_CHROOT |
26720 |
++ help |
26721 |
++ If you say Y here, the current working directory of all newly-chrooted |
26722 |
++ applications will be set to the the root directory of the chroot. |
26723 |
++ The man page on chroot(2) states: |
26724 |
++ Note that this call does not change the current working |
26725 |
++ directory, so that `.' can be outside the tree rooted at |
26726 |
++ `/'. In particular, the super-user can escape from a |
26727 |
++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'. |
26728 |
++ |
26729 |
++ It is recommended that you say Y here, since it's not known to break |
26730 |
++ any software. If the sysctl option is enabled, a sysctl option with |
26731 |
++ name "chroot_enforce_chdir" is created. |
26732 |
++ |
26733 |
++config GRKERNSEC_CHROOT_CHMOD |
26734 |
++ bool "Deny (f)chmod +s" |
26735 |
++ depends on GRKERNSEC_CHROOT |
26736 |
++ help |
26737 |
++ If you say Y here, processes inside a chroot will not be able to chmod |
26738 |
++ or fchmod files to make them have suid or sgid bits. This protects |
26739 |
++ against another published method of breaking a chroot. If the sysctl |
26740 |
++ option is enabled, a sysctl option with name "chroot_deny_chmod" is |
26741 |
++ created. |
26742 |
++ |
26743 |
++config GRKERNSEC_CHROOT_FCHDIR |
26744 |
++ bool "Deny fchdir out of chroot" |
26745 |
++ depends on GRKERNSEC_CHROOT |
26746 |
++ help |
26747 |
++ If you say Y here, a well-known method of breaking chroots by fchdir'ing |
26748 |
++ to a file descriptor of the chrooting process that points to a directory |
26749 |
++ outside the filesystem will be stopped. If the sysctl option |
26750 |
++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created. |
26751 |
++ |
26752 |
++config GRKERNSEC_CHROOT_MKNOD |
26753 |
++ bool "Deny mknod" |
26754 |
++ depends on GRKERNSEC_CHROOT |
26755 |
++ help |
26756 |
++ If you say Y here, processes inside a chroot will not be allowed to |
26757 |
++ mknod. The problem with using mknod inside a chroot is that it |
26758 |
++ would allow an attacker to create a device entry that is the same |
26759 |
++ as one on the physical root of your system, which could range from |
26760 |
++ anything from the console device to a device for your harddrive (which |
26761 |
++ they could then use to wipe the drive or steal data). It is recommended |
26762 |
++ that you say Y here, unless you run into software incompatibilities. |
26763 |
++ If the sysctl option is enabled, a sysctl option with name |
26764 |
++ "chroot_deny_mknod" is created. |
26765 |
++ |
26766 |
++config GRKERNSEC_CHROOT_SHMAT |
26767 |
++ bool "Deny shmat() out of chroot" |
26768 |
++ depends on GRKERNSEC_CHROOT |
26769 |
++ help |
26770 |
++ If you say Y here, processes inside a chroot will not be able to attach |
26771 |
++ to shared memory segments that were created outside of the chroot jail. |
26772 |
++ It is recommended that you say Y here. If the sysctl option is enabled, |
26773 |
++ a sysctl option with name "chroot_deny_shmat" is created. |
26774 |
++ |
26775 |
++config GRKERNSEC_CHROOT_UNIX |
26776 |
++ bool "Deny access to abstract AF_UNIX sockets out of chroot" |
26777 |
++ depends on GRKERNSEC_CHROOT |
26778 |
++ help |
26779 |
++ If you say Y here, processes inside a chroot will not be able to |
26780 |
++ connect to abstract (meaning not belonging to a filesystem) Unix |
26781 |
++ domain sockets that were bound outside of a chroot. It is recommended |
26782 |
++ that you say Y here. If the sysctl option is enabled, a sysctl option |
26783 |
++ with name "chroot_deny_unix" is created. |
26784 |
++ |
26785 |
++config GRKERNSEC_CHROOT_FINDTASK |
26786 |
++ bool "Protect outside processes" |
26787 |
++ depends on GRKERNSEC_CHROOT |
26788 |
++ help |
26789 |
++ If you say Y here, processes inside a chroot will not be able to |
26790 |
++ kill, send signals with fcntl, ptrace, capget, getpgid, getsid, |
26791 |
++ or view any process outside of the chroot. If the sysctl |
26792 |
++ option is enabled, a sysctl option with name "chroot_findtask" is |
26793 |
++ created. |
26794 |
++ |
26795 |
++config GRKERNSEC_CHROOT_NICE |
26796 |
++ bool "Restrict priority changes" |
26797 |
++ depends on GRKERNSEC_CHROOT |
26798 |
++ help |
26799 |
++ If you say Y here, processes inside a chroot will not be able to raise |
26800 |
++ the priority of processes in the chroot, or alter the priority of |
26801 |
++ processes outside the chroot. This provides more security than simply |
26802 |
++ removing CAP_SYS_NICE from the process' capability set. If the |
26803 |
++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice" |
26804 |
++ is created. |
26805 |
++ |
26806 |
++config GRKERNSEC_CHROOT_SYSCTL |
26807 |
++ bool "Deny sysctl writes" |
26808 |
++ depends on GRKERNSEC_CHROOT |
26809 |
++ help |
26810 |
++ If you say Y here, an attacker in a chroot will not be able to |
26811 |
++ write to sysctl entries, either by sysctl(2) or through a /proc |
26812 |
++ interface. It is strongly recommended that you say Y here. If the |
26813 |
++ sysctl option is enabled, a sysctl option with name |
26814 |
++ "chroot_deny_sysctl" is created. |
26815 |
++ |
26816 |
++config GRKERNSEC_CHROOT_CAPS |
26817 |
++ bool "Capability restrictions" |
26818 |
++ depends on GRKERNSEC_CHROOT |
26819 |
++ help |
26820 |
++ If you say Y here, the capabilities on all root processes within a |
26821 |
++ chroot jail will be lowered to stop module insertion, raw i/o, |
26822 |
++ system and net admin tasks, rebooting the system, modifying immutable |
26823 |
++ files, modifying IPC owned by another, and changing the system time. |
26824 |
++ This is left an option because it can break some apps. Disable this |
26825 |
++ if your chrooted apps are having problems performing those kinds of |
26826 |
++ tasks. If the sysctl option is enabled, a sysctl option with |
26827 |
++ name "chroot_caps" is created. |
26828 |
++ |
26829 |
++endmenu |
26830 |
++menu "Kernel Auditing" |
26831 |
++depends on GRKERNSEC |
26832 |
++ |
26833 |
++config GRKERNSEC_AUDIT_GROUP |
26834 |
++ bool "Single group for auditing" |
26835 |
++ help |
26836 |
++ If you say Y here, the exec, chdir, (un)mount, and ipc logging features |
26837 |
++ will only operate on a group you specify. This option is recommended |
26838 |
++ if you only want to watch certain users instead of having a large |
26839 |
++ amount of logs from the entire system. If the sysctl option is enabled, |
26840 |
++ a sysctl option with name "audit_group" is created. |
26841 |
++ |
26842 |
++config GRKERNSEC_AUDIT_GID |
26843 |
++ int "GID for auditing" |
26844 |
++ depends on GRKERNSEC_AUDIT_GROUP |
26845 |
++ default 1007 |
26846 |
++ |
26847 |
++config GRKERNSEC_EXECLOG |
26848 |
++ bool "Exec logging" |
26849 |
++ help |
26850 |
++ If you say Y here, all execve() calls will be logged (since the |
26851 |
++ other exec*() calls are frontends to execve(), all execution |
26852 |
++ will be logged). Useful for shell-servers that like to keep track |
26853 |
++ of their users. If the sysctl option is enabled, a sysctl option with |
26854 |
++ name "exec_logging" is created. |
26855 |
++ WARNING: This option when enabled will produce a LOT of logs, especially |
26856 |
++ on an active system. |
26857 |
++ |
26858 |
++config GRKERNSEC_RESLOG |
26859 |
++ bool "Resource logging" |
26860 |
++ help |
26861 |
++ If you say Y here, all attempts to overstep resource limits will |
26862 |
++ be logged with the resource name, the requested size, and the current |
26863 |
++ limit. It is highly recommended that you say Y here. If the sysctl |
26864 |
++ option is enabled, a sysctl option with name "resource_logging" is |
26865 |
++ created. If the RBAC system is enabled, the sysctl value is ignored. |
26866 |
++ |
26867 |
++config GRKERNSEC_CHROOT_EXECLOG |
26868 |
++ bool "Log execs within chroot" |
26869 |
++ help |
26870 |
++ If you say Y here, all executions inside a chroot jail will be logged |
26871 |
++ to syslog. This can cause a large amount of logs if certain |
26872 |
++ applications (eg. djb's daemontools) are installed on the system, and |
26873 |
++ is therefore left as an option. If the sysctl option is enabled, a |
26874 |
++ sysctl option with name "chroot_execlog" is created. |
26875 |
++ |
26876 |
++config GRKERNSEC_AUDIT_CHDIR |
26877 |
++ bool "Chdir logging" |
26878 |
++ help |
26879 |
++ If you say Y here, all chdir() calls will be logged. If the sysctl |
26880 |
++ option is enabled, a sysctl option with name "audit_chdir" is created. |
26881 |
++ |
26882 |
++config GRKERNSEC_AUDIT_MOUNT |
26883 |
++ bool "(Un)Mount logging" |
26884 |
++ help |
26885 |
++ If you say Y here, all mounts and unmounts will be logged. If the |
26886 |
++ sysctl option is enabled, a sysctl option with name "audit_mount" is |
26887 |
++ created. |
26888 |
++ |
26889 |
++config GRKERNSEC_AUDIT_IPC |
26890 |
++ bool "IPC logging" |
26891 |
++ help |
26892 |
++ If you say Y here, creation and removal of message queues, semaphores, |
26893 |
++ and shared memory will be logged. If the sysctl option is enabled, a |
26894 |
++ sysctl option with name "audit_ipc" is created. |
26895 |
++ |
26896 |
++config GRKERNSEC_SIGNAL |
26897 |
++ bool "Signal logging" |
26898 |
++ help |
26899 |
++ If you say Y here, certain important signals will be logged, such as |
26900 |
++ SIGSEGV, which will as a result inform you of when a error in a program |
26901 |
++ occurred, which in some cases could mean a possible exploit attempt. |
26902 |
++ If the sysctl option is enabled, a sysctl option with name |
26903 |
++ "signal_logging" is created. |
26904 |
++ |
26905 |
++config GRKERNSEC_FORKFAIL |
26906 |
++ bool "Fork failure logging" |
26907 |
++ help |
26908 |
++ If you say Y here, all failed fork() attempts will be logged. |
26909 |
++ This could suggest a fork bomb, or someone attempting to overstep |
26910 |
++ their process limit. If the sysctl option is enabled, a sysctl option |
26911 |
++ with name "forkfail_logging" is created. |
26912 |
++ |
26913 |
++config GRKERNSEC_TIME |
26914 |
++ bool "Time change logging" |
26915 |
++ help |
26916 |
++ If you say Y here, any changes of the system clock will be logged. |
26917 |
++ If the sysctl option is enabled, a sysctl option with name |
26918 |
++ "timechange_logging" is created. |
26919 |
++ |
26920 |
++config GRKERNSEC_PROC_IPADDR |
26921 |
++ bool "/proc/<pid>/ipaddr support" |
26922 |
++ help |
26923 |
++ If you say Y here, a new entry will be added to each /proc/<pid> |
26924 |
++ directory that contains the IP address of the person using the task. |
26925 |
++ The IP is carried across local TCP and AF_UNIX stream sockets. |
26926 |
++ This information can be useful for IDS/IPSes to perform remote response |
26927 |
++ to a local attack. The entry is readable by only the owner of the |
26928 |
++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via |
26929 |
++ the RBAC system), and thus does not create privacy concerns. |
26930 |
++ |
26931 |
++config GRKERNSEC_AUDIT_TEXTREL |
26932 |
++ bool 'ELF text relocations logging (READ HELP)' |
26933 |
++ depends on PAX_MPROTECT |
26934 |
++ help |
26935 |
++ If you say Y here, text relocations will be logged with the filename |
26936 |
++ of the offending library or binary. The purpose of the feature is |
26937 |
++ to help Linux distribution developers get rid of libraries and |
26938 |
++ binaries that need text relocations which hinder the future progress |
26939 |
++ of PaX. Only Linux distribution developers should say Y here, and |
26940 |
++ never on a production machine, as this option creates an information |
26941 |
++ leak that could aid an attacker in defeating the randomization of |
26942 |
++ a single memory region. If the sysctl option is enabled, a sysctl |
26943 |
++ option with name "audit_textrel" is created. |
26944 |
++ |
26945 |
++endmenu |
26946 |
++ |
26947 |
++menu "Executable Protections" |
26948 |
++depends on GRKERNSEC |
26949 |
++ |
26950 |
++config GRKERNSEC_EXECVE |
26951 |
++ bool "Enforce RLIMIT_NPROC on execs" |
26952 |
++ help |
26953 |
++ If you say Y here, users with a resource limit on processes will |
26954 |
++ have the value checked during execve() calls. The current system |
26955 |
++ only checks the system limit during fork() calls. If the sysctl option |
26956 |
++ is enabled, a sysctl option with name "execve_limiting" is created. |
26957 |
++ |
26958 |
++config GRKERNSEC_DMESG |
26959 |
++ bool "Dmesg(8) restriction" |
26960 |
++ help |
26961 |
++ If you say Y here, non-root users will not be able to use dmesg(8) |
26962 |
++ to view up to the last 4kb of messages in the kernel's log buffer. |
26963 |
++ If the sysctl option is enabled, a sysctl option with name "dmesg" is |
26964 |
++ created. |
26965 |
++ |
26966 |
++config GRKERNSEC_TPE |
26967 |
++ bool "Trusted Path Execution (TPE)" |
26968 |
++ help |
26969 |
++ If you say Y here, you will be able to choose a gid to add to the |
26970 |
++ supplementary groups of users you want to mark as "untrusted." |
26971 |
++ These users will not be able to execute any files that are not in |
26972 |
++ root-owned directories writable only by root. If the sysctl option |
26973 |
++ is enabled, a sysctl option with name "tpe" is created. |
26974 |
++ |
26975 |
++config GRKERNSEC_TPE_ALL |
26976 |
++ bool "Partially restrict non-root users" |
26977 |
++ depends on GRKERNSEC_TPE |
26978 |
++ help |
26979 |
++ If you say Y here, All non-root users other than the ones in the |
26980 |
++ group specified in the main TPE option will only be allowed to |
26981 |
++ execute files in directories they own that are not group or |
26982 |
++ world-writable, or in directories owned by root and writable only by |
26983 |
++ root. If the sysctl option is enabled, a sysctl option with name |
26984 |
++ "tpe_restrict_all" is created. |
26985 |
++ |
26986 |
++config GRKERNSEC_TPE_INVERT |
26987 |
++ bool "Invert GID option" |
26988 |
++ depends on GRKERNSEC_TPE |
26989 |
++ help |
26990 |
++ If you say Y here, the group you specify in the TPE configuration will |
26991 |
++ decide what group TPE restrictions will be *disabled* for. This |
26992 |
++ option is useful if you want TPE restrictions to be applied to most |
26993 |
++ users on the system. |
26994 |
++ |
26995 |
++config GRKERNSEC_TPE_GID |
26996 |
++ int "GID for untrusted users" |
26997 |
++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT |
26998 |
++ default 1005 |
26999 |
++ help |
27000 |
++ If you have selected the "Invert GID option" above, setting this |
27001 |
++ GID determines what group TPE restrictions will be *disabled* for. |
27002 |
++ If you have not selected the "Invert GID option" above, setting this |
27003 |
++ GID determines what group TPE restrictions will be *enabled* for. |
27004 |
++ If the sysctl option is enabled, a sysctl option with name "tpe_gid" |
27005 |
++ is created. |
27006 |
++ |
27007 |
++config GRKERNSEC_TPE_GID |
27008 |
++ int "GID for trusted users" |
27009 |
++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT |
27010 |
++ default 1005 |
27011 |
++ help |
27012 |
++ If you have selected the "Invert GID option" above, setting this |
27013 |
++ GID determines what group TPE restrictions will be *disabled* for. |
27014 |
++ If you have not selected the "Invert GID option" above, setting this |
27015 |
++ GID determines what group TPE restrictions will be *enabled* for. |
27016 |
++ If the sysctl option is enabled, a sysctl option with name "tpe_gid" |
27017 |
++ is created. |
27018 |
++ |
27019 |
++endmenu |
27020 |
++menu "Network Protections" |
27021 |
++depends on GRKERNSEC |
27022 |
++ |
27023 |
++config GRKERNSEC_RANDNET |
27024 |
++ bool "Larger entropy pools" |
27025 |
++ help |
27026 |
++ If you say Y here, the entropy pools used for many features of Linux |
27027 |
++ and grsecurity will be doubled in size. Since several grsecurity |
27028 |
++ features use additional randomness, it is recommended that you say Y |
27029 |
++ here. Saying Y here has a similar effect as modifying |
27030 |
++ /proc/sys/kernel/random/poolsize. |
27031 |
++ |
27032 |
++config GRKERNSEC_SOCKET |
27033 |
++ bool "Socket restrictions" |
27034 |
++ help |
27035 |
++ If you say Y here, you will be able to choose from several options. |
27036 |
++ If you assign a GID on your system and add it to the supplementary |
27037 |
++ groups of users you want to restrict socket access to, this patch |
27038 |
++ will perform up to three things, based on the option(s) you choose. |
27039 |
++ |
27040 |
++config GRKERNSEC_SOCKET_ALL |
27041 |
++ bool "Deny any sockets to group" |
27042 |
++ depends on GRKERNSEC_SOCKET |
27043 |
++ help |
27044 |
++ If you say Y here, you will be able to choose a GID of whose users will |
27045 |
++ be unable to connect to other hosts from your machine or run server |
27046 |
++ applications from your machine. If the sysctl option is enabled, a |
27047 |
++ sysctl option with name "socket_all" is created. |
27048 |
++ |
27049 |
++config GRKERNSEC_SOCKET_ALL_GID |
27050 |
++ int "GID to deny all sockets for" |
27051 |
++ depends on GRKERNSEC_SOCKET_ALL |
27052 |
++ default 1004 |
27053 |
++ help |
27054 |
++ Here you can choose the GID to disable socket access for. Remember to |
27055 |
++ add the users you want socket access disabled for to the GID |
27056 |
++ specified here. If the sysctl option is enabled, a sysctl option |
27057 |
++ with name "socket_all_gid" is created. |
27058 |
++ |
27059 |
++config GRKERNSEC_SOCKET_CLIENT |
27060 |
++ bool "Deny client sockets to group" |
27061 |
++ depends on GRKERNSEC_SOCKET |
27062 |
++ help |
27063 |
++ If you say Y here, you will be able to choose a GID of whose users will |
27064 |
++ be unable to connect to other hosts from your machine, but will be |
27065 |
++ able to run servers. If this option is enabled, all users in the group |
27066 |
++ you specify will have to use passive mode when initiating ftp transfers |
27067 |
++ from the shell on your machine. If the sysctl option is enabled, a |
27068 |
++ sysctl option with name "socket_client" is created. |
27069 |
++ |
27070 |
++config GRKERNSEC_SOCKET_CLIENT_GID |
27071 |
++ int "GID to deny client sockets for" |
27072 |
++ depends on GRKERNSEC_SOCKET_CLIENT |
27073 |
++ default 1003 |
27074 |
++ help |
27075 |
++ Here you can choose the GID to disable client socket access for. |
27076 |
++ Remember to add the users you want client socket access disabled for to |
27077 |
++ the GID specified here. If the sysctl option is enabled, a sysctl |
27078 |
++ option with name "socket_client_gid" is created. |
27079 |
++ |
27080 |
++config GRKERNSEC_SOCKET_SERVER |
27081 |
++ bool "Deny server sockets to group" |
27082 |
++ depends on GRKERNSEC_SOCKET |
27083 |
++ help |
27084 |
++ If you say Y here, you will be able to choose a GID of whose users will |
27085 |
++ be unable to run server applications from your machine. If the sysctl |
27086 |
++ option is enabled, a sysctl option with name "socket_server" is created. |
27087 |
++ |
27088 |
++config GRKERNSEC_SOCKET_SERVER_GID |
27089 |
++ int "GID to deny server sockets for" |
27090 |
++ depends on GRKERNSEC_SOCKET_SERVER |
27091 |
++ default 1002 |
27092 |
++ help |
27093 |
++ Here you can choose the GID to disable server socket access for. |
27094 |
++ Remember to add the users you want server socket access disabled for to |
27095 |
++ the GID specified here. If the sysctl option is enabled, a sysctl |
27096 |
++ option with name "socket_server_gid" is created. |
27097 |
++ |
27098 |
++endmenu |
27099 |
++menu "Sysctl support" |
27100 |
++depends on GRKERNSEC && SYSCTL |
27101 |
++ |
27102 |
++config GRKERNSEC_SYSCTL |
27103 |
++ bool "Sysctl support" |
27104 |
++ help |
27105 |
++ If you say Y here, you will be able to change the options that |
27106 |
++ grsecurity runs with at bootup, without having to recompile your |
27107 |
++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity |
27108 |
++ to enable (1) or disable (0) various features. All the sysctl entries |
27109 |
++ are mutable until the "grsec_lock" entry is set to a non-zero value. |
27110 |
++ All features enabled in the kernel configuration are disabled at boot |
27111 |
++ if you do not say Y to the "Turn on features by default" option. |
27112 |
++ All options should be set at startup, and the grsec_lock entry should |
27113 |
++ be set to a non-zero value after all the options are set. |
27114 |
++ *THIS IS EXTREMELY IMPORTANT* |
27115 |
++ |
27116 |
++config GRKERNSEC_SYSCTL_ON |
27117 |
++ bool "Turn on features by default" |
27118 |
++ depends on GRKERNSEC_SYSCTL |
27119 |
++ help |
27120 |
++ If you say Y here, instead of having all features enabled in the |
27121 |
++ kernel configuration disabled at boot time, the features will be |
27122 |
++ enabled at boot time. It is recommended you say Y here unless |
27123 |
++ there is some reason you would want all sysctl-tunable features to |
27124 |
++ be disabled by default. As mentioned elsewhere, it is important |
27125 |
++ to enable the grsec_lock entry once you have finished modifying |
27126 |
++ the sysctl entries. |
27127 |
++ |
27128 |
++endmenu |
27129 |
++menu "Logging Options" |
27130 |
++depends on GRKERNSEC |
27131 |
++ |
27132 |
++config GRKERNSEC_FLOODTIME |
27133 |
++ int "Seconds in between log messages (minimum)" |
27134 |
++ default 10 |
27135 |
++ help |
27136 |
++ This option allows you to enforce the number of seconds between |
27137 |
++ grsecurity log messages. The default should be suitable for most |
27138 |
++ people, however, if you choose to change it, choose a value small enough |
27139 |
++ to allow informative logs to be produced, but large enough to |
27140 |
++ prevent flooding. |
27141 |
++ |
27142 |
++config GRKERNSEC_FLOODBURST |
27143 |
++ int "Number of messages in a burst (maximum)" |
27144 |
++ default 4 |
27145 |
++ help |
27146 |
++ This option allows you to choose the maximum number of messages allowed |
27147 |
++ within the flood time interval you chose in a separate option. The |
27148 |
++ default should be suitable for most people, however if you find that |
27149 |
++ many of your logs are being interpreted as flooding, you may want to |
27150 |
++ raise this value. |
27151 |
++ |
27152 |
++endmenu |
27153 |
++ |
27154 |
++endmenu |
27155 |
+diff -urNp linux-2.6.24.4/grsecurity/Makefile linux-2.6.24.4/grsecurity/Makefile |
27156 |
+--- linux-2.6.24.4/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500 |
27157 |
++++ linux-2.6.24.4/grsecurity/Makefile 2008-03-26 17:56:56.000000000 -0400 |
27158 |
+@@ -0,0 +1,20 @@ |
27159 |
++# grsecurity's ACL system was originally written in 2001 by Michael Dalton |
27160 |
++# during 2001-2005 it has been completely redesigned by Brad Spengler |
27161 |
++# into an RBAC system |
27162 |
++# |
27163 |
++# All code in this directory and various hooks inserted throughout the kernel |
27164 |
++# are copyright Brad Spengler, and released under the GPL v2 or higher |
27165 |
++ |
27166 |
++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \ |
27167 |
++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \ |
27168 |
++ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o |
27169 |
++ |
27170 |
++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \ |
27171 |
++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \ |
27172 |
++ gracl_learn.o grsec_log.o |
27173 |
++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o |
27174 |
++ |
27175 |
++ifndef CONFIG_GRKERNSEC |
27176 |
++obj-y += grsec_disabled.o |
27177 |
++endif |
27178 |
++ |
27179 |
+diff -urNp linux-2.6.24.4/include/acpi/acpiosxf.h linux-2.6.24.4/include/acpi/acpiosxf.h |
27180 |
+--- linux-2.6.24.4/include/acpi/acpiosxf.h 2008-03-24 14:49:18.000000000 -0400 |
27181 |
++++ linux-2.6.24.4/include/acpi/acpiosxf.h 2008-03-26 17:56:56.000000000 -0400 |
27182 |
+@@ -219,7 +219,7 @@ acpi_os_write_memory(acpi_physical_addre |
27183 |
+ */ |
27184 |
+ acpi_status |
27185 |
+ acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, |
27186 |
+- u32 reg, void *value, u32 width); |
27187 |
++ u32 reg, u32 *value, u32 width); |
27188 |
+ |
27189 |
+ acpi_status |
27190 |
+ acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, |
27191 |
+diff -urNp linux-2.6.24.4/include/asm-alpha/a.out.h linux-2.6.24.4/include/asm-alpha/a.out.h |
27192 |
+--- linux-2.6.24.4/include/asm-alpha/a.out.h 2008-03-24 14:49:18.000000000 -0400 |
27193 |
++++ linux-2.6.24.4/include/asm-alpha/a.out.h 2008-03-26 17:56:56.000000000 -0400 |
27194 |
+@@ -98,7 +98,7 @@ struct exec |
27195 |
+ set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \ |
27196 |
+ ? ADDR_LIMIT_32BIT : 0) | PER_OSF4)) |
27197 |
+ |
27198 |
+-#define STACK_TOP \ |
27199 |
++#define __STACK_TOP \ |
27200 |
+ (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL) |
27201 |
+ |
27202 |
+ #define STACK_TOP_MAX 0x00120000000UL |
27203 |
+diff -urNp linux-2.6.24.4/include/asm-alpha/elf.h linux-2.6.24.4/include/asm-alpha/elf.h |
27204 |
+--- linux-2.6.24.4/include/asm-alpha/elf.h 2008-03-24 14:49:18.000000000 -0400 |
27205 |
++++ linux-2.6.24.4/include/asm-alpha/elf.h 2008-03-26 17:56:56.000000000 -0400 |
27206 |
+@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N |
27207 |
+ |
27208 |
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) |
27209 |
+ |
27210 |
++#ifdef CONFIG_PAX_ASLR |
27211 |
++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL) |
27212 |
++ |
27213 |
++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28) |
27214 |
++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19) |
27215 |
++#endif |
27216 |
++ |
27217 |
+ /* $0 is set by ld.so to a pointer to a function which might be |
27218 |
+ registered using atexit. This provides a mean for the dynamic |
27219 |
+ linker to call DT_FINI functions for shared libraries that have |
27220 |
+diff -urNp linux-2.6.24.4/include/asm-alpha/kmap_types.h linux-2.6.24.4/include/asm-alpha/kmap_types.h |
27221 |
+--- linux-2.6.24.4/include/asm-alpha/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27222 |
++++ linux-2.6.24.4/include/asm-alpha/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27223 |
+@@ -24,7 +24,8 @@ D(9) KM_IRQ0, |
27224 |
+ D(10) KM_IRQ1, |
27225 |
+ D(11) KM_SOFTIRQ0, |
27226 |
+ D(12) KM_SOFTIRQ1, |
27227 |
+-D(13) KM_TYPE_NR |
27228 |
++D(13) KM_CLEARPAGE, |
27229 |
++D(14) KM_TYPE_NR |
27230 |
+ }; |
27231 |
+ |
27232 |
+ #undef D |
27233 |
+diff -urNp linux-2.6.24.4/include/asm-alpha/pgtable.h linux-2.6.24.4/include/asm-alpha/pgtable.h |
27234 |
+--- linux-2.6.24.4/include/asm-alpha/pgtable.h 2008-03-24 14:49:18.000000000 -0400 |
27235 |
++++ linux-2.6.24.4/include/asm-alpha/pgtable.h 2008-03-26 17:56:56.000000000 -0400 |
27236 |
+@@ -101,6 +101,17 @@ struct vm_area_struct; |
27237 |
+ #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS) |
27238 |
+ #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) |
27239 |
+ #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) |
27240 |
++ |
27241 |
++#ifdef CONFIG_PAX_PAGEEXEC |
27242 |
++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE) |
27243 |
++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE) |
27244 |
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE) |
27245 |
++#else |
27246 |
++# define PAGE_SHARED_NOEXEC PAGE_SHARED |
27247 |
++# define PAGE_COPY_NOEXEC PAGE_COPY |
27248 |
++# define PAGE_READONLY_NOEXEC PAGE_READONLY |
27249 |
++#endif |
27250 |
++ |
27251 |
+ #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE) |
27252 |
+ |
27253 |
+ #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x)) |
27254 |
+diff -urNp linux-2.6.24.4/include/asm-arm/a.out.h linux-2.6.24.4/include/asm-arm/a.out.h |
27255 |
+--- linux-2.6.24.4/include/asm-arm/a.out.h 2008-03-24 14:49:18.000000000 -0400 |
27256 |
++++ linux-2.6.24.4/include/asm-arm/a.out.h 2008-03-26 17:56:56.000000000 -0400 |
27257 |
+@@ -28,7 +28,7 @@ struct exec |
27258 |
+ #define M_ARM 103 |
27259 |
+ |
27260 |
+ #ifdef __KERNEL__ |
27261 |
+-#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \ |
27262 |
++#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \ |
27263 |
+ TASK_SIZE : TASK_SIZE_26) |
27264 |
+ #define STACK_TOP_MAX TASK_SIZE |
27265 |
+ #endif |
27266 |
+diff -urNp linux-2.6.24.4/include/asm-arm/elf.h linux-2.6.24.4/include/asm-arm/elf.h |
27267 |
+--- linux-2.6.24.4/include/asm-arm/elf.h 2008-03-24 14:49:18.000000000 -0400 |
27268 |
++++ linux-2.6.24.4/include/asm-arm/elf.h 2008-03-26 17:56:56.000000000 -0400 |
27269 |
+@@ -88,7 +88,14 @@ extern char elf_platform[]; |
27270 |
+ the loader. We need to make sure that it is out of the way of the program |
27271 |
+ that it will "exec", and that there is sufficient room for the brk. */ |
27272 |
+ |
27273 |
+-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) |
27274 |
++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) |
27275 |
++ |
27276 |
++#ifdef CONFIG_PAX_ASLR |
27277 |
++#define PAX_ELF_ET_DYN_BASE 0x00008000UL |
27278 |
++ |
27279 |
++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10) |
27280 |
++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10) |
27281 |
++#endif |
27282 |
+ |
27283 |
+ /* When the program starts, a1 contains a pointer to a function to be |
27284 |
+ registered with atexit, as per the SVR4 ABI. A value of 0 means we |
27285 |
+diff -urNp linux-2.6.24.4/include/asm-arm/kmap_types.h linux-2.6.24.4/include/asm-arm/kmap_types.h |
27286 |
+--- linux-2.6.24.4/include/asm-arm/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27287 |
++++ linux-2.6.24.4/include/asm-arm/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27288 |
+@@ -18,6 +18,7 @@ enum km_type { |
27289 |
+ KM_IRQ1, |
27290 |
+ KM_SOFTIRQ0, |
27291 |
+ KM_SOFTIRQ1, |
27292 |
++ KM_CLEARPAGE, |
27293 |
+ KM_TYPE_NR |
27294 |
+ }; |
27295 |
+ |
27296 |
+diff -urNp linux-2.6.24.4/include/asm-avr32/a.out.h linux-2.6.24.4/include/asm-avr32/a.out.h |
27297 |
+--- linux-2.6.24.4/include/asm-avr32/a.out.h 2008-03-24 14:49:18.000000000 -0400 |
27298 |
++++ linux-2.6.24.4/include/asm-avr32/a.out.h 2008-03-26 17:56:56.000000000 -0400 |
27299 |
+@@ -19,8 +19,8 @@ struct exec |
27300 |
+ |
27301 |
+ #ifdef __KERNEL__ |
27302 |
+ |
27303 |
+-#define STACK_TOP TASK_SIZE |
27304 |
+-#define STACK_TOP_MAX STACK_TOP |
27305 |
++#define __STACK_TOP TASK_SIZE |
27306 |
++#define STACK_TOP_MAX __STACK_TOP |
27307 |
+ |
27308 |
+ #endif |
27309 |
+ |
27310 |
+diff -urNp linux-2.6.24.4/include/asm-avr32/elf.h linux-2.6.24.4/include/asm-avr32/elf.h |
27311 |
+--- linux-2.6.24.4/include/asm-avr32/elf.h 2008-03-24 14:49:18.000000000 -0400 |
27312 |
++++ linux-2.6.24.4/include/asm-avr32/elf.h 2008-03-26 17:56:56.000000000 -0400 |
27313 |
+@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg |
27314 |
+ the loader. We need to make sure that it is out of the way of the program |
27315 |
+ that it will "exec", and that there is sufficient room for the brk. */ |
27316 |
+ |
27317 |
+-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) |
27318 |
++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) |
27319 |
+ |
27320 |
++#ifdef CONFIG_PAX_ASLR |
27321 |
++#define PAX_ELF_ET_DYN_BASE 0x00001000UL |
27322 |
++ |
27323 |
++#define PAX_DELTA_MMAP_LEN 15 |
27324 |
++#define PAX_DELTA_STACK_LEN 15 |
27325 |
++#endif |
27326 |
+ |
27327 |
+ /* This yields a mask that user programs can use to figure out what |
27328 |
+ instruction set this CPU supports. This could be done in user space, |
27329 |
+diff -urNp linux-2.6.24.4/include/asm-avr32/kmap_types.h linux-2.6.24.4/include/asm-avr32/kmap_types.h |
27330 |
+--- linux-2.6.24.4/include/asm-avr32/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27331 |
++++ linux-2.6.24.4/include/asm-avr32/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27332 |
+@@ -22,7 +22,8 @@ D(10) KM_IRQ0, |
27333 |
+ D(11) KM_IRQ1, |
27334 |
+ D(12) KM_SOFTIRQ0, |
27335 |
+ D(13) KM_SOFTIRQ1, |
27336 |
+-D(14) KM_TYPE_NR |
27337 |
++D(14) KM_CLEARPAGE, |
27338 |
++D(15) KM_TYPE_NR |
27339 |
+ }; |
27340 |
+ |
27341 |
+ #undef D |
27342 |
+diff -urNp linux-2.6.24.4/include/asm-blackfin/kmap_types.h linux-2.6.24.4/include/asm-blackfin/kmap_types.h |
27343 |
+--- linux-2.6.24.4/include/asm-blackfin/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27344 |
++++ linux-2.6.24.4/include/asm-blackfin/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27345 |
+@@ -15,6 +15,7 @@ enum km_type { |
27346 |
+ KM_IRQ1, |
27347 |
+ KM_SOFTIRQ0, |
27348 |
+ KM_SOFTIRQ1, |
27349 |
++ KM_CLEARPAGE, |
27350 |
+ KM_TYPE_NR |
27351 |
+ }; |
27352 |
+ |
27353 |
+diff -urNp linux-2.6.24.4/include/asm-cris/kmap_types.h linux-2.6.24.4/include/asm-cris/kmap_types.h |
27354 |
+--- linux-2.6.24.4/include/asm-cris/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27355 |
++++ linux-2.6.24.4/include/asm-cris/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27356 |
+@@ -19,6 +19,7 @@ enum km_type { |
27357 |
+ KM_IRQ1, |
27358 |
+ KM_SOFTIRQ0, |
27359 |
+ KM_SOFTIRQ1, |
27360 |
++ KM_CLEARPAGE, |
27361 |
+ KM_TYPE_NR |
27362 |
+ }; |
27363 |
+ |
27364 |
+diff -urNp linux-2.6.24.4/include/asm-frv/kmap_types.h linux-2.6.24.4/include/asm-frv/kmap_types.h |
27365 |
+--- linux-2.6.24.4/include/asm-frv/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27366 |
++++ linux-2.6.24.4/include/asm-frv/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27367 |
+@@ -23,6 +23,7 @@ enum km_type { |
27368 |
+ KM_IRQ1, |
27369 |
+ KM_SOFTIRQ0, |
27370 |
+ KM_SOFTIRQ1, |
27371 |
++ KM_CLEARPAGE, |
27372 |
+ KM_TYPE_NR |
27373 |
+ }; |
27374 |
+ |
27375 |
+diff -urNp linux-2.6.24.4/include/asm-generic/futex.h linux-2.6.24.4/include/asm-generic/futex.h |
27376 |
+--- linux-2.6.24.4/include/asm-generic/futex.h 2008-03-24 14:49:18.000000000 -0400 |
27377 |
++++ linux-2.6.24.4/include/asm-generic/futex.h 2008-03-26 17:56:56.000000000 -0400 |
27378 |
+@@ -8,7 +8,7 @@ |
27379 |
+ #include <asm/uaccess.h> |
27380 |
+ |
27381 |
+ static inline int |
27382 |
+-futex_atomic_op_inuser (int encoded_op, int __user *uaddr) |
27383 |
++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
27384 |
+ { |
27385 |
+ int op = (encoded_op >> 28) & 7; |
27386 |
+ int cmp = (encoded_op >> 24) & 15; |
27387 |
+@@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op, |
27388 |
+ } |
27389 |
+ |
27390 |
+ static inline int |
27391 |
+-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) |
27392 |
++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval) |
27393 |
+ { |
27394 |
+ return -ENOSYS; |
27395 |
+ } |
27396 |
+diff -urNp linux-2.6.24.4/include/asm-generic/vmlinux.lds.h linux-2.6.24.4/include/asm-generic/vmlinux.lds.h |
27397 |
+--- linux-2.6.24.4/include/asm-generic/vmlinux.lds.h 2008-03-24 14:49:18.000000000 -0400 |
27398 |
++++ linux-2.6.24.4/include/asm-generic/vmlinux.lds.h 2008-03-26 17:56:56.000000000 -0400 |
27399 |
+@@ -23,6 +23,7 @@ |
27400 |
+ .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ |
27401 |
+ VMLINUX_SYMBOL(__start_rodata) = .; \ |
27402 |
+ *(.rodata) *(.rodata.*) \ |
27403 |
++ *(.data.read_only) \ |
27404 |
+ *(__vermagic) /* Kernel version magic */ \ |
27405 |
+ *(__markers_strings) /* Markers: strings */ \ |
27406 |
+ } \ |
27407 |
+diff -urNp linux-2.6.24.4/include/asm-h8300/kmap_types.h linux-2.6.24.4/include/asm-h8300/kmap_types.h |
27408 |
+--- linux-2.6.24.4/include/asm-h8300/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27409 |
++++ linux-2.6.24.4/include/asm-h8300/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27410 |
+@@ -15,6 +15,7 @@ enum km_type { |
27411 |
+ KM_IRQ1, |
27412 |
+ KM_SOFTIRQ0, |
27413 |
+ KM_SOFTIRQ1, |
27414 |
++ KM_CLEARPAGE, |
27415 |
+ KM_TYPE_NR |
27416 |
+ }; |
27417 |
+ |
27418 |
+diff -urNp linux-2.6.24.4/include/asm-ia64/elf.h linux-2.6.24.4/include/asm-ia64/elf.h |
27419 |
+--- linux-2.6.24.4/include/asm-ia64/elf.h 2008-03-24 14:49:18.000000000 -0400 |
27420 |
++++ linux-2.6.24.4/include/asm-ia64/elf.h 2008-03-26 17:56:56.000000000 -0400 |
27421 |
+@@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR |
27422 |
+ typedef struct ia64_fpreg elf_fpreg_t; |
27423 |
+ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; |
27424 |
+ |
27425 |
++#ifdef CONFIG_PAX_ASLR |
27426 |
++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL) |
27427 |
+ |
27428 |
++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) |
27429 |
++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) |
27430 |
++#endif |
27431 |
+ |
27432 |
+ struct pt_regs; /* forward declaration... */ |
27433 |
+ extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst); |
27434 |
+diff -urNp linux-2.6.24.4/include/asm-ia64/kmap_types.h linux-2.6.24.4/include/asm-ia64/kmap_types.h |
27435 |
+--- linux-2.6.24.4/include/asm-ia64/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27436 |
++++ linux-2.6.24.4/include/asm-ia64/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27437 |
+@@ -22,7 +22,8 @@ D(9) KM_IRQ0, |
27438 |
+ D(10) KM_IRQ1, |
27439 |
+ D(11) KM_SOFTIRQ0, |
27440 |
+ D(12) KM_SOFTIRQ1, |
27441 |
+-D(13) KM_TYPE_NR |
27442 |
++D(13) KM_CLEARPAGE, |
27443 |
++D(14) KM_TYPE_NR |
27444 |
+ }; |
27445 |
+ |
27446 |
+ #undef D |
27447 |
+diff -urNp linux-2.6.24.4/include/asm-ia64/pgtable.h linux-2.6.24.4/include/asm-ia64/pgtable.h |
27448 |
+--- linux-2.6.24.4/include/asm-ia64/pgtable.h 2008-03-24 14:49:18.000000000 -0400 |
27449 |
++++ linux-2.6.24.4/include/asm-ia64/pgtable.h 2008-03-26 17:56:56.000000000 -0400 |
27450 |
+@@ -143,6 +143,17 @@ |
27451 |
+ #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) |
27452 |
+ #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) |
27453 |
+ #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX) |
27454 |
++ |
27455 |
++#ifdef CONFIG_PAX_PAGEEXEC |
27456 |
++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW) |
27457 |
++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) |
27458 |
++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) |
27459 |
++#else |
27460 |
++# define PAGE_SHARED_NOEXEC PAGE_SHARED |
27461 |
++# define PAGE_READONLY_NOEXEC PAGE_READONLY |
27462 |
++# define PAGE_COPY_NOEXEC PAGE_COPY |
27463 |
++#endif |
27464 |
++ |
27465 |
+ #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX) |
27466 |
+ #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX) |
27467 |
+ #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX) |
27468 |
+diff -urNp linux-2.6.24.4/include/asm-ia64/processor.h linux-2.6.24.4/include/asm-ia64/processor.h |
27469 |
+--- linux-2.6.24.4/include/asm-ia64/processor.h 2008-03-24 14:49:18.000000000 -0400 |
27470 |
++++ linux-2.6.24.4/include/asm-ia64/processor.h 2008-03-26 17:56:56.000000000 -0400 |
27471 |
+@@ -275,7 +275,7 @@ struct thread_struct { |
27472 |
+ .on_ustack = 0, \ |
27473 |
+ .ksp = 0, \ |
27474 |
+ .map_base = DEFAULT_MAP_BASE, \ |
27475 |
+- .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \ |
27476 |
++ .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \ |
27477 |
+ .task_size = DEFAULT_TASK_SIZE, \ |
27478 |
+ .last_fph_cpu = -1, \ |
27479 |
+ INIT_THREAD_IA32 \ |
27480 |
+diff -urNp linux-2.6.24.4/include/asm-ia64/ustack.h linux-2.6.24.4/include/asm-ia64/ustack.h |
27481 |
+--- linux-2.6.24.4/include/asm-ia64/ustack.h 2008-03-24 14:49:18.000000000 -0400 |
27482 |
++++ linux-2.6.24.4/include/asm-ia64/ustack.h 2008-03-26 17:56:56.000000000 -0400 |
27483 |
+@@ -10,8 +10,8 @@ |
27484 |
+ |
27485 |
+ /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */ |
27486 |
+ #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2) |
27487 |
+-#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT) |
27488 |
+-#define STACK_TOP_MAX STACK_TOP |
27489 |
++#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT) |
27490 |
++#define STACK_TOP_MAX __STACK_TOP |
27491 |
+ #endif |
27492 |
+ |
27493 |
+ /* Make a default stack size of 2GiB */ |
27494 |
+diff -urNp linux-2.6.24.4/include/asm-m32r/kmap_types.h linux-2.6.24.4/include/asm-m32r/kmap_types.h |
27495 |
+--- linux-2.6.24.4/include/asm-m32r/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27496 |
++++ linux-2.6.24.4/include/asm-m32r/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27497 |
+@@ -21,7 +21,8 @@ D(9) KM_IRQ0, |
27498 |
+ D(10) KM_IRQ1, |
27499 |
+ D(11) KM_SOFTIRQ0, |
27500 |
+ D(12) KM_SOFTIRQ1, |
27501 |
+-D(13) KM_TYPE_NR |
27502 |
++D(13) KM_CLEARPAGE, |
27503 |
++D(14) KM_TYPE_NR |
27504 |
+ }; |
27505 |
+ |
27506 |
+ #undef D |
27507 |
+diff -urNp linux-2.6.24.4/include/asm-m68k/kmap_types.h linux-2.6.24.4/include/asm-m68k/kmap_types.h |
27508 |
+--- linux-2.6.24.4/include/asm-m68k/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27509 |
++++ linux-2.6.24.4/include/asm-m68k/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27510 |
+@@ -15,6 +15,7 @@ enum km_type { |
27511 |
+ KM_IRQ1, |
27512 |
+ KM_SOFTIRQ0, |
27513 |
+ KM_SOFTIRQ1, |
27514 |
++ KM_CLEARPAGE, |
27515 |
+ KM_TYPE_NR |
27516 |
+ }; |
27517 |
+ |
27518 |
+diff -urNp linux-2.6.24.4/include/asm-m68knommu/kmap_types.h linux-2.6.24.4/include/asm-m68knommu/kmap_types.h |
27519 |
+--- linux-2.6.24.4/include/asm-m68knommu/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27520 |
++++ linux-2.6.24.4/include/asm-m68knommu/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27521 |
+@@ -15,6 +15,7 @@ enum km_type { |
27522 |
+ KM_IRQ1, |
27523 |
+ KM_SOFTIRQ0, |
27524 |
+ KM_SOFTIRQ1, |
27525 |
++ KM_CLEARPAGE, |
27526 |
+ KM_TYPE_NR |
27527 |
+ }; |
27528 |
+ |
27529 |
+diff -urNp linux-2.6.24.4/include/asm-mips/a.out.h linux-2.6.24.4/include/asm-mips/a.out.h |
27530 |
+--- linux-2.6.24.4/include/asm-mips/a.out.h 2008-03-24 14:49:18.000000000 -0400 |
27531 |
++++ linux-2.6.24.4/include/asm-mips/a.out.h 2008-03-26 17:56:56.000000000 -0400 |
27532 |
+@@ -35,10 +35,10 @@ struct exec |
27533 |
+ #ifdef __KERNEL__ |
27534 |
+ |
27535 |
+ #ifdef CONFIG_32BIT |
27536 |
+-#define STACK_TOP TASK_SIZE |
27537 |
++#define __STACK_TOP TASK_SIZE |
27538 |
+ #endif |
27539 |
+ #ifdef CONFIG_64BIT |
27540 |
+-#define STACK_TOP \ |
27541 |
++#define __STACK_TOP \ |
27542 |
+ (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE) |
27543 |
+ #endif |
27544 |
+ #define STACK_TOP_MAX TASK_SIZE |
27545 |
+diff -urNp linux-2.6.24.4/include/asm-mips/elf.h linux-2.6.24.4/include/asm-mips/elf.h |
27546 |
+--- linux-2.6.24.4/include/asm-mips/elf.h 2008-03-24 14:49:18.000000000 -0400 |
27547 |
++++ linux-2.6.24.4/include/asm-mips/elf.h 2008-03-26 17:56:56.000000000 -0400 |
27548 |
+@@ -372,4 +372,11 @@ extern int dump_task_fpu(struct task_str |
27549 |
+ #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) |
27550 |
+ #endif |
27551 |
+ |
27552 |
++#ifdef CONFIG_PAX_ASLR |
27553 |
++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) |
27554 |
++ |
27555 |
++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
27556 |
++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
27557 |
++#endif |
27558 |
++ |
27559 |
+ #endif /* _ASM_ELF_H */ |
27560 |
+diff -urNp linux-2.6.24.4/include/asm-mips/kmap_types.h linux-2.6.24.4/include/asm-mips/kmap_types.h |
27561 |
+--- linux-2.6.24.4/include/asm-mips/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27562 |
++++ linux-2.6.24.4/include/asm-mips/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27563 |
+@@ -22,7 +22,8 @@ D(9) KM_IRQ0, |
27564 |
+ D(10) KM_IRQ1, |
27565 |
+ D(11) KM_SOFTIRQ0, |
27566 |
+ D(12) KM_SOFTIRQ1, |
27567 |
+-D(13) KM_TYPE_NR |
27568 |
++D(13) KM_CLEARPAGE, |
27569 |
++D(14) KM_TYPE_NR |
27570 |
+ }; |
27571 |
+ |
27572 |
+ #undef D |
27573 |
+diff -urNp linux-2.6.24.4/include/asm-mips/page.h linux-2.6.24.4/include/asm-mips/page.h |
27574 |
+--- linux-2.6.24.4/include/asm-mips/page.h 2008-03-24 14:49:18.000000000 -0400 |
27575 |
++++ linux-2.6.24.4/include/asm-mips/page.h 2008-03-26 17:56:56.000000000 -0400 |
27576 |
+@@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa |
27577 |
+ #ifdef CONFIG_CPU_MIPS32 |
27578 |
+ typedef struct { unsigned long pte_low, pte_high; } pte_t; |
27579 |
+ #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) |
27580 |
+- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; }) |
27581 |
++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; }) |
27582 |
+ #else |
27583 |
+ typedef struct { unsigned long long pte; } pte_t; |
27584 |
+ #define pte_val(x) ((x).pte) |
27585 |
+diff -urNp linux-2.6.24.4/include/asm-mips/system.h linux-2.6.24.4/include/asm-mips/system.h |
27586 |
+--- linux-2.6.24.4/include/asm-mips/system.h 2008-03-24 14:49:18.000000000 -0400 |
27587 |
++++ linux-2.6.24.4/include/asm-mips/system.h 2008-03-26 17:56:56.000000000 -0400 |
27588 |
+@@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void); |
27589 |
+ */ |
27590 |
+ #define __ARCH_WANT_UNLOCKED_CTXSW |
27591 |
+ |
27592 |
+-extern unsigned long arch_align_stack(unsigned long sp); |
27593 |
++#define arch_align_stack(x) (x) |
27594 |
+ |
27595 |
+ #endif /* _ASM_SYSTEM_H */ |
27596 |
+diff -urNp linux-2.6.24.4/include/asm-parisc/a.out.h linux-2.6.24.4/include/asm-parisc/a.out.h |
27597 |
+--- linux-2.6.24.4/include/asm-parisc/a.out.h 2008-03-24 14:49:18.000000000 -0400 |
27598 |
++++ linux-2.6.24.4/include/asm-parisc/a.out.h 2008-03-26 17:56:56.000000000 -0400 |
27599 |
+@@ -22,7 +22,7 @@ struct exec |
27600 |
+ /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc. |
27601 |
+ * prumpf */ |
27602 |
+ |
27603 |
+-#define STACK_TOP TASK_SIZE |
27604 |
++#define __STACK_TOP TASK_SIZE |
27605 |
+ #define STACK_TOP_MAX DEFAULT_TASK_SIZE |
27606 |
+ |
27607 |
+ #endif |
27608 |
+diff -urNp linux-2.6.24.4/include/asm-parisc/elf.h linux-2.6.24.4/include/asm-parisc/elf.h |
27609 |
+--- linux-2.6.24.4/include/asm-parisc/elf.h 2008-03-24 14:49:18.000000000 -0400 |
27610 |
++++ linux-2.6.24.4/include/asm-parisc/elf.h 2008-03-26 17:56:56.000000000 -0400 |
27611 |
+@@ -337,6 +337,13 @@ struct pt_regs; /* forward declaration.. |
27612 |
+ |
27613 |
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000) |
27614 |
+ |
27615 |
++#ifdef CONFIG_PAX_ASLR |
27616 |
++#define PAX_ELF_ET_DYN_BASE 0x10000UL |
27617 |
++ |
27618 |
++#define PAX_DELTA_MMAP_LEN 16 |
27619 |
++#define PAX_DELTA_STACK_LEN 16 |
27620 |
++#endif |
27621 |
++ |
27622 |
+ /* This yields a mask that user programs can use to figure out what |
27623 |
+ instruction set this CPU supports. This could be done in user space, |
27624 |
+ but it's not easy, and we've already done it here. */ |
27625 |
+diff -urNp linux-2.6.24.4/include/asm-parisc/kmap_types.h linux-2.6.24.4/include/asm-parisc/kmap_types.h |
27626 |
+--- linux-2.6.24.4/include/asm-parisc/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27627 |
++++ linux-2.6.24.4/include/asm-parisc/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27628 |
+@@ -22,7 +22,8 @@ D(9) KM_IRQ0, |
27629 |
+ D(10) KM_IRQ1, |
27630 |
+ D(11) KM_SOFTIRQ0, |
27631 |
+ D(12) KM_SOFTIRQ1, |
27632 |
+-D(13) KM_TYPE_NR |
27633 |
++D(13) KM_CLEARPAGE, |
27634 |
++D(14) KM_TYPE_NR |
27635 |
+ }; |
27636 |
+ |
27637 |
+ #undef D |
27638 |
+diff -urNp linux-2.6.24.4/include/asm-parisc/pgtable.h linux-2.6.24.4/include/asm-parisc/pgtable.h |
27639 |
+--- linux-2.6.24.4/include/asm-parisc/pgtable.h 2008-03-24 14:49:18.000000000 -0400 |
27640 |
++++ linux-2.6.24.4/include/asm-parisc/pgtable.h 2008-03-26 17:56:56.000000000 -0400 |
27641 |
+@@ -210,6 +210,17 @@ extern void *vmalloc_start; |
27642 |
+ #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED) |
27643 |
+ #define PAGE_COPY PAGE_EXECREAD |
27644 |
+ #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) |
27645 |
++ |
27646 |
++#ifdef CONFIG_PAX_PAGEEXEC |
27647 |
++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED) |
27648 |
++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED) |
27649 |
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED) |
27650 |
++#else |
27651 |
++# define PAGE_SHARED_NOEXEC PAGE_SHARED |
27652 |
++# define PAGE_COPY_NOEXEC PAGE_COPY |
27653 |
++# define PAGE_READONLY_NOEXEC PAGE_READONLY |
27654 |
++#endif |
27655 |
++ |
27656 |
+ #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) |
27657 |
+ #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) |
27658 |
+ #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) |
27659 |
+diff -urNp linux-2.6.24.4/include/asm-powerpc/a.out.h linux-2.6.24.4/include/asm-powerpc/a.out.h |
27660 |
+--- linux-2.6.24.4/include/asm-powerpc/a.out.h 2008-03-24 14:49:18.000000000 -0400 |
27661 |
++++ linux-2.6.24.4/include/asm-powerpc/a.out.h 2008-03-26 17:56:56.000000000 -0400 |
27662 |
+@@ -23,15 +23,15 @@ struct exec |
27663 |
+ #define STACK_TOP_USER64 TASK_SIZE_USER64 |
27664 |
+ #define STACK_TOP_USER32 TASK_SIZE_USER32 |
27665 |
+ |
27666 |
+-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ |
27667 |
++#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \ |
27668 |
+ STACK_TOP_USER32 : STACK_TOP_USER64) |
27669 |
+ |
27670 |
+ #define STACK_TOP_MAX STACK_TOP_USER64 |
27671 |
+ |
27672 |
+ #else /* __powerpc64__ */ |
27673 |
+ |
27674 |
+-#define STACK_TOP TASK_SIZE |
27675 |
+-#define STACK_TOP_MAX STACK_TOP |
27676 |
++#define __STACK_TOP TASK_SIZE |
27677 |
++#define STACK_TOP_MAX __STACK_TOP |
27678 |
+ |
27679 |
+ #endif /* __powerpc64__ */ |
27680 |
+ #endif /* __KERNEL__ */ |
27681 |
+diff -urNp linux-2.6.24.4/include/asm-powerpc/elf.h linux-2.6.24.4/include/asm-powerpc/elf.h |
27682 |
+--- linux-2.6.24.4/include/asm-powerpc/elf.h 2008-03-24 14:49:18.000000000 -0400 |
27683 |
++++ linux-2.6.24.4/include/asm-powerpc/elf.h 2008-03-26 17:56:56.000000000 -0400 |
27684 |
+@@ -160,6 +160,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N |
27685 |
+ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32]; |
27686 |
+ #endif |
27687 |
+ |
27688 |
++#ifdef CONFIG_PAX_ASLR |
27689 |
++#define PAX_ELF_ET_DYN_BASE (0x10000000UL) |
27690 |
++ |
27691 |
++#ifdef __powerpc64__ |
27692 |
++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28) |
27693 |
++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28) |
27694 |
++#else |
27695 |
++#define PAX_DELTA_MMAP_LEN 15 |
27696 |
++#define PAX_DELTA_STACK_LEN 15 |
27697 |
++#endif |
27698 |
++#endif |
27699 |
++ |
27700 |
+ #ifdef __KERNEL__ |
27701 |
+ /* |
27702 |
+ * This is used to ensure we don't load something for the wrong architecture. |
27703 |
+diff -urNp linux-2.6.24.4/include/asm-powerpc/kmap_types.h linux-2.6.24.4/include/asm-powerpc/kmap_types.h |
27704 |
+--- linux-2.6.24.4/include/asm-powerpc/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27705 |
++++ linux-2.6.24.4/include/asm-powerpc/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27706 |
+@@ -26,6 +26,7 @@ enum km_type { |
27707 |
+ KM_SOFTIRQ1, |
27708 |
+ KM_PPC_SYNC_PAGE, |
27709 |
+ KM_PPC_SYNC_ICACHE, |
27710 |
++ KM_CLEARPAGE, |
27711 |
+ KM_TYPE_NR |
27712 |
+ }; |
27713 |
+ |
27714 |
+diff -urNp linux-2.6.24.4/include/asm-powerpc/page_64.h linux-2.6.24.4/include/asm-powerpc/page_64.h |
27715 |
+--- linux-2.6.24.4/include/asm-powerpc/page_64.h 2008-03-24 14:49:18.000000000 -0400 |
27716 |
++++ linux-2.6.24.4/include/asm-powerpc/page_64.h 2008-03-26 17:56:56.000000000 -0400 |
27717 |
+@@ -171,15 +171,18 @@ do { \ |
27718 |
+ * stack by default, so in the absense of a PT_GNU_STACK program header |
27719 |
+ * we turn execute permission off. |
27720 |
+ */ |
27721 |
+-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ |
27722 |
+- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
27723 |
++#define VM_STACK_DEFAULT_FLAGS32 \ |
27724 |
++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ |
27725 |
++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
27726 |
+ |
27727 |
+ #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ |
27728 |
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
27729 |
+ |
27730 |
++#ifndef CONFIG_PAX_PAGEEXEC |
27731 |
+ #define VM_STACK_DEFAULT_FLAGS \ |
27732 |
+ (test_thread_flag(TIF_32BIT) ? \ |
27733 |
+ VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64) |
27734 |
++#endif |
27735 |
+ |
27736 |
+ #include <asm-generic/page.h> |
27737 |
+ |
27738 |
+diff -urNp linux-2.6.24.4/include/asm-powerpc/page.h linux-2.6.24.4/include/asm-powerpc/page.h |
27739 |
+--- linux-2.6.24.4/include/asm-powerpc/page.h 2008-03-24 14:49:18.000000000 -0400 |
27740 |
++++ linux-2.6.24.4/include/asm-powerpc/page.h 2008-03-26 17:56:56.000000000 -0400 |
27741 |
+@@ -71,8 +71,9 @@ |
27742 |
+ * and needs to be executable. This means the whole heap ends |
27743 |
+ * up being executable. |
27744 |
+ */ |
27745 |
+-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ |
27746 |
+- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
27747 |
++#define VM_DATA_DEFAULT_FLAGS32 \ |
27748 |
++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ |
27749 |
++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
27750 |
+ |
27751 |
+ #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ |
27752 |
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
27753 |
+diff -urNp linux-2.6.24.4/include/asm-ppc/mmu_context.h linux-2.6.24.4/include/asm-ppc/mmu_context.h |
27754 |
+--- linux-2.6.24.4/include/asm-ppc/mmu_context.h 2008-03-24 14:49:18.000000000 -0400 |
27755 |
++++ linux-2.6.24.4/include/asm-ppc/mmu_context.h 2008-03-26 17:56:56.000000000 -0400 |
27756 |
+@@ -146,7 +146,8 @@ static inline void get_mmu_context(struc |
27757 |
+ static inline int init_new_context(struct task_struct *t, struct mm_struct *mm) |
27758 |
+ { |
27759 |
+ mm->context.id = NO_CONTEXT; |
27760 |
+- mm->context.vdso_base = 0; |
27761 |
++ if (t == current) |
27762 |
++ mm->context.vdso_base = ~0UL; |
27763 |
+ return 0; |
27764 |
+ } |
27765 |
+ |
27766 |
+diff -urNp linux-2.6.24.4/include/asm-ppc/pgtable.h linux-2.6.24.4/include/asm-ppc/pgtable.h |
27767 |
+--- linux-2.6.24.4/include/asm-ppc/pgtable.h 2008-03-24 14:49:18.000000000 -0400 |
27768 |
++++ linux-2.6.24.4/include/asm-ppc/pgtable.h 2008-03-26 17:56:56.000000000 -0400 |
27769 |
+@@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema |
27770 |
+ |
27771 |
+ #define PAGE_NONE __pgprot(_PAGE_BASE) |
27772 |
+ #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER) |
27773 |
+-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) |
27774 |
++#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC) |
27775 |
+ #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) |
27776 |
+-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC) |
27777 |
++#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC) |
27778 |
+ #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER) |
27779 |
+-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) |
27780 |
++#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC) |
27781 |
++ |
27782 |
++#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x) |
27783 |
++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED) |
27784 |
++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED) |
27785 |
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED) |
27786 |
++#else |
27787 |
++# define PAGE_SHARED_NOEXEC PAGE_SHARED |
27788 |
++# define PAGE_COPY_NOEXEC PAGE_COPY |
27789 |
++# define PAGE_READONLY_NOEXEC PAGE_READONLY |
27790 |
++#endif |
27791 |
+ |
27792 |
+ #define PAGE_KERNEL __pgprot(_PAGE_RAM) |
27793 |
+ #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO) |
27794 |
+@@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema |
27795 |
+ * This is the closest we can get.. |
27796 |
+ */ |
27797 |
+ #define __P000 PAGE_NONE |
27798 |
+-#define __P001 PAGE_READONLY_X |
27799 |
+-#define __P010 PAGE_COPY |
27800 |
+-#define __P011 PAGE_COPY_X |
27801 |
+-#define __P100 PAGE_READONLY |
27802 |
++#define __P001 PAGE_READONLY_NOEXEC |
27803 |
++#define __P010 PAGE_COPY_NOEXEC |
27804 |
++#define __P011 PAGE_COPY_NOEXEC |
27805 |
++#define __P100 PAGE_READONLY_X |
27806 |
+ #define __P101 PAGE_READONLY_X |
27807 |
+-#define __P110 PAGE_COPY |
27808 |
++#define __P110 PAGE_COPY_X |
27809 |
+ #define __P111 PAGE_COPY_X |
27810 |
+ |
27811 |
+ #define __S000 PAGE_NONE |
27812 |
+-#define __S001 PAGE_READONLY_X |
27813 |
+-#define __S010 PAGE_SHARED |
27814 |
+-#define __S011 PAGE_SHARED_X |
27815 |
+-#define __S100 PAGE_READONLY |
27816 |
++#define __S001 PAGE_READONLY_NOEXEC |
27817 |
++#define __S010 PAGE_SHARED_NOEXEC |
27818 |
++#define __S011 PAGE_SHARED_NOEXEC |
27819 |
++#define __S100 PAGE_READONLY_X |
27820 |
+ #define __S101 PAGE_READONLY_X |
27821 |
+-#define __S110 PAGE_SHARED |
27822 |
++#define __S110 PAGE_SHARED_X |
27823 |
+ #define __S111 PAGE_SHARED_X |
27824 |
+ |
27825 |
+ #ifndef __ASSEMBLY__ |
27826 |
+diff -urNp linux-2.6.24.4/include/asm-s390/kmap_types.h linux-2.6.24.4/include/asm-s390/kmap_types.h |
27827 |
+--- linux-2.6.24.4/include/asm-s390/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27828 |
++++ linux-2.6.24.4/include/asm-s390/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27829 |
+@@ -16,6 +16,7 @@ enum km_type { |
27830 |
+ KM_IRQ1, |
27831 |
+ KM_SOFTIRQ0, |
27832 |
+ KM_SOFTIRQ1, |
27833 |
++ KM_CLEARPAGE, |
27834 |
+ KM_TYPE_NR |
27835 |
+ }; |
27836 |
+ |
27837 |
+diff -urNp linux-2.6.24.4/include/asm-sh/kmap_types.h linux-2.6.24.4/include/asm-sh/kmap_types.h |
27838 |
+--- linux-2.6.24.4/include/asm-sh/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27839 |
++++ linux-2.6.24.4/include/asm-sh/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27840 |
+@@ -24,7 +24,8 @@ D(9) KM_IRQ0, |
27841 |
+ D(10) KM_IRQ1, |
27842 |
+ D(11) KM_SOFTIRQ0, |
27843 |
+ D(12) KM_SOFTIRQ1, |
27844 |
+-D(13) KM_TYPE_NR |
27845 |
++D(13) KM_CLEARPAGE, |
27846 |
++D(14) KM_TYPE_NR |
27847 |
+ }; |
27848 |
+ |
27849 |
+ #undef D |
27850 |
+diff -urNp linux-2.6.24.4/include/asm-sparc/a.out.h linux-2.6.24.4/include/asm-sparc/a.out.h |
27851 |
+--- linux-2.6.24.4/include/asm-sparc/a.out.h 2008-03-24 14:49:18.000000000 -0400 |
27852 |
++++ linux-2.6.24.4/include/asm-sparc/a.out.h 2008-03-26 17:56:56.000000000 -0400 |
27853 |
+@@ -91,8 +91,8 @@ struct relocation_info /* used when head |
27854 |
+ |
27855 |
+ #include <asm/page.h> |
27856 |
+ |
27857 |
+-#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE) |
27858 |
+-#define STACK_TOP_MAX STACK_TOP |
27859 |
++#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE) |
27860 |
++#define STACK_TOP_MAX __STACK_TOP |
27861 |
+ |
27862 |
+ #endif /* __KERNEL__ */ |
27863 |
+ |
27864 |
+diff -urNp linux-2.6.24.4/include/asm-sparc/elf.h linux-2.6.24.4/include/asm-sparc/elf.h |
27865 |
+--- linux-2.6.24.4/include/asm-sparc/elf.h 2008-03-24 14:49:18.000000000 -0400 |
27866 |
++++ linux-2.6.24.4/include/asm-sparc/elf.h 2008-03-26 17:56:56.000000000 -0400 |
27867 |
+@@ -143,6 +143,13 @@ do { unsigned long *dest = &(__elf_regs[ |
27868 |
+ |
27869 |
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE) |
27870 |
+ |
27871 |
++#ifdef CONFIG_PAX_ASLR |
27872 |
++#define PAX_ELF_ET_DYN_BASE 0x10000UL |
27873 |
++ |
27874 |
++#define PAX_DELTA_MMAP_LEN 16 |
27875 |
++#define PAX_DELTA_STACK_LEN 16 |
27876 |
++#endif |
27877 |
++ |
27878 |
+ /* This yields a mask that user programs can use to figure out what |
27879 |
+ instruction set this cpu supports. This can NOT be done in userspace |
27880 |
+ on Sparc. */ |
27881 |
+diff -urNp linux-2.6.24.4/include/asm-sparc/kmap_types.h linux-2.6.24.4/include/asm-sparc/kmap_types.h |
27882 |
+--- linux-2.6.24.4/include/asm-sparc/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27883 |
++++ linux-2.6.24.4/include/asm-sparc/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27884 |
+@@ -15,6 +15,7 @@ enum km_type { |
27885 |
+ KM_IRQ1, |
27886 |
+ KM_SOFTIRQ0, |
27887 |
+ KM_SOFTIRQ1, |
27888 |
++ KM_CLEARPAGE, |
27889 |
+ KM_TYPE_NR |
27890 |
+ }; |
27891 |
+ |
27892 |
+diff -urNp linux-2.6.24.4/include/asm-sparc/pgtable.h linux-2.6.24.4/include/asm-sparc/pgtable.h |
27893 |
+--- linux-2.6.24.4/include/asm-sparc/pgtable.h 2008-03-24 14:49:18.000000000 -0400 |
27894 |
++++ linux-2.6.24.4/include/asm-sparc/pgtable.h 2008-03-26 17:56:56.000000000 -0400 |
27895 |
+@@ -69,6 +69,16 @@ extern pgprot_t PAGE_SHARED; |
27896 |
+ #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy)) |
27897 |
+ #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly)) |
27898 |
+ |
27899 |
++#ifdef CONFIG_PAX_PAGEEXEC |
27900 |
++extern pgprot_t PAGE_SHARED_NOEXEC; |
27901 |
++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec)) |
27902 |
++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec)) |
27903 |
++#else |
27904 |
++# define PAGE_SHARED_NOEXEC PAGE_SHARED |
27905 |
++# define PAGE_COPY_NOEXEC PAGE_COPY |
27906 |
++# define PAGE_READONLY_NOEXEC PAGE_READONLY |
27907 |
++#endif |
27908 |
++ |
27909 |
+ extern unsigned long page_kernel; |
27910 |
+ |
27911 |
+ #ifdef MODULE |
27912 |
+diff -urNp linux-2.6.24.4/include/asm-sparc/pgtsrmmu.h linux-2.6.24.4/include/asm-sparc/pgtsrmmu.h |
27913 |
+--- linux-2.6.24.4/include/asm-sparc/pgtsrmmu.h 2008-03-24 14:49:18.000000000 -0400 |
27914 |
++++ linux-2.6.24.4/include/asm-sparc/pgtsrmmu.h 2008-03-26 17:56:56.000000000 -0400 |
27915 |
+@@ -115,6 +115,16 @@ |
27916 |
+ SRMMU_EXEC | SRMMU_REF) |
27917 |
+ #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \ |
27918 |
+ SRMMU_EXEC | SRMMU_REF) |
27919 |
++ |
27920 |
++#ifdef CONFIG_PAX_PAGEEXEC |
27921 |
++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \ |
27922 |
++ SRMMU_WRITE | SRMMU_REF) |
27923 |
++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \ |
27924 |
++ SRMMU_REF) |
27925 |
++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \ |
27926 |
++ SRMMU_REF) |
27927 |
++#endif |
27928 |
++ |
27929 |
+ #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \ |
27930 |
+ SRMMU_DIRTY | SRMMU_REF) |
27931 |
+ |
27932 |
+diff -urNp linux-2.6.24.4/include/asm-sparc/uaccess.h linux-2.6.24.4/include/asm-sparc/uaccess.h |
27933 |
+--- linux-2.6.24.4/include/asm-sparc/uaccess.h 2008-03-24 14:49:18.000000000 -0400 |
27934 |
++++ linux-2.6.24.4/include/asm-sparc/uaccess.h 2008-03-26 17:56:56.000000000 -0400 |
27935 |
+@@ -41,7 +41,7 @@ |
27936 |
+ * No one can read/write anything from userland in the kernel space by setting |
27937 |
+ * large size and address near to PAGE_OFFSET - a fault will break his intentions. |
27938 |
+ */ |
27939 |
+-#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; }) |
27940 |
++#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; }) |
27941 |
+ #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) |
27942 |
+ #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size))) |
27943 |
+ #define access_ok(type, addr, size) \ |
27944 |
+diff -urNp linux-2.6.24.4/include/asm-sparc64/a.out.h linux-2.6.24.4/include/asm-sparc64/a.out.h |
27945 |
+--- linux-2.6.24.4/include/asm-sparc64/a.out.h 2008-03-24 14:49:18.000000000 -0400 |
27946 |
++++ linux-2.6.24.4/include/asm-sparc64/a.out.h 2008-03-26 17:56:56.000000000 -0400 |
27947 |
+@@ -98,7 +98,7 @@ struct relocation_info /* used when head |
27948 |
+ #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE) |
27949 |
+ #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL)) |
27950 |
+ |
27951 |
+-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ |
27952 |
++#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \ |
27953 |
+ STACK_TOP32 : STACK_TOP64) |
27954 |
+ |
27955 |
+ #define STACK_TOP_MAX STACK_TOP64 |
27956 |
+diff -urNp linux-2.6.24.4/include/asm-sparc64/elf.h linux-2.6.24.4/include/asm-sparc64/elf.h |
27957 |
+--- linux-2.6.24.4/include/asm-sparc64/elf.h 2008-03-24 14:49:18.000000000 -0400 |
27958 |
++++ linux-2.6.24.4/include/asm-sparc64/elf.h 2008-03-26 17:56:56.000000000 -0400 |
27959 |
+@@ -143,6 +143,12 @@ typedef struct { |
27960 |
+ #define ELF_ET_DYN_BASE 0x0000010000000000UL |
27961 |
+ #endif |
27962 |
+ |
27963 |
++#ifdef CONFIG_PAX_ASLR |
27964 |
++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL) |
27965 |
++ |
27966 |
++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 ) |
27967 |
++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 ) |
27968 |
++#endif |
27969 |
+ |
27970 |
+ /* This yields a mask that user programs can use to figure out what |
27971 |
+ instruction set this cpu supports. */ |
27972 |
+diff -urNp linux-2.6.24.4/include/asm-sparc64/kmap_types.h linux-2.6.24.4/include/asm-sparc64/kmap_types.h |
27973 |
+--- linux-2.6.24.4/include/asm-sparc64/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27974 |
++++ linux-2.6.24.4/include/asm-sparc64/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27975 |
+@@ -19,6 +19,7 @@ enum km_type { |
27976 |
+ KM_IRQ1, |
27977 |
+ KM_SOFTIRQ0, |
27978 |
+ KM_SOFTIRQ1, |
27979 |
++ KM_CLEARPAGE, |
27980 |
+ KM_TYPE_NR |
27981 |
+ }; |
27982 |
+ |
27983 |
+diff -urNp linux-2.6.24.4/include/asm-um/kmap_types.h linux-2.6.24.4/include/asm-um/kmap_types.h |
27984 |
+--- linux-2.6.24.4/include/asm-um/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27985 |
++++ linux-2.6.24.4/include/asm-um/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27986 |
+@@ -23,6 +23,7 @@ enum km_type { |
27987 |
+ KM_IRQ1, |
27988 |
+ KM_SOFTIRQ0, |
27989 |
+ KM_SOFTIRQ1, |
27990 |
++ KM_CLEARPAGE, |
27991 |
+ KM_TYPE_NR |
27992 |
+ }; |
27993 |
+ |
27994 |
+diff -urNp linux-2.6.24.4/include/asm-v850/kmap_types.h linux-2.6.24.4/include/asm-v850/kmap_types.h |
27995 |
+--- linux-2.6.24.4/include/asm-v850/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
27996 |
++++ linux-2.6.24.4/include/asm-v850/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
27997 |
+@@ -13,6 +13,7 @@ enum km_type { |
27998 |
+ KM_PTE1, |
27999 |
+ KM_IRQ0, |
28000 |
+ KM_IRQ1, |
28001 |
++ KM_CLEARPAGE, |
28002 |
+ KM_TYPE_NR |
28003 |
+ }; |
28004 |
+ |
28005 |
+diff -urNp linux-2.6.24.4/include/asm-x86/alternative_32.h linux-2.6.24.4/include/asm-x86/alternative_32.h |
28006 |
+--- linux-2.6.24.4/include/asm-x86/alternative_32.h 2008-03-24 14:49:18.000000000 -0400 |
28007 |
++++ linux-2.6.24.4/include/asm-x86/alternative_32.h 2008-03-26 17:56:56.000000000 -0400 |
28008 |
+@@ -54,7 +54,7 @@ static inline void alternatives_smp_swit |
28009 |
+ " .byte 662b-661b\n" /* sourcelen */ \ |
28010 |
+ " .byte 664f-663f\n" /* replacementlen */ \ |
28011 |
+ ".previous\n" \ |
28012 |
+- ".section .altinstr_replacement,\"ax\"\n" \ |
28013 |
++ ".section .altinstr_replacement,\"a\"\n" \ |
28014 |
+ "663:\n\t" newinstr "\n664:\n" /* replacement */\ |
28015 |
+ ".previous" :: "i" (feature) : "memory") |
28016 |
+ |
28017 |
+@@ -78,7 +78,7 @@ static inline void alternatives_smp_swit |
28018 |
+ " .byte 662b-661b\n" /* sourcelen */ \ |
28019 |
+ " .byte 664f-663f\n" /* replacementlen */ \ |
28020 |
+ ".previous\n" \ |
28021 |
+- ".section .altinstr_replacement,\"ax\"\n" \ |
28022 |
++ ".section .altinstr_replacement,\"a\"\n" \ |
28023 |
+ "663:\n\t" newinstr "\n664:\n" /* replacement */\ |
28024 |
+ ".previous" :: "i" (feature), ##input) |
28025 |
+ |
28026 |
+@@ -93,7 +93,7 @@ static inline void alternatives_smp_swit |
28027 |
+ " .byte 662b-661b\n" /* sourcelen */ \ |
28028 |
+ " .byte 664f-663f\n" /* replacementlen */ \ |
28029 |
+ ".previous\n" \ |
28030 |
+- ".section .altinstr_replacement,\"ax\"\n" \ |
28031 |
++ ".section .altinstr_replacement,\"a\"\n" \ |
28032 |
+ "663:\n\t" newinstr "\n664:\n" /* replacement */ \ |
28033 |
+ ".previous" : output : [feat] "i" (feature), ##input) |
28034 |
+ |
28035 |
+diff -urNp linux-2.6.24.4/include/asm-x86/alternative_64.h linux-2.6.24.4/include/asm-x86/alternative_64.h |
28036 |
+--- linux-2.6.24.4/include/asm-x86/alternative_64.h 2008-03-24 14:49:18.000000000 -0400 |
28037 |
++++ linux-2.6.24.4/include/asm-x86/alternative_64.h 2008-03-26 17:56:56.000000000 -0400 |
28038 |
+@@ -94,7 +94,7 @@ static inline void alternatives_smp_swit |
28039 |
+ " .byte 662b-661b\n" /* sourcelen */ \ |
28040 |
+ " .byte 664f-663f\n" /* replacementlen */ \ |
28041 |
+ ".previous\n" \ |
28042 |
+- ".section .altinstr_replacement,\"ax\"\n" \ |
28043 |
++ ".section .altinstr_replacement,\"a\"\n" \ |
28044 |
+ "663:\n\t" newinstr "\n664:\n" /* replacement */ \ |
28045 |
+ ".previous" :: "i" (feature) : "memory") |
28046 |
+ |
28047 |
+@@ -118,7 +118,7 @@ static inline void alternatives_smp_swit |
28048 |
+ " .byte 662b-661b\n" /* sourcelen */ \ |
28049 |
+ " .byte 664f-663f\n" /* replacementlen */ \ |
28050 |
+ ".previous\n" \ |
28051 |
+- ".section .altinstr_replacement,\"ax\"\n" \ |
28052 |
++ ".section .altinstr_replacement,\"a\"\n" \ |
28053 |
+ "663:\n\t" newinstr "\n664:\n" /* replacement */ \ |
28054 |
+ ".previous" :: "i" (feature), ##input) |
28055 |
+ |
28056 |
+@@ -133,7 +133,7 @@ static inline void alternatives_smp_swit |
28057 |
+ " .byte 662b-661b\n" /* sourcelen */ \ |
28058 |
+ " .byte 664f-663f\n" /* replacementlen */ \ |
28059 |
+ ".previous\n" \ |
28060 |
+- ".section .altinstr_replacement,\"ax\"\n" \ |
28061 |
++ ".section .altinstr_replacement,\"a\"\n" \ |
28062 |
+ "663:\n\t" newinstr "\n664:\n" /* replacement */ \ |
28063 |
+ ".previous" : output : [feat] "i" (feature), ##input) |
28064 |
+ |
28065 |
+diff -urNp linux-2.6.24.4/include/asm-x86/a.out.h linux-2.6.24.4/include/asm-x86/a.out.h |
28066 |
+--- linux-2.6.24.4/include/asm-x86/a.out.h 2008-03-24 14:49:18.000000000 -0400 |
28067 |
++++ linux-2.6.24.4/include/asm-x86/a.out.h 2008-03-26 17:56:56.000000000 -0400 |
28068 |
+@@ -19,9 +19,13 @@ struct exec |
28069 |
+ |
28070 |
+ #ifdef __KERNEL__ |
28071 |
+ # include <linux/thread_info.h> |
28072 |
+-# define STACK_TOP TASK_SIZE |
28073 |
++# ifdef CONFIG_PAX_SEGMEXEC |
28074 |
++# define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE) |
28075 |
++# else |
28076 |
++# define __STACK_TOP TASK_SIZE |
28077 |
++# endif |
28078 |
+ # ifdef CONFIG_X86_32 |
28079 |
+-# define STACK_TOP_MAX STACK_TOP |
28080 |
++# define STACK_TOP_MAX TASK_SIZE |
28081 |
+ # else |
28082 |
+ # define STACK_TOP_MAX TASK_SIZE64 |
28083 |
+ # endif |
28084 |
+diff -urNp linux-2.6.24.4/include/asm-x86/apic_32.h linux-2.6.24.4/include/asm-x86/apic_32.h |
28085 |
+--- linux-2.6.24.4/include/asm-x86/apic_32.h 2008-03-24 14:49:18.000000000 -0400 |
28086 |
++++ linux-2.6.24.4/include/asm-x86/apic_32.h 2008-03-26 17:56:56.000000000 -0400 |
28087 |
+@@ -8,7 +8,7 @@ |
28088 |
+ #include <asm/processor.h> |
28089 |
+ #include <asm/system.h> |
28090 |
+ |
28091 |
+-#define Dprintk(x...) |
28092 |
++#define Dprintk(x...) do {} while (0) |
28093 |
+ |
28094 |
+ /* |
28095 |
+ * Debugging macros |
28096 |
+diff -urNp linux-2.6.24.4/include/asm-x86/apic_64.h linux-2.6.24.4/include/asm-x86/apic_64.h |
28097 |
+--- linux-2.6.24.4/include/asm-x86/apic_64.h 2008-03-24 14:49:18.000000000 -0400 |
28098 |
++++ linux-2.6.24.4/include/asm-x86/apic_64.h 2008-03-26 17:56:56.000000000 -0400 |
28099 |
+@@ -7,7 +7,7 @@ |
28100 |
+ #include <asm/apicdef.h> |
28101 |
+ #include <asm/system.h> |
28102 |
+ |
28103 |
+-#define Dprintk(x...) |
28104 |
++#define Dprintk(x...) do {} while (0) |
28105 |
+ |
28106 |
+ /* |
28107 |
+ * Debugging macros |
28108 |
+diff -urNp linux-2.6.24.4/include/asm-x86/boot.h linux-2.6.24.4/include/asm-x86/boot.h |
28109 |
+--- linux-2.6.24.4/include/asm-x86/boot.h 2008-03-24 14:49:18.000000000 -0400 |
28110 |
++++ linux-2.6.24.4/include/asm-x86/boot.h 2008-03-26 17:56:56.000000000 -0400 |
28111 |
+@@ -13,8 +13,13 @@ |
28112 |
+ #define ASK_VGA 0xfffd /* ask for it at bootup */ |
28113 |
+ |
28114 |
+ /* Physical address where kernel should be loaded. */ |
28115 |
+-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ |
28116 |
++#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ |
28117 |
+ + (CONFIG_PHYSICAL_ALIGN - 1)) \ |
28118 |
+ & ~(CONFIG_PHYSICAL_ALIGN - 1)) |
28119 |
+ |
28120 |
++#ifndef __ASSEMBLY__ |
28121 |
++extern unsigned char __LOAD_PHYSICAL_ADDR[]; |
28122 |
++#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR) |
28123 |
++#endif |
28124 |
++ |
28125 |
+ #endif /* _ASM_BOOT_H */ |
28126 |
+diff -urNp linux-2.6.24.4/include/asm-x86/cache.h linux-2.6.24.4/include/asm-x86/cache.h |
28127 |
+--- linux-2.6.24.4/include/asm-x86/cache.h 2008-03-24 14:49:18.000000000 -0400 |
28128 |
++++ linux-2.6.24.4/include/asm-x86/cache.h 2008-03-26 17:56:56.000000000 -0400 |
28129 |
+@@ -6,6 +6,7 @@ |
28130 |
+ #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) |
28131 |
+ |
28132 |
+ #define __read_mostly __attribute__((__section__(".data.read_mostly"))) |
28133 |
++#define __read_only __attribute__((__section__(".data.read_only"))) |
28134 |
+ |
28135 |
+ #ifdef CONFIG_X86_VSMP |
28136 |
+ /* vSMP Internode cacheline shift */ |
28137 |
+diff -urNp linux-2.6.24.4/include/asm-x86/checksum_32.h linux-2.6.24.4/include/asm-x86/checksum_32.h |
28138 |
+--- linux-2.6.24.4/include/asm-x86/checksum_32.h 2008-03-24 14:49:18.000000000 -0400 |
28139 |
++++ linux-2.6.24.4/include/asm-x86/checksum_32.h 2008-03-26 17:56:56.000000000 -0400 |
28140 |
+@@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi |
28141 |
+ asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, |
28142 |
+ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr); |
28143 |
+ |
28144 |
++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst, |
28145 |
++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr); |
28146 |
++ |
28147 |
++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst, |
28148 |
++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr); |
28149 |
++ |
28150 |
+ /* |
28151 |
+ * Note: when you get a NULL pointer exception here this means someone |
28152 |
+ * passed in an incorrect kernel address to one of these functions. |
28153 |
+@@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const |
28154 |
+ int len, __wsum sum, int *err_ptr) |
28155 |
+ { |
28156 |
+ might_sleep(); |
28157 |
+- return csum_partial_copy_generic((__force void *)src, dst, |
28158 |
++ return csum_partial_copy_generic_from_user((__force void *)src, dst, |
28159 |
+ len, sum, err_ptr, NULL); |
28160 |
+ } |
28161 |
+ |
28162 |
+@@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t |
28163 |
+ { |
28164 |
+ might_sleep(); |
28165 |
+ if (access_ok(VERIFY_WRITE, dst, len)) |
28166 |
+- return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr); |
28167 |
++ return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr); |
28168 |
+ |
28169 |
+ if (len) |
28170 |
+ *err_ptr = -EFAULT; |
28171 |
+diff -urNp linux-2.6.24.4/include/asm-x86/desc_32.h linux-2.6.24.4/include/asm-x86/desc_32.h |
28172 |
+--- linux-2.6.24.4/include/asm-x86/desc_32.h 2008-03-24 14:49:18.000000000 -0400 |
28173 |
++++ linux-2.6.24.4/include/asm-x86/desc_32.h 2008-03-26 17:56:56.000000000 -0400 |
28174 |
+@@ -7,30 +7,26 @@ |
28175 |
+ #ifndef __ASSEMBLY__ |
28176 |
+ |
28177 |
+ #include <linux/preempt.h> |
28178 |
+-#include <linux/smp.h> |
28179 |
+ #include <linux/percpu.h> |
28180 |
++#include <linux/smp.h> |
28181 |
+ |
28182 |
+ #include <asm/mmu.h> |
28183 |
+ |
28184 |
++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)]; |
28185 |
++ |
28186 |
+ struct Xgt_desc_struct { |
28187 |
+ unsigned short size; |
28188 |
+- unsigned long address __attribute__((packed)); |
28189 |
++ struct desc_struct *address __attribute__((packed)); |
28190 |
+ unsigned short pad; |
28191 |
+ } __attribute__ ((packed)); |
28192 |
+ |
28193 |
+-struct gdt_page |
28194 |
+-{ |
28195 |
+- struct desc_struct gdt[GDT_ENTRIES]; |
28196 |
+-} __attribute__((aligned(PAGE_SIZE))); |
28197 |
+-DECLARE_PER_CPU(struct gdt_page, gdt_page); |
28198 |
+- |
28199 |
+ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) |
28200 |
+ { |
28201 |
+- return per_cpu(gdt_page, cpu).gdt; |
28202 |
++ return cpu_gdt_table[cpu]; |
28203 |
+ } |
28204 |
+ |
28205 |
+ extern struct Xgt_desc_struct idt_descr; |
28206 |
+-extern struct desc_struct idt_table[]; |
28207 |
++extern struct desc_struct idt_table[256]; |
28208 |
+ extern void set_intr_gate(unsigned int irq, void * addr); |
28209 |
+ |
28210 |
+ static inline void pack_descriptor(__u32 *a, __u32 *b, |
28211 |
+@@ -81,8 +77,20 @@ static inline void pack_gate(__u32 *a, _ |
28212 |
+ static inline void write_dt_entry(struct desc_struct *dt, |
28213 |
+ int entry, u32 entry_low, u32 entry_high) |
28214 |
+ { |
28215 |
++ |
28216 |
++#ifdef CONFIG_PAX_KERNEXEC |
28217 |
++ unsigned long cr0; |
28218 |
++ |
28219 |
++ pax_open_kernel(cr0); |
28220 |
++#endif |
28221 |
++ |
28222 |
+ dt[entry].a = entry_low; |
28223 |
+ dt[entry].b = entry_high; |
28224 |
++ |
28225 |
++#ifdef CONFIG_PAX_KERNEXEC |
28226 |
++ pax_close_kernel(cr0); |
28227 |
++#endif |
28228 |
++ |
28229 |
+ } |
28230 |
+ |
28231 |
+ static inline void native_set_ldt(const void *addr, unsigned int entries) |
28232 |
+@@ -139,8 +147,19 @@ static inline void native_load_tls(struc |
28233 |
+ unsigned int i; |
28234 |
+ struct desc_struct *gdt = get_cpu_gdt_table(cpu); |
28235 |
+ |
28236 |
++#ifdef CONFIG_PAX_KERNEXEC |
28237 |
++ unsigned long cr0; |
28238 |
++ |
28239 |
++ pax_open_kernel(cr0); |
28240 |
++#endif |
28241 |
++ |
28242 |
+ for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) |
28243 |
+ gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; |
28244 |
++ |
28245 |
++#ifdef CONFIG_PAX_KERNEXEC |
28246 |
++ pax_close_kernel(cr0); |
28247 |
++#endif |
28248 |
++ |
28249 |
+ } |
28250 |
+ |
28251 |
+ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) |
28252 |
+@@ -175,7 +194,7 @@ static inline void __set_tss_desc(unsign |
28253 |
+ ((info)->seg_32bit << 22) | \ |
28254 |
+ ((info)->limit_in_pages << 23) | \ |
28255 |
+ ((info)->useable << 20) | \ |
28256 |
+- 0x7000) |
28257 |
++ 0x7100) |
28258 |
+ |
28259 |
+ #define LDT_empty(info) (\ |
28260 |
+ (info)->base_addr == 0 && \ |
28261 |
+@@ -207,15 +226,25 @@ static inline void load_LDT(mm_context_t |
28262 |
+ preempt_enable(); |
28263 |
+ } |
28264 |
+ |
28265 |
+-static inline unsigned long get_desc_base(unsigned long *desc) |
28266 |
++static inline unsigned long get_desc_base(struct desc_struct *desc) |
28267 |
+ { |
28268 |
+ unsigned long base; |
28269 |
+- base = ((desc[0] >> 16) & 0x0000ffff) | |
28270 |
+- ((desc[1] << 16) & 0x00ff0000) | |
28271 |
+- (desc[1] & 0xff000000); |
28272 |
++ base = ((desc->a >> 16) & 0x0000ffff) | |
28273 |
++ ((desc->b << 16) & 0x00ff0000) | |
28274 |
++ (desc->b & 0xff000000); |
28275 |
+ return base; |
28276 |
+ } |
28277 |
+ |
28278 |
++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu) |
28279 |
++{ |
28280 |
++ __u32 a, b; |
28281 |
++ |
28282 |
++ if (likely(limit)) |
28283 |
++ limit = (limit - 1UL) >> PAGE_SHIFT; |
28284 |
++ pack_descriptor(&a, &b, base, limit, 0xFB, 0xC); |
28285 |
++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b); |
28286 |
++} |
28287 |
++ |
28288 |
+ #else /* __ASSEMBLY__ */ |
28289 |
+ |
28290 |
+ /* |
28291 |
+diff -urNp linux-2.6.24.4/include/asm-x86/desc_64.h linux-2.6.24.4/include/asm-x86/desc_64.h |
28292 |
+--- linux-2.6.24.4/include/asm-x86/desc_64.h 2008-03-24 14:49:18.000000000 -0400 |
28293 |
++++ linux-2.6.24.4/include/asm-x86/desc_64.h 2008-03-26 17:56:56.000000000 -0400 |
28294 |
+@@ -14,7 +14,7 @@ |
28295 |
+ #include <asm/segment.h> |
28296 |
+ #include <asm/mmu.h> |
28297 |
+ |
28298 |
+-extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; |
28299 |
++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)]; |
28300 |
+ |
28301 |
+ #define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8)) |
28302 |
+ #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8)) |
28303 |
+@@ -34,12 +34,10 @@ static inline unsigned long __store_tr(v |
28304 |
+ * This is the ldt that every process will get unless we need |
28305 |
+ * something other than this. |
28306 |
+ */ |
28307 |
+-extern struct desc_struct default_ldt[]; |
28308 |
+ extern struct gate_struct idt_table[]; |
28309 |
+-extern struct desc_ptr cpu_gdt_descr[]; |
28310 |
+ |
28311 |
+ /* the cpu gdt accessor */ |
28312 |
+-#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) |
28313 |
++#define cpu_gdt(_cpu) (cpu_gdt_table[_cpu]) |
28314 |
+ |
28315 |
+ static inline void load_gdt(const struct desc_ptr *ptr) |
28316 |
+ { |
28317 |
+@@ -54,6 +52,11 @@ static inline void store_gdt(struct desc |
28318 |
+ static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist) |
28319 |
+ { |
28320 |
+ struct gate_struct s; |
28321 |
++ |
28322 |
++#ifdef CONFIG_PAX_KERNEXEC |
28323 |
++ unsigned long cr0; |
28324 |
++#endif |
28325 |
++ |
28326 |
+ s.offset_low = PTR_LOW(func); |
28327 |
+ s.segment = __KERNEL_CS; |
28328 |
+ s.ist = ist; |
28329 |
+@@ -65,7 +68,17 @@ static inline void _set_gate(void *adr, |
28330 |
+ s.offset_middle = PTR_MIDDLE(func); |
28331 |
+ s.offset_high = PTR_HIGH(func); |
28332 |
+ /* does not need to be atomic because it is only done once at setup time */ |
28333 |
++ |
28334 |
++#ifdef CONFIG_PAX_KERNEXEC |
28335 |
++ pax_open_kernel(cr0); |
28336 |
++#endif |
28337 |
++ |
28338 |
+ memcpy(adr, &s, 16); |
28339 |
++ |
28340 |
++#ifdef CONFIG_PAX_KERNEXEC |
28341 |
++ pax_close_kernel(cr0); |
28342 |
++#endif |
28343 |
++ |
28344 |
+ } |
28345 |
+ |
28346 |
+ static inline void set_intr_gate(int nr, void *func) |
28347 |
+@@ -105,6 +118,11 @@ static inline void set_tssldt_descriptor |
28348 |
+ unsigned size) |
28349 |
+ { |
28350 |
+ struct ldttss_desc d; |
28351 |
++ |
28352 |
++#ifdef CONFIG_PAX_KERNEXEC |
28353 |
++ unsigned long cr0; |
28354 |
++#endif |
28355 |
++ |
28356 |
+ memset(&d,0,sizeof(d)); |
28357 |
+ d.limit0 = size & 0xFFFF; |
28358 |
+ d.base0 = PTR_LOW(tss); |
28359 |
+@@ -114,7 +132,17 @@ static inline void set_tssldt_descriptor |
28360 |
+ d.limit1 = (size >> 16) & 0xF; |
28361 |
+ d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; |
28362 |
+ d.base3 = PTR_HIGH(tss); |
28363 |
++ |
28364 |
++#ifdef CONFIG_PAX_KERNEXEC |
28365 |
++ pax_open_kernel(cr0); |
28366 |
++#endif |
28367 |
++ |
28368 |
+ memcpy(ptr, &d, 16); |
28369 |
++ |
28370 |
++#ifdef CONFIG_PAX_KERNEXEC |
28371 |
++ pax_close_kernel(cr0); |
28372 |
++#endif |
28373 |
++ |
28374 |
+ } |
28375 |
+ |
28376 |
+ static inline void set_tss_desc(unsigned cpu, void *addr) |
28377 |
+@@ -152,7 +180,7 @@ static inline void set_ldt_desc(unsigned |
28378 |
+ ((info)->limit_in_pages << 23) | \ |
28379 |
+ ((info)->useable << 20) | \ |
28380 |
+ /* ((info)->lm << 21) | */ \ |
28381 |
+- 0x7000) |
28382 |
++ 0x7100) |
28383 |
+ |
28384 |
+ #define LDT_empty(info) (\ |
28385 |
+ (info)->base_addr == 0 && \ |
28386 |
+@@ -170,8 +198,19 @@ static inline void load_TLS(struct threa |
28387 |
+ unsigned int i; |
28388 |
+ u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN); |
28389 |
+ |
28390 |
++#ifdef CONFIG_PAX_KERNEXEC |
28391 |
++ unsigned long cr0; |
28392 |
++ |
28393 |
++ pax_open_kernel(cr0); |
28394 |
++#endif |
28395 |
++ |
28396 |
+ for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) |
28397 |
+ gdt[i] = t->tls_array[i]; |
28398 |
++ |
28399 |
++#ifdef CONFIG_PAX_KERNEXEC |
28400 |
++ pax_close_kernel(cr0); |
28401 |
++#endif |
28402 |
++ |
28403 |
+ } |
28404 |
+ |
28405 |
+ /* |
28406 |
+@@ -197,7 +236,7 @@ static inline void load_LDT(mm_context_t |
28407 |
+ put_cpu(); |
28408 |
+ } |
28409 |
+ |
28410 |
+-extern struct desc_ptr idt_descr; |
28411 |
++extern const struct desc_ptr idt_descr; |
28412 |
+ |
28413 |
+ #endif /* !__ASSEMBLY__ */ |
28414 |
+ |
28415 |
+diff -urNp linux-2.6.24.4/include/asm-x86/elf.h linux-2.6.24.4/include/asm-x86/elf.h |
28416 |
+--- linux-2.6.24.4/include/asm-x86/elf.h 2008-03-24 14:49:18.000000000 -0400 |
28417 |
++++ linux-2.6.24.4/include/asm-x86/elf.h 2008-03-26 17:56:56.000000000 -0400 |
28418 |
+@@ -206,7 +206,25 @@ extern int vdso_enabled; |
28419 |
+ the loader. We need to make sure that it is out of the way of the program |
28420 |
+ that it will "exec", and that there is sufficient room for the brk. */ |
28421 |
+ |
28422 |
++#ifdef CONFIG_PAX_SEGMEXEC |
28423 |
++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2) |
28424 |
++#else |
28425 |
+ #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) |
28426 |
++#endif |
28427 |
++ |
28428 |
++#ifdef CONFIG_PAX_ASLR |
28429 |
++#ifdef CONFIG_X86_32 |
28430 |
++#define PAX_ELF_ET_DYN_BASE 0x10000000UL |
28431 |
++ |
28432 |
++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16) |
28433 |
++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16) |
28434 |
++#else |
28435 |
++#define PAX_ELF_ET_DYN_BASE 0x400000UL |
28436 |
++ |
28437 |
++#define PAX_DELTA_MMAP_LEN 32 |
28438 |
++#define PAX_DELTA_STACK_LEN 32 |
28439 |
++#endif |
28440 |
++#endif |
28441 |
+ |
28442 |
+ /* This yields a mask that user programs can use to figure out what |
28443 |
+ instruction set this CPU supports. This could be done in user space, |
28444 |
+@@ -246,7 +264,7 @@ extern int dump_task_extended_fpu (struc |
28445 |
+ #define ELF_CORE_XFPREG_TYPE NT_PRXFPREG |
28446 |
+ |
28447 |
+ #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) |
28448 |
+-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) |
28449 |
++#define VDSO_CURRENT_BASE (current->mm->context.vdso) |
28450 |
+ #define VDSO_PRELINK 0 |
28451 |
+ |
28452 |
+ #define VDSO_SYM(x) \ |
28453 |
+@@ -274,7 +292,7 @@ do if (vdso_enabled) { \ |
28454 |
+ |
28455 |
+ #define ARCH_DLINFO \ |
28456 |
+ do if (vdso_enabled) { \ |
28457 |
+- NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\ |
28458 |
++ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\ |
28459 |
+ } while (0) |
28460 |
+ |
28461 |
+ #endif /* !CONFIG_X86_32 */ |
28462 |
+diff -urNp linux-2.6.24.4/include/asm-x86/futex_32.h linux-2.6.24.4/include/asm-x86/futex_32.h |
28463 |
+--- linux-2.6.24.4/include/asm-x86/futex_32.h 2008-03-24 14:49:18.000000000 -0400 |
28464 |
++++ linux-2.6.24.4/include/asm-x86/futex_32.h 2008-03-26 17:56:56.000000000 -0400 |
28465 |
+@@ -11,8 +11,11 @@ |
28466 |
+ |
28467 |
+ #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \ |
28468 |
+ __asm__ __volatile ( \ |
28469 |
++ "movw %w6, %%ds\n"\ |
28470 |
+ "1: " insn "\n" \ |
28471 |
+-"2: .section .fixup,\"ax\"\n\ |
28472 |
++"2: pushl %%ss\n\ |
28473 |
++ popl %%ds\n\ |
28474 |
++ .section .fixup,\"ax\"\n\ |
28475 |
+ 3: mov %3, %1\n\ |
28476 |
+ jmp 2b\n\ |
28477 |
+ .previous\n\ |
28478 |
+@@ -21,16 +24,19 @@ |
28479 |
+ .long 1b,3b\n\ |
28480 |
+ .previous" \ |
28481 |
+ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \ |
28482 |
+- : "i" (-EFAULT), "0" (oparg), "1" (0)) |
28483 |
++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS)) |
28484 |
+ |
28485 |
+ #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \ |
28486 |
+ __asm__ __volatile ( \ |
28487 |
+-"1: movl %2, %0\n\ |
28488 |
++" movw %w7, %%es\n\ |
28489 |
++1: movl %%es:%2, %0\n\ |
28490 |
+ movl %0, %3\n" \ |
28491 |
+ insn "\n" \ |
28492 |
+-"2: lock ; cmpxchgl %3, %2\n\ |
28493 |
++"2: lock ; cmpxchgl %3, %%es:%2\n\ |
28494 |
+ jnz 1b\n\ |
28495 |
+-3: .section .fixup,\"ax\"\n\ |
28496 |
++3: pushl %%ss\n\ |
28497 |
++ popl %%es\n\ |
28498 |
++ .section .fixup,\"ax\"\n\ |
28499 |
+ 4: mov %5, %1\n\ |
28500 |
+ jmp 3b\n\ |
28501 |
+ .previous\n\ |
28502 |
+@@ -40,10 +46,10 @@ |
28503 |
+ .previous" \ |
28504 |
+ : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \ |
28505 |
+ "=&r" (tem) \ |
28506 |
+- : "r" (oparg), "i" (-EFAULT), "1" (0)) |
28507 |
++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS)) |
28508 |
+ |
28509 |
+ static inline int |
28510 |
+-futex_atomic_op_inuser (int encoded_op, int __user *uaddr) |
28511 |
++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
28512 |
+ { |
28513 |
+ int op = (encoded_op >> 28) & 7; |
28514 |
+ int cmp = (encoded_op >> 24) & 15; |
28515 |
+@@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op, |
28516 |
+ pagefault_disable(); |
28517 |
+ |
28518 |
+ if (op == FUTEX_OP_SET) |
28519 |
+- __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); |
28520 |
++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg); |
28521 |
+ else { |
28522 |
+ #ifndef CONFIG_X86_BSWAP |
28523 |
+ if (boot_cpu_data.x86 == 3) |
28524 |
+@@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op, |
28525 |
+ #endif |
28526 |
+ switch (op) { |
28527 |
+ case FUTEX_OP_ADD: |
28528 |
+- __futex_atomic_op1("lock ; xaddl %0, %2", ret, |
28529 |
++ __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, |
28530 |
+ oldval, uaddr, oparg); |
28531 |
+ break; |
28532 |
+ case FUTEX_OP_OR: |
28533 |
+@@ -105,15 +111,17 @@ futex_atomic_op_inuser (int encoded_op, |
28534 |
+ } |
28535 |
+ |
28536 |
+ static inline int |
28537 |
+-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) |
28538 |
++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval) |
28539 |
+ { |
28540 |
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) |
28541 |
+ return -EFAULT; |
28542 |
+ |
28543 |
+ __asm__ __volatile__( |
28544 |
+- "1: lock ; cmpxchgl %3, %1 \n" |
28545 |
+- |
28546 |
+- "2: .section .fixup, \"ax\" \n" |
28547 |
++ " movw %w5, %%ds \n" |
28548 |
++ "1: lock ; cmpxchgl %3, %%ds:%1 \n" |
28549 |
++ "2: pushl %%ss \n" |
28550 |
++ " popl %%ds \n" |
28551 |
++ " .section .fixup, \"ax\" \n" |
28552 |
+ "3: mov %2, %0 \n" |
28553 |
+ " jmp 2b \n" |
28554 |
+ " .previous \n" |
28555 |
+@@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user |
28556 |
+ " .previous \n" |
28557 |
+ |
28558 |
+ : "=a" (oldval), "+m" (*uaddr) |
28559 |
+- : "i" (-EFAULT), "r" (newval), "0" (oldval) |
28560 |
++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS) |
28561 |
+ : "memory" |
28562 |
+ ); |
28563 |
+ |
28564 |
+diff -urNp linux-2.6.24.4/include/asm-x86/futex_64.h linux-2.6.24.4/include/asm-x86/futex_64.h |
28565 |
+--- linux-2.6.24.4/include/asm-x86/futex_64.h 2008-03-24 14:49:18.000000000 -0400 |
28566 |
++++ linux-2.6.24.4/include/asm-x86/futex_64.h 2008-03-26 17:56:56.000000000 -0400 |
28567 |
+@@ -42,7 +42,7 @@ |
28568 |
+ : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0)) |
28569 |
+ |
28570 |
+ static inline int |
28571 |
+-futex_atomic_op_inuser (int encoded_op, int __user *uaddr) |
28572 |
++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
28573 |
+ { |
28574 |
+ int op = (encoded_op >> 28) & 7; |
28575 |
+ int cmp = (encoded_op >> 24) & 15; |
28576 |
+@@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op, |
28577 |
+ } |
28578 |
+ |
28579 |
+ static inline int |
28580 |
+-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) |
28581 |
++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval) |
28582 |
+ { |
28583 |
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) |
28584 |
+ return -EFAULT; |
28585 |
+diff -urNp linux-2.6.24.4/include/asm-x86/i387_32.h linux-2.6.24.4/include/asm-x86/i387_32.h |
28586 |
+--- linux-2.6.24.4/include/asm-x86/i387_32.h 2008-03-24 14:49:18.000000000 -0400 |
28587 |
++++ linux-2.6.24.4/include/asm-x86/i387_32.h 2008-03-26 17:56:56.000000000 -0400 |
28588 |
+@@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void); |
28589 |
+ #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) |
28590 |
+ |
28591 |
+ /* We need a safe address that is cheap to find and that is already |
28592 |
+- in L1 during context switch. The best choices are unfortunately |
28593 |
+- different for UP and SMP */ |
28594 |
+-#ifdef CONFIG_SMP |
28595 |
+-#define safe_address (__per_cpu_offset[0]) |
28596 |
+-#else |
28597 |
+-#define safe_address (kstat_cpu(0).cpustat.user) |
28598 |
+-#endif |
28599 |
++ in L1 during context switch. */ |
28600 |
++#define safe_address (init_tss[smp_processor_id()].x86_tss.esp0) |
28601 |
+ |
28602 |
+ /* |
28603 |
+ * These must be called with preempt disabled |
28604 |
+diff -urNp linux-2.6.24.4/include/asm-x86/io_64.h linux-2.6.24.4/include/asm-x86/io_64.h |
28605 |
+--- linux-2.6.24.4/include/asm-x86/io_64.h 2008-03-24 14:49:18.000000000 -0400 |
28606 |
++++ linux-2.6.24.4/include/asm-x86/io_64.h 2008-03-26 17:56:56.000000000 -0400 |
28607 |
+@@ -120,6 +120,17 @@ static inline void * phys_to_virt(unsign |
28608 |
+ } |
28609 |
+ #endif |
28610 |
+ |
28611 |
++#define ARCH_HAS_VALID_PHYS_ADDR_RANGE |
28612 |
++static inline int valid_phys_addr_range (unsigned long addr, size_t count) |
28613 |
++{ |
28614 |
++ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0; |
28615 |
++} |
28616 |
++ |
28617 |
++static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count) |
28618 |
++{ |
28619 |
++ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0; |
28620 |
++} |
28621 |
++ |
28622 |
+ /* |
28623 |
+ * Change "struct page" to physical address. |
28624 |
+ */ |
28625 |
+diff -urNp linux-2.6.24.4/include/asm-x86/irqflags_32.h linux-2.6.24.4/include/asm-x86/irqflags_32.h |
28626 |
+--- linux-2.6.24.4/include/asm-x86/irqflags_32.h 2008-03-24 14:49:18.000000000 -0400 |
28627 |
++++ linux-2.6.24.4/include/asm-x86/irqflags_32.h 2008-03-26 17:56:56.000000000 -0400 |
28628 |
+@@ -108,6 +108,8 @@ static inline unsigned long __raw_local_ |
28629 |
+ #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit |
28630 |
+ #define INTERRUPT_RETURN iret |
28631 |
+ #define GET_CR0_INTO_EAX movl %cr0, %eax |
28632 |
++#define GET_CR0_INTO_EDX movl %cr0, %edx |
28633 |
++#define SET_CR0_FROM_EDX movl %edx, %cr0 |
28634 |
+ #endif /* __ASSEMBLY__ */ |
28635 |
+ #endif /* CONFIG_PARAVIRT */ |
28636 |
+ |
28637 |
+diff -urNp linux-2.6.24.4/include/asm-x86/kmap_types.h linux-2.6.24.4/include/asm-x86/kmap_types.h |
28638 |
+--- linux-2.6.24.4/include/asm-x86/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
28639 |
++++ linux-2.6.24.4/include/asm-x86/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
28640 |
+@@ -21,7 +21,8 @@ D(9) KM_IRQ0, |
28641 |
+ D(10) KM_IRQ1, |
28642 |
+ D(11) KM_SOFTIRQ0, |
28643 |
+ D(12) KM_SOFTIRQ1, |
28644 |
+-D(13) KM_TYPE_NR |
28645 |
++D(13) KM_CLEARPAGE, |
28646 |
++D(14) KM_TYPE_NR |
28647 |
+ }; |
28648 |
+ |
28649 |
+ #undef D |
28650 |
+diff -urNp linux-2.6.24.4/include/asm-x86/mach-default/apm.h linux-2.6.24.4/include/asm-x86/mach-default/apm.h |
28651 |
+--- linux-2.6.24.4/include/asm-x86/mach-default/apm.h 2008-03-24 14:49:18.000000000 -0400 |
28652 |
++++ linux-2.6.24.4/include/asm-x86/mach-default/apm.h 2008-03-26 17:56:56.000000000 -0400 |
28653 |
+@@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32 |
28654 |
+ __asm__ __volatile__(APM_DO_ZERO_SEGS |
28655 |
+ "pushl %%edi\n\t" |
28656 |
+ "pushl %%ebp\n\t" |
28657 |
+- "lcall *%%cs:apm_bios_entry\n\t" |
28658 |
++ "lcall *%%ss:apm_bios_entry\n\t" |
28659 |
+ "setc %%al\n\t" |
28660 |
+ "popl %%ebp\n\t" |
28661 |
+ "popl %%edi\n\t" |
28662 |
+@@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as |
28663 |
+ __asm__ __volatile__(APM_DO_ZERO_SEGS |
28664 |
+ "pushl %%edi\n\t" |
28665 |
+ "pushl %%ebp\n\t" |
28666 |
+- "lcall *%%cs:apm_bios_entry\n\t" |
28667 |
++ "lcall *%%ss:apm_bios_entry\n\t" |
28668 |
+ "setc %%bl\n\t" |
28669 |
+ "popl %%ebp\n\t" |
28670 |
+ "popl %%edi\n\t" |
28671 |
+diff -urNp linux-2.6.24.4/include/asm-x86/mman.h linux-2.6.24.4/include/asm-x86/mman.h |
28672 |
+--- linux-2.6.24.4/include/asm-x86/mman.h 2008-03-24 14:49:18.000000000 -0400 |
28673 |
++++ linux-2.6.24.4/include/asm-x86/mman.h 2008-03-26 17:56:56.000000000 -0400 |
28674 |
+@@ -16,4 +16,14 @@ |
28675 |
+ #define MCL_CURRENT 1 /* lock all current mappings */ |
28676 |
+ #define MCL_FUTURE 2 /* lock all future mappings */ |
28677 |
+ |
28678 |
++#ifdef __KERNEL__ |
28679 |
++#ifndef __ASSEMBLY__ |
28680 |
++#ifdef CONFIG_X86_32 |
28681 |
++#define arch_mmap_check i386_mmap_check |
28682 |
++int i386_mmap_check(unsigned long addr, unsigned long len, |
28683 |
++ unsigned long flags); |
28684 |
++#endif |
28685 |
++#endif |
28686 |
++#endif |
28687 |
++ |
28688 |
+ #endif /* _ASM_X86_MMAN_H */ |
28689 |
+diff -urNp linux-2.6.24.4/include/asm-x86/mmu_context_32.h linux-2.6.24.4/include/asm-x86/mmu_context_32.h |
28690 |
+--- linux-2.6.24.4/include/asm-x86/mmu_context_32.h 2008-03-24 14:49:18.000000000 -0400 |
28691 |
++++ linux-2.6.24.4/include/asm-x86/mmu_context_32.h 2008-03-26 17:56:56.000000000 -0400 |
28692 |
+@@ -57,6 +57,22 @@ static inline void switch_mm(struct mm_s |
28693 |
+ */ |
28694 |
+ if (unlikely(prev->context.ldt != next->context.ldt)) |
28695 |
+ load_LDT_nolock(&next->context); |
28696 |
++ |
28697 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP) |
28698 |
++ if (!nx_enabled) { |
28699 |
++ smp_mb__before_clear_bit(); |
28700 |
++ cpu_clear(cpu, prev->context.cpu_user_cs_mask); |
28701 |
++ smp_mb__after_clear_bit(); |
28702 |
++ cpu_set(cpu, next->context.cpu_user_cs_mask); |
28703 |
++ } |
28704 |
++#endif |
28705 |
++ |
28706 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
28707 |
++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base || |
28708 |
++ prev->context.user_cs_limit != next->context.user_cs_limit)) |
28709 |
++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu); |
28710 |
++#endif |
28711 |
++ |
28712 |
+ } |
28713 |
+ #ifdef CONFIG_SMP |
28714 |
+ else { |
28715 |
+@@ -69,6 +85,19 @@ static inline void switch_mm(struct mm_s |
28716 |
+ */ |
28717 |
+ load_cr3(next->pgd); |
28718 |
+ load_LDT_nolock(&next->context); |
28719 |
++ |
28720 |
++#ifdef CONFIG_PAX_PAGEEXEC |
28721 |
++ if (!nx_enabled) |
28722 |
++ cpu_set(cpu, next->context.cpu_user_cs_mask); |
28723 |
++#endif |
28724 |
++ |
28725 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
28726 |
++#ifdef CONFIG_PAX_PAGEEXEC |
28727 |
++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled)) |
28728 |
++#endif |
28729 |
++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu); |
28730 |
++#endif |
28731 |
++ |
28732 |
+ } |
28733 |
+ } |
28734 |
+ #endif |
28735 |
+diff -urNp linux-2.6.24.4/include/asm-x86/mmu.h linux-2.6.24.4/include/asm-x86/mmu.h |
28736 |
+--- linux-2.6.24.4/include/asm-x86/mmu.h 2008-03-24 14:49:18.000000000 -0400 |
28737 |
++++ linux-2.6.24.4/include/asm-x86/mmu.h 2008-03-26 17:56:56.000000000 -0400 |
28738 |
+@@ -11,13 +11,26 @@ |
28739 |
+ * cpu_vm_mask is used to optimize ldt flushing. |
28740 |
+ */ |
28741 |
+ typedef struct { |
28742 |
+- void *ldt; |
28743 |
++ struct desc_struct *ldt; |
28744 |
+ #ifdef CONFIG_X86_64 |
28745 |
+ rwlock_t ldtlock; |
28746 |
+ #endif |
28747 |
+ int size; |
28748 |
+ struct mutex lock; |
28749 |
+- void *vdso; |
28750 |
++ unsigned long vdso; |
28751 |
++ |
28752 |
++#ifdef CONFIG_X86_32 |
28753 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
28754 |
++ unsigned long user_cs_base; |
28755 |
++ unsigned long user_cs_limit; |
28756 |
++ |
28757 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP) |
28758 |
++ cpumask_t cpu_user_cs_mask; |
28759 |
++#endif |
28760 |
++ |
28761 |
++#endif |
28762 |
++#endif |
28763 |
++ |
28764 |
+ } mm_context_t; |
28765 |
+ |
28766 |
+ #endif /* _ASM_X86_MMU_H */ |
28767 |
+diff -urNp linux-2.6.24.4/include/asm-x86/module_32.h linux-2.6.24.4/include/asm-x86/module_32.h |
28768 |
+--- linux-2.6.24.4/include/asm-x86/module_32.h 2008-03-24 14:49:18.000000000 -0400 |
28769 |
++++ linux-2.6.24.4/include/asm-x86/module_32.h 2008-03-26 17:56:56.000000000 -0400 |
28770 |
+@@ -70,6 +70,12 @@ struct mod_arch_specific |
28771 |
+ #define MODULE_STACKSIZE "" |
28772 |
+ #endif |
28773 |
+ |
28774 |
+-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE |
28775 |
++#ifdef CONFIG_GRKERNSEC |
28776 |
++#define MODULE_GRSEC "GRSECURITY " |
28777 |
++#else |
28778 |
++#define MODULE_GRSEC "" |
28779 |
++#endif |
28780 |
++ |
28781 |
++#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC |
28782 |
+ |
28783 |
+ #endif /* _ASM_I386_MODULE_H */ |
28784 |
+diff -urNp linux-2.6.24.4/include/asm-x86/page_32.h linux-2.6.24.4/include/asm-x86/page_32.h |
28785 |
+--- linux-2.6.24.4/include/asm-x86/page_32.h 2008-03-24 14:49:18.000000000 -0400 |
28786 |
++++ linux-2.6.24.4/include/asm-x86/page_32.h 2008-03-26 17:56:56.000000000 -0400 |
28787 |
+@@ -90,7 +90,6 @@ static inline pte_t native_make_pte(unsi |
28788 |
+ typedef struct { unsigned long pte_low; } pte_t; |
28789 |
+ typedef struct { unsigned long pgd; } pgd_t; |
28790 |
+ typedef struct { unsigned long pgprot; } pgprot_t; |
28791 |
+-#define boot_pte_t pte_t /* or would you rather have a typedef */ |
28792 |
+ |
28793 |
+ static inline unsigned long native_pgd_val(pgd_t pgd) |
28794 |
+ { |
28795 |
+@@ -175,6 +174,18 @@ extern int page_is_ram(unsigned long pag |
28796 |
+ #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET) |
28797 |
+ #endif |
28798 |
+ |
28799 |
++#ifdef CONFIG_PAX_KERNEXEC |
28800 |
++#ifndef __ASSEMBLY__ |
28801 |
++extern unsigned char MODULES_VADDR[]; |
28802 |
++extern unsigned char MODULES_END[]; |
28803 |
++extern unsigned char KERNEL_TEXT_OFFSET[]; |
28804 |
++#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET) |
28805 |
++#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET) |
28806 |
++#endif |
28807 |
++#else |
28808 |
++#define ktla_ktva(addr) (addr) |
28809 |
++#define ktva_ktla(addr) (addr) |
28810 |
++#endif |
28811 |
+ |
28812 |
+ #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) |
28813 |
+ #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) |
28814 |
+@@ -197,6 +208,10 @@ extern int page_is_ram(unsigned long pag |
28815 |
+ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ |
28816 |
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
28817 |
+ |
28818 |
++#ifdef CONFIG_PAX_PAGEEXEC |
28819 |
++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1 |
28820 |
++#endif |
28821 |
++ |
28822 |
+ #include <asm-generic/memory_model.h> |
28823 |
+ #include <asm-generic/page.h> |
28824 |
+ |
28825 |
+diff -urNp linux-2.6.24.4/include/asm-x86/page_64.h linux-2.6.24.4/include/asm-x86/page_64.h |
28826 |
+--- linux-2.6.24.4/include/asm-x86/page_64.h 2008-03-24 14:49:18.000000000 -0400 |
28827 |
++++ linux-2.6.24.4/include/asm-x86/page_64.h 2008-03-26 17:56:56.000000000 -0400 |
28828 |
+@@ -94,6 +94,9 @@ extern unsigned long phys_base; |
28829 |
+ #define __START_KERNEL_map _AC(0xffffffff80000000, UL) |
28830 |
+ #define __PAGE_OFFSET _AC(0xffff810000000000, UL) |
28831 |
+ |
28832 |
++#define ktla_ktva(addr) (addr) |
28833 |
++#define ktva_ktla(addr) (addr) |
28834 |
++ |
28835 |
+ /* to align the pointer to the (next) page boundary */ |
28836 |
+ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) |
28837 |
+ |
28838 |
+diff -urNp linux-2.6.24.4/include/asm-x86/paravirt.h linux-2.6.24.4/include/asm-x86/paravirt.h |
28839 |
+--- linux-2.6.24.4/include/asm-x86/paravirt.h 2008-03-24 14:49:18.000000000 -0400 |
28840 |
++++ linux-2.6.24.4/include/asm-x86/paravirt.h 2008-03-26 17:56:56.000000000 -0400 |
28841 |
+@@ -1124,23 +1124,23 @@ static inline unsigned long __raw_local_ |
28842 |
+ |
28843 |
+ #define INTERRUPT_RETURN \ |
28844 |
+ PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \ |
28845 |
+- jmp *%cs:pv_cpu_ops+PV_CPU_iret) |
28846 |
++ jmp *%ss:pv_cpu_ops+PV_CPU_iret) |
28847 |
+ |
28848 |
+ #define DISABLE_INTERRUPTS(clobbers) \ |
28849 |
+ PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ |
28850 |
+ pushl %eax; pushl %ecx; pushl %edx; \ |
28851 |
+- call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \ |
28852 |
++ call *%ss:pv_irq_ops+PV_IRQ_irq_disable; \ |
28853 |
+ popl %edx; popl %ecx; popl %eax) \ |
28854 |
+ |
28855 |
+ #define ENABLE_INTERRUPTS(clobbers) \ |
28856 |
+ PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \ |
28857 |
+ pushl %eax; pushl %ecx; pushl %edx; \ |
28858 |
+- call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \ |
28859 |
++ call *%ss:pv_irq_ops+PV_IRQ_irq_enable; \ |
28860 |
+ popl %edx; popl %ecx; popl %eax) |
28861 |
+ |
28862 |
+ #define ENABLE_INTERRUPTS_SYSEXIT \ |
28863 |
+ PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), CLBR_NONE,\ |
28864 |
+- jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_sysexit) |
28865 |
++ jmp *%ss:pv_cpu_ops+PV_CPU_irq_enable_sysexit) |
28866 |
+ |
28867 |
+ #define GET_CR0_INTO_EAX \ |
28868 |
+ push %ecx; push %edx; \ |
28869 |
+diff -urNp linux-2.6.24.4/include/asm-x86/pda.h linux-2.6.24.4/include/asm-x86/pda.h |
28870 |
+--- linux-2.6.24.4/include/asm-x86/pda.h 2008-03-24 14:49:18.000000000 -0400 |
28871 |
++++ linux-2.6.24.4/include/asm-x86/pda.h 2008-03-26 17:56:56.000000000 -0400 |
28872 |
+@@ -16,11 +16,9 @@ struct x8664_pda { |
28873 |
+ unsigned long oldrsp; /* 24 user rsp for system call */ |
28874 |
+ int irqcount; /* 32 Irq nesting counter. Starts with -1 */ |
28875 |
+ int cpunumber; /* 36 Logical CPU number */ |
28876 |
+-#ifdef CONFIG_CC_STACKPROTECTOR |
28877 |
+ unsigned long stack_canary; /* 40 stack canary value */ |
28878 |
+ /* gcc-ABI: this canary MUST be at |
28879 |
+ offset 40!!! */ |
28880 |
+-#endif |
28881 |
+ char *irqstackptr; |
28882 |
+ int nodenumber; /* number of current node */ |
28883 |
+ unsigned int __softirq_pending; |
28884 |
+diff -urNp linux-2.6.24.4/include/asm-x86/percpu_32.h linux-2.6.24.4/include/asm-x86/percpu_32.h |
28885 |
+--- linux-2.6.24.4/include/asm-x86/percpu_32.h 2008-03-24 14:49:18.000000000 -0400 |
28886 |
++++ linux-2.6.24.4/include/asm-x86/percpu_32.h 2008-03-26 17:56:56.000000000 -0400 |
28887 |
+@@ -22,7 +22,7 @@ |
28888 |
+ #define PER_CPU_VAR(var) %fs:per_cpu__##var |
28889 |
+ #else /* ! SMP */ |
28890 |
+ #define PER_CPU(var, reg) \ |
28891 |
+- movl $per_cpu__##var, reg |
28892 |
++ movl per_cpu__##var, reg |
28893 |
+ #define PER_CPU_VAR(var) per_cpu__##var |
28894 |
+ #endif /* SMP */ |
28895 |
+ |
28896 |
+@@ -42,12 +42,12 @@ |
28897 |
+ */ |
28898 |
+ #ifdef CONFIG_SMP |
28899 |
+ /* Same as generic implementation except for optimized local access. */ |
28900 |
+-#define __GENERIC_PER_CPU |
28901 |
+ |
28902 |
+ /* This is used for other cpus to find our section. */ |
28903 |
+ extern unsigned long __per_cpu_offset[]; |
28904 |
++extern void setup_per_cpu_areas(void); |
28905 |
+ |
28906 |
+-#define per_cpu_offset(x) (__per_cpu_offset[x]) |
28907 |
++#define per_cpu_offset(x) (__per_cpu_offset[x] - (unsigned long)__per_cpu_start) |
28908 |
+ |
28909 |
+ /* Separate out the type, so (int[3], foo) works. */ |
28910 |
+ #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name |
28911 |
+@@ -64,11 +64,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_ |
28912 |
+ |
28913 |
+ /* var is in discarded region: offset to particular copy we want */ |
28914 |
+ #define per_cpu(var, cpu) (*({ \ |
28915 |
+- extern int simple_indentifier_##var(void); \ |
28916 |
++ extern int simple_identifier_##var(void); \ |
28917 |
+ RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); })) |
28918 |
+ |
28919 |
+ #define __raw_get_cpu_var(var) (*({ \ |
28920 |
+- extern int simple_indentifier_##var(void); \ |
28921 |
++ extern int simple_identifier_##var(void); \ |
28922 |
+ RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off)); \ |
28923 |
+ })) |
28924 |
+ |
28925 |
+@@ -79,7 +79,7 @@ DECLARE_PER_CPU(unsigned long, this_cpu_ |
28926 |
+ do { \ |
28927 |
+ unsigned int __i; \ |
28928 |
+ for_each_possible_cpu(__i) \ |
28929 |
+- memcpy((pcpudst)+__per_cpu_offset[__i], \ |
28930 |
++ memcpy((pcpudst)+per_cpu_offset(__i), \ |
28931 |
+ (src), (size)); \ |
28932 |
+ } while (0) |
28933 |
+ |
28934 |
+diff -urNp linux-2.6.24.4/include/asm-x86/pgalloc_32.h linux-2.6.24.4/include/asm-x86/pgalloc_32.h |
28935 |
+--- linux-2.6.24.4/include/asm-x86/pgalloc_32.h 2008-03-24 14:49:18.000000000 -0400 |
28936 |
++++ linux-2.6.24.4/include/asm-x86/pgalloc_32.h 2008-03-26 17:56:56.000000000 -0400 |
28937 |
+@@ -15,11 +15,19 @@ |
28938 |
+ #define paravirt_release_pd(pfn) do { } while (0) |
28939 |
+ #endif |
28940 |
+ |
28941 |
++#ifdef CONFIG_COMPAT_VDSO |
28942 |
+ #define pmd_populate_kernel(mm, pmd, pte) \ |
28943 |
+ do { \ |
28944 |
+ paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \ |
28945 |
+ set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \ |
28946 |
+ } while (0) |
28947 |
++#else |
28948 |
++#define pmd_populate_kernel(mm, pmd, pte) \ |
28949 |
++do { \ |
28950 |
++ paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \ |
28951 |
++ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); \ |
28952 |
++} while (0) |
28953 |
++#endif |
28954 |
+ |
28955 |
+ #define pmd_populate(mm, pmd, pte) \ |
28956 |
+ do { \ |
28957 |
+diff -urNp linux-2.6.24.4/include/asm-x86/pgalloc_64.h linux-2.6.24.4/include/asm-x86/pgalloc_64.h |
28958 |
+--- linux-2.6.24.4/include/asm-x86/pgalloc_64.h 2008-03-24 14:49:18.000000000 -0400 |
28959 |
++++ linux-2.6.24.4/include/asm-x86/pgalloc_64.h 2008-03-26 17:56:56.000000000 -0400 |
28960 |
+@@ -6,7 +6,7 @@ |
28961 |
+ #include <linux/mm.h> |
28962 |
+ |
28963 |
+ #define pmd_populate_kernel(mm, pmd, pte) \ |
28964 |
+- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte))) |
28965 |
++ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte))) |
28966 |
+ #define pud_populate(mm, pud, pmd) \ |
28967 |
+ set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd))) |
28968 |
+ #define pgd_populate(mm, pgd, pud) \ |
28969 |
+diff -urNp linux-2.6.24.4/include/asm-x86/pgtable-2level.h linux-2.6.24.4/include/asm-x86/pgtable-2level.h |
28970 |
+--- linux-2.6.24.4/include/asm-x86/pgtable-2level.h 2008-03-24 14:49:18.000000000 -0400 |
28971 |
++++ linux-2.6.24.4/include/asm-x86/pgtable-2level.h 2008-03-26 17:56:56.000000000 -0400 |
28972 |
+@@ -22,7 +22,19 @@ static inline void native_set_pte_at(str |
28973 |
+ } |
28974 |
+ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) |
28975 |
+ { |
28976 |
++ |
28977 |
++#ifdef CONFIG_PAX_KERNEXEC |
28978 |
++ unsigned long cr0; |
28979 |
++ |
28980 |
++ pax_open_kernel(cr0); |
28981 |
++#endif |
28982 |
++ |
28983 |
+ *pmdp = pmd; |
28984 |
++ |
28985 |
++#ifdef CONFIG_PAX_KERNEXEC |
28986 |
++ pax_close_kernel(cr0); |
28987 |
++#endif |
28988 |
++ |
28989 |
+ } |
28990 |
+ #ifndef CONFIG_PARAVIRT |
28991 |
+ #define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval) |
28992 |
+diff -urNp linux-2.6.24.4/include/asm-x86/pgtable_32.h linux-2.6.24.4/include/asm-x86/pgtable_32.h |
28993 |
+--- linux-2.6.24.4/include/asm-x86/pgtable_32.h 2008-03-24 14:49:18.000000000 -0400 |
28994 |
++++ linux-2.6.24.4/include/asm-x86/pgtable_32.h 2008-03-26 17:56:56.000000000 -0400 |
28995 |
+@@ -31,7 +31,6 @@ struct vm_area_struct; |
28996 |
+ */ |
28997 |
+ #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) |
28998 |
+ extern unsigned long empty_zero_page[1024]; |
28999 |
+-extern pgd_t swapper_pg_dir[1024]; |
29000 |
+ extern struct kmem_cache *pmd_cache; |
29001 |
+ extern spinlock_t pgd_lock; |
29002 |
+ extern struct page *pgd_list; |
29003 |
+@@ -55,6 +54,11 @@ void paging_init(void); |
29004 |
+ # include <asm/pgtable-2level-defs.h> |
29005 |
+ #endif |
29006 |
+ |
29007 |
++extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; |
29008 |
++#ifdef CONFIG_X86_PAE |
29009 |
++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD]; |
29010 |
++#endif |
29011 |
++ |
29012 |
+ #define PGDIR_SIZE (1UL << PGDIR_SHIFT) |
29013 |
+ #define PGDIR_MASK (~(PGDIR_SIZE-1)) |
29014 |
+ |
29015 |
+@@ -64,9 +68,11 @@ void paging_init(void); |
29016 |
+ #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT) |
29017 |
+ #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS) |
29018 |
+ |
29019 |
++#ifndef CONFIG_X86_PAE |
29020 |
+ #define TWOLEVEL_PGDIR_SHIFT 22 |
29021 |
+ #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT) |
29022 |
+ #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS) |
29023 |
++#endif |
29024 |
+ |
29025 |
+ /* Just any arbitrary offset to the start of the vmalloc VM area: the |
29026 |
+ * current 8MB value just means that there will be a 8MB "hole" after the |
29027 |
+@@ -133,7 +139,7 @@ void paging_init(void); |
29028 |
+ #define PAGE_NONE \ |
29029 |
+ __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) |
29030 |
+ #define PAGE_SHARED \ |
29031 |
+- __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) |
29032 |
++ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) |
29033 |
+ |
29034 |
+ #define PAGE_SHARED_EXEC \ |
29035 |
+ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) |
29036 |
+@@ -199,7 +205,7 @@ extern unsigned long long __PAGE_KERNEL, |
29037 |
+ #undef TEST_ACCESS_OK |
29038 |
+ |
29039 |
+ /* The boot page tables (all created as a single array) */ |
29040 |
+-extern unsigned long pg0[]; |
29041 |
++extern pte_t pg0[]; |
29042 |
+ |
29043 |
+ #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) |
29044 |
+ |
29045 |
+@@ -215,30 +221,55 @@ extern unsigned long pg0[]; |
29046 |
+ * The following only work if pte_present() is true. |
29047 |
+ * Undefined behaviour if not.. |
29048 |
+ */ |
29049 |
++static inline int pte_user(pte_t pte) { return (pte).pte_low & _PAGE_USER; } |
29050 |
+ static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_DIRTY; } |
29051 |
+ static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; } |
29052 |
+ static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; } |
29053 |
+ static inline int pte_huge(pte_t pte) { return (pte).pte_low & _PAGE_PSE; } |
29054 |
+ |
29055 |
++#ifdef CONFIG_X86_PAE |
29056 |
++# include <asm/pgtable-3level.h> |
29057 |
++#else |
29058 |
++# include <asm/pgtable-2level.h> |
29059 |
++#endif |
29060 |
++ |
29061 |
+ /* |
29062 |
+ * The following only works if pte_present() is not true. |
29063 |
+ */ |
29064 |
+ static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; } |
29065 |
+ |
29066 |
++static inline pte_t pte_exprotect(pte_t pte) |
29067 |
++{ |
29068 |
++#ifdef CONFIG_X86_PAE |
29069 |
++ if (__supported_pte_mask & _PAGE_NX) |
29070 |
++ set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX)); |
29071 |
++ else |
29072 |
++#endif |
29073 |
++ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); |
29074 |
++ return pte; |
29075 |
++} |
29076 |
++ |
29077 |
+ static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; } |
29078 |
+ static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; } |
29079 |
+ static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; } |
29080 |
++static inline pte_t pte_mkread(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; } |
29081 |
++ |
29082 |
++static inline pte_t pte_mkexec(pte_t pte) |
29083 |
++{ |
29084 |
++#ifdef CONFIG_X86_PAE |
29085 |
++ if (__supported_pte_mask & _PAGE_NX) |
29086 |
++ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); |
29087 |
++ else |
29088 |
++#endif |
29089 |
++ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); |
29090 |
++ return pte; |
29091 |
++} |
29092 |
++ |
29093 |
+ static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; } |
29094 |
+ static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; } |
29095 |
+ static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; } |
29096 |
+ static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; } |
29097 |
+ |
29098 |
+-#ifdef CONFIG_X86_PAE |
29099 |
+-# include <asm/pgtable-3level.h> |
29100 |
+-#else |
29101 |
+-# include <asm/pgtable-2level.h> |
29102 |
+-#endif |
29103 |
+- |
29104 |
+ #ifndef CONFIG_PARAVIRT |
29105 |
+ /* |
29106 |
+ * Rules for using pte_update - it must be called after any PTE update which |
29107 |
+@@ -350,7 +381,19 @@ static inline void ptep_set_wrprotect(st |
29108 |
+ */ |
29109 |
+ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) |
29110 |
+ { |
29111 |
+- memcpy(dst, src, count * sizeof(pgd_t)); |
29112 |
++ |
29113 |
++#ifdef CONFIG_PAX_KERNEXEC |
29114 |
++ unsigned long cr0; |
29115 |
++ |
29116 |
++ pax_open_kernel(cr0); |
29117 |
++#endif |
29118 |
++ |
29119 |
++ memcpy(dst, src, count * sizeof(pgd_t)); |
29120 |
++ |
29121 |
++#ifdef CONFIG_PAX_KERNEXEC |
29122 |
++ pax_close_kernel(cr0); |
29123 |
++#endif |
29124 |
++ |
29125 |
+ } |
29126 |
+ |
29127 |
+ /* |
29128 |
+@@ -497,6 +540,9 @@ static inline void paravirt_pagetable_se |
29129 |
+ |
29130 |
+ #endif /* !__ASSEMBLY__ */ |
29131 |
+ |
29132 |
++#define HAVE_ARCH_UNMAPPED_AREA |
29133 |
++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN |
29134 |
++ |
29135 |
+ #ifdef CONFIG_FLATMEM |
29136 |
+ #define kern_addr_valid(addr) (1) |
29137 |
+ #endif /* CONFIG_FLATMEM */ |
29138 |
+diff -urNp linux-2.6.24.4/include/asm-x86/pgtable-3level.h linux-2.6.24.4/include/asm-x86/pgtable-3level.h |
29139 |
+--- linux-2.6.24.4/include/asm-x86/pgtable-3level.h 2008-03-24 14:49:18.000000000 -0400 |
29140 |
++++ linux-2.6.24.4/include/asm-x86/pgtable-3level.h 2008-03-26 17:56:56.000000000 -0400 |
29141 |
+@@ -67,11 +67,35 @@ static inline void native_set_pte_atomic |
29142 |
+ } |
29143 |
+ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) |
29144 |
+ { |
29145 |
++ |
29146 |
++#ifdef CONFIG_PAX_KERNEXEC |
29147 |
++ unsigned long cr0; |
29148 |
++ |
29149 |
++ pax_open_kernel(cr0); |
29150 |
++#endif |
29151 |
++ |
29152 |
+ set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd)); |
29153 |
++ |
29154 |
++#ifdef CONFIG_PAX_KERNEXEC |
29155 |
++ pax_close_kernel(cr0); |
29156 |
++#endif |
29157 |
++ |
29158 |
+ } |
29159 |
+ static inline void native_set_pud(pud_t *pudp, pud_t pud) |
29160 |
+ { |
29161 |
++ |
29162 |
++#ifdef CONFIG_PAX_KERNEXEC |
29163 |
++ unsigned long cr0; |
29164 |
++ |
29165 |
++ pax_open_kernel(cr0); |
29166 |
++#endif |
29167 |
++ |
29168 |
+ *pudp = pud; |
29169 |
++ |
29170 |
++#ifdef CONFIG_PAX_KERNEXEC |
29171 |
++ pax_close_kernel(cr0); |
29172 |
++#endif |
29173 |
++ |
29174 |
+ } |
29175 |
+ |
29176 |
+ /* |
29177 |
+diff -urNp linux-2.6.24.4/include/asm-x86/pgtable_64.h linux-2.6.24.4/include/asm-x86/pgtable_64.h |
29178 |
+--- linux-2.6.24.4/include/asm-x86/pgtable_64.h 2008-03-24 14:49:18.000000000 -0400 |
29179 |
++++ linux-2.6.24.4/include/asm-x86/pgtable_64.h 2008-03-26 17:56:56.000000000 -0400 |
29180 |
+@@ -79,7 +79,19 @@ static inline void set_pte(pte_t *dst, p |
29181 |
+ |
29182 |
+ static inline void set_pmd(pmd_t *dst, pmd_t val) |
29183 |
+ { |
29184 |
++ |
29185 |
++#ifdef CONFIG_PAX_KERNEXEC |
29186 |
++ unsigned long cr0; |
29187 |
++ |
29188 |
++ pax_open_kernel(cr0); |
29189 |
++#endif |
29190 |
++ |
29191 |
+ pmd_val(*dst) = pmd_val(val); |
29192 |
++ |
29193 |
++#ifdef CONFIG_PAX_KERNEXEC |
29194 |
++ pax_close_kernel(cr0); |
29195 |
++#endif |
29196 |
++ |
29197 |
+ } |
29198 |
+ |
29199 |
+ static inline void set_pud(pud_t *dst, pud_t val) |
29200 |
+@@ -180,6 +192,10 @@ static inline pte_t ptep_get_and_clear_f |
29201 |
+ #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) |
29202 |
+ #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) |
29203 |
+ #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) |
29204 |
++ |
29205 |
++#define PAGE_READONLY_NOEXEC PAGE_READONLY |
29206 |
++#define PAGE_SHARED_NOEXEC PAGE_SHARED |
29207 |
++ |
29208 |
+ #define __PAGE_KERNEL \ |
29209 |
+ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) |
29210 |
+ #define __PAGE_KERNEL_EXEC \ |
29211 |
+@@ -188,10 +204,12 @@ static inline pte_t ptep_get_and_clear_f |
29212 |
+ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX) |
29213 |
+ #define __PAGE_KERNEL_RO \ |
29214 |
+ (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) |
29215 |
++#define __PAGE_KERNEL_RX \ |
29216 |
++ (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED) |
29217 |
+ #define __PAGE_KERNEL_VSYSCALL \ |
29218 |
+ (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) |
29219 |
+ #define __PAGE_KERNEL_VSYSCALL_NOCACHE \ |
29220 |
+- (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD) |
29221 |
++ (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD | _PAGE_NX) |
29222 |
+ #define __PAGE_KERNEL_LARGE \ |
29223 |
+ (__PAGE_KERNEL | _PAGE_PSE) |
29224 |
+ #define __PAGE_KERNEL_LARGE_EXEC \ |
29225 |
+@@ -202,6 +220,7 @@ static inline pte_t ptep_get_and_clear_f |
29226 |
+ #define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL) |
29227 |
+ #define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC) |
29228 |
+ #define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO) |
29229 |
++#define PAGE_KERNEL_RX MAKE_GLOBAL(__PAGE_KERNEL_RX) |
29230 |
+ #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) |
29231 |
+ #define PAGE_KERNEL_VSYSCALL32 __pgprot(__PAGE_KERNEL_VSYSCALL) |
29232 |
+ #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL) |
29233 |
+@@ -231,17 +250,17 @@ static inline pte_t ptep_get_and_clear_f |
29234 |
+ |
29235 |
+ static inline unsigned long pgd_bad(pgd_t pgd) |
29236 |
+ { |
29237 |
+- return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); |
29238 |
++ return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX); |
29239 |
+ } |
29240 |
+ |
29241 |
+ static inline unsigned long pud_bad(pud_t pud) |
29242 |
+ { |
29243 |
+- return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); |
29244 |
++ return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX); |
29245 |
+ } |
29246 |
+ |
29247 |
+ static inline unsigned long pmd_bad(pmd_t pmd) |
29248 |
+ { |
29249 |
+- return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); |
29250 |
++ return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX); |
29251 |
+ } |
29252 |
+ |
29253 |
+ #define pte_none(x) (!pte_val(x)) |
29254 |
+diff -urNp linux-2.6.24.4/include/asm-x86/processor_32.h linux-2.6.24.4/include/asm-x86/processor_32.h |
29255 |
+--- linux-2.6.24.4/include/asm-x86/processor_32.h 2008-03-24 14:49:18.000000000 -0400 |
29256 |
++++ linux-2.6.24.4/include/asm-x86/processor_32.h 2008-03-26 17:56:56.000000000 -0400 |
29257 |
+@@ -100,8 +100,6 @@ struct cpuinfo_x86 { |
29258 |
+ |
29259 |
+ extern struct cpuinfo_x86 boot_cpu_data; |
29260 |
+ extern struct cpuinfo_x86 new_cpu_data; |
29261 |
+-extern struct tss_struct doublefault_tss; |
29262 |
+-DECLARE_PER_CPU(struct tss_struct, init_tss); |
29263 |
+ |
29264 |
+ #ifdef CONFIG_SMP |
29265 |
+ DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); |
29266 |
+@@ -215,11 +213,19 @@ extern int bootloader_type; |
29267 |
+ */ |
29268 |
+ #define TASK_SIZE (PAGE_OFFSET) |
29269 |
+ |
29270 |
++#ifdef CONFIG_PAX_SEGMEXEC |
29271 |
++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2) |
29272 |
++#endif |
29273 |
++ |
29274 |
+ /* This decides where the kernel will search for a free chunk of vm |
29275 |
+ * space during mmap's. |
29276 |
+ */ |
29277 |
+ #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) |
29278 |
+ |
29279 |
++#ifdef CONFIG_PAX_SEGMEXEC |
29280 |
++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3)) |
29281 |
++#endif |
29282 |
++ |
29283 |
+ #define HAVE_ARCH_PICK_MMAP_LAYOUT |
29284 |
+ |
29285 |
+ extern void hard_disable_TSC(void); |
29286 |
+@@ -344,6 +350,9 @@ struct tss_struct { |
29287 |
+ |
29288 |
+ #define ARCH_MIN_TASKALIGN 16 |
29289 |
+ |
29290 |
++extern struct tss_struct doublefault_tss; |
29291 |
++extern struct tss_struct init_tss[NR_CPUS]; |
29292 |
++ |
29293 |
+ struct thread_struct { |
29294 |
+ /* cached TLS descriptors. */ |
29295 |
+ struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; |
29296 |
+@@ -372,7 +381,7 @@ struct thread_struct { |
29297 |
+ }; |
29298 |
+ |
29299 |
+ #define INIT_THREAD { \ |
29300 |
+- .esp0 = sizeof(init_stack) + (long)&init_stack, \ |
29301 |
++ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \ |
29302 |
+ .vm86_info = NULL, \ |
29303 |
+ .sysenter_cs = __KERNEL_CS, \ |
29304 |
+ .io_bitmap_ptr = NULL, \ |
29305 |
+@@ -387,7 +396,7 @@ struct thread_struct { |
29306 |
+ */ |
29307 |
+ #define INIT_TSS { \ |
29308 |
+ .x86_tss = { \ |
29309 |
+- .esp0 = sizeof(init_stack) + (long)&init_stack, \ |
29310 |
++ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \ |
29311 |
+ .ss0 = __KERNEL_DS, \ |
29312 |
+ .ss1 = __KERNEL_CS, \ |
29313 |
+ .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ |
29314 |
+@@ -428,11 +437,7 @@ void show_trace(struct task_struct *task |
29315 |
+ unsigned long get_wchan(struct task_struct *p); |
29316 |
+ |
29317 |
+ #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long)) |
29318 |
+-#define KSTK_TOP(info) \ |
29319 |
+-({ \ |
29320 |
+- unsigned long *__ptr = (unsigned long *)(info); \ |
29321 |
+- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \ |
29322 |
+-}) |
29323 |
++#define KSTK_TOP(info) ((info)->task.thread.esp0) |
29324 |
+ |
29325 |
+ /* |
29326 |
+ * The below -8 is to reserve 8 bytes on top of the ring0 stack. |
29327 |
+@@ -447,7 +452,7 @@ unsigned long get_wchan(struct task_stru |
29328 |
+ #define task_pt_regs(task) \ |
29329 |
+ ({ \ |
29330 |
+ struct pt_regs *__regs__; \ |
29331 |
+- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \ |
29332 |
++ __regs__ = (struct pt_regs *)((task)->thread.esp0); \ |
29333 |
+ __regs__ - 1; \ |
29334 |
+ }) |
29335 |
+ |
29336 |
+diff -urNp linux-2.6.24.4/include/asm-x86/processor_64.h linux-2.6.24.4/include/asm-x86/processor_64.h |
29337 |
+--- linux-2.6.24.4/include/asm-x86/processor_64.h 2008-03-24 14:49:18.000000000 -0400 |
29338 |
++++ linux-2.6.24.4/include/asm-x86/processor_64.h 2008-03-26 17:56:56.000000000 -0400 |
29339 |
+@@ -142,7 +142,7 @@ static inline void clear_in_cr4 (unsigne |
29340 |
+ /* This decides where the kernel will search for a free chunk of vm |
29341 |
+ * space during mmap's. |
29342 |
+ */ |
29343 |
+-#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000) |
29344 |
++#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFf000) |
29345 |
+ |
29346 |
+ #define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64) |
29347 |
+ #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64) |
29348 |
+@@ -201,7 +201,7 @@ struct tss_struct { |
29349 |
+ |
29350 |
+ |
29351 |
+ extern struct cpuinfo_x86 boot_cpu_data; |
29352 |
+-DECLARE_PER_CPU(struct tss_struct,init_tss); |
29353 |
++extern struct tss_struct init_tss[NR_CPUS]; |
29354 |
+ /* Save the original ist values for checking stack pointers during debugging */ |
29355 |
+ struct orig_ist { |
29356 |
+ unsigned long ist[7]; |
29357 |
+diff -urNp linux-2.6.24.4/include/asm-x86/ptrace.h linux-2.6.24.4/include/asm-x86/ptrace.h |
29358 |
+--- linux-2.6.24.4/include/asm-x86/ptrace.h 2008-03-24 14:49:18.000000000 -0400 |
29359 |
++++ linux-2.6.24.4/include/asm-x86/ptrace.h 2008-03-26 17:56:56.000000000 -0400 |
29360 |
+@@ -39,17 +39,18 @@ struct task_struct; |
29361 |
+ extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); |
29362 |
+ |
29363 |
+ /* |
29364 |
+- * user_mode_vm(regs) determines whether a register set came from user mode. |
29365 |
++ * user_mode(regs) determines whether a register set came from user mode. |
29366 |
+ * This is true if V8086 mode was enabled OR if the register set was from |
29367 |
+ * protected mode with RPL-3 CS value. This tricky test checks that with |
29368 |
+ * one comparison. Many places in the kernel can bypass this full check |
29369 |
+- * if they have already ruled out V8086 mode, so user_mode(regs) can be used. |
29370 |
++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can |
29371 |
++ * be used. |
29372 |
+ */ |
29373 |
+-static inline int user_mode(struct pt_regs *regs) |
29374 |
++static inline int user_mode_novm(struct pt_regs *regs) |
29375 |
+ { |
29376 |
+ return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL; |
29377 |
+ } |
29378 |
+-static inline int user_mode_vm(struct pt_regs *regs) |
29379 |
++static inline int user_mode(struct pt_regs *regs) |
29380 |
+ { |
29381 |
+ return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL; |
29382 |
+ } |
29383 |
+diff -urNp linux-2.6.24.4/include/asm-x86/reboot.h linux-2.6.24.4/include/asm-x86/reboot.h |
29384 |
+--- linux-2.6.24.4/include/asm-x86/reboot.h 2008-03-24 14:49:18.000000000 -0400 |
29385 |
++++ linux-2.6.24.4/include/asm-x86/reboot.h 2008-03-26 17:56:56.000000000 -0400 |
29386 |
+@@ -15,6 +15,6 @@ struct machine_ops |
29387 |
+ |
29388 |
+ extern struct machine_ops machine_ops; |
29389 |
+ |
29390 |
+-void machine_real_restart(unsigned char *code, int length); |
29391 |
++void machine_real_restart(const unsigned char *code, unsigned int length); |
29392 |
+ |
29393 |
+ #endif /* _ASM_REBOOT_H */ |
29394 |
+diff -urNp linux-2.6.24.4/include/asm-x86/segment_32.h linux-2.6.24.4/include/asm-x86/segment_32.h |
29395 |
+--- linux-2.6.24.4/include/asm-x86/segment_32.h 2008-03-24 14:49:18.000000000 -0400 |
29396 |
++++ linux-2.6.24.4/include/asm-x86/segment_32.h 2008-03-26 17:56:56.000000000 -0400 |
29397 |
+@@ -81,6 +81,12 @@ |
29398 |
+ #define __KERNEL_PERCPU 0 |
29399 |
+ #endif |
29400 |
+ |
29401 |
++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16) |
29402 |
++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8) |
29403 |
++ |
29404 |
++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17) |
29405 |
++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8) |
29406 |
++ |
29407 |
+ #define GDT_ENTRY_DOUBLEFAULT_TSS 31 |
29408 |
+ |
29409 |
+ /* |
29410 |
+@@ -140,9 +146,9 @@ |
29411 |
+ #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8) |
29412 |
+ |
29413 |
+ /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */ |
29414 |
+-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8) |
29415 |
++#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS) |
29416 |
+ |
29417 |
+ /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ |
29418 |
+-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) |
29419 |
++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16) |
29420 |
+ |
29421 |
+ #endif |
29422 |
+diff -urNp linux-2.6.24.4/include/asm-x86/system_32.h linux-2.6.24.4/include/asm-x86/system_32.h |
29423 |
+--- linux-2.6.24.4/include/asm-x86/system_32.h 2008-03-24 14:49:18.000000000 -0400 |
29424 |
++++ linux-2.6.24.4/include/asm-x86/system_32.h 2008-03-26 17:56:56.000000000 -0400 |
29425 |
+@@ -188,6 +188,21 @@ static inline void clflush(volatile void |
29426 |
+ /* Set the 'TS' bit */ |
29427 |
+ #define stts() write_cr0(8 | read_cr0()) |
29428 |
+ |
29429 |
++#define pax_open_kernel(cr0) \ |
29430 |
++do { \ |
29431 |
++ typecheck(unsigned long, cr0); \ |
29432 |
++ preempt_disable(); \ |
29433 |
++ cr0 = read_cr0(); \ |
29434 |
++ write_cr0(cr0 & ~X86_CR0_WP); \ |
29435 |
++} while (0) |
29436 |
++ |
29437 |
++#define pax_close_kernel(cr0) \ |
29438 |
++do { \ |
29439 |
++ typecheck(unsigned long, cr0); \ |
29440 |
++ write_cr0(cr0); \ |
29441 |
++ preempt_enable_no_resched(); \ |
29442 |
++} while (0) |
29443 |
++ |
29444 |
+ #endif /* __KERNEL__ */ |
29445 |
+ |
29446 |
+ static inline unsigned long get_limit(unsigned long segment) |
29447 |
+@@ -195,7 +210,7 @@ static inline unsigned long get_limit(un |
29448 |
+ unsigned long __limit; |
29449 |
+ __asm__("lsll %1,%0" |
29450 |
+ :"=r" (__limit):"r" (segment)); |
29451 |
+- return __limit+1; |
29452 |
++ return __limit; |
29453 |
+ } |
29454 |
+ |
29455 |
+ #define nop() __asm__ __volatile__ ("nop") |
29456 |
+@@ -311,7 +326,7 @@ void enable_hlt(void); |
29457 |
+ extern int es7000_plat; |
29458 |
+ void cpu_idle_wait(void); |
29459 |
+ |
29460 |
+-extern unsigned long arch_align_stack(unsigned long sp); |
29461 |
++#define arch_align_stack(x) (x) |
29462 |
+ extern void free_init_pages(char *what, unsigned long begin, unsigned long end); |
29463 |
+ |
29464 |
+ void default_idle(void); |
29465 |
+diff -urNp linux-2.6.24.4/include/asm-x86/system_64.h linux-2.6.24.4/include/asm-x86/system_64.h |
29466 |
+--- linux-2.6.24.4/include/asm-x86/system_64.h 2008-03-24 14:49:18.000000000 -0400 |
29467 |
++++ linux-2.6.24.4/include/asm-x86/system_64.h 2008-03-26 17:56:56.000000000 -0400 |
29468 |
+@@ -33,6 +33,8 @@ |
29469 |
+ ".globl thread_return\n" \ |
29470 |
+ "thread_return:\n\t" \ |
29471 |
+ "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \ |
29472 |
++ "movq %P[task_canary](%%rsi),%%r8\n\t" \ |
29473 |
++ "movq %%r8,%%gs:%P[pda_canary]\n\t" \ |
29474 |
+ "movq %P[thread_info](%%rsi),%%r8\n\t" \ |
29475 |
+ LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ |
29476 |
+ "movq %%rax,%%rdi\n\t" \ |
29477 |
+@@ -44,7 +46,9 @@ |
29478 |
+ [ti_flags] "i" (offsetof(struct thread_info, flags)),\ |
29479 |
+ [tif_fork] "i" (TIF_FORK), \ |
29480 |
+ [thread_info] "i" (offsetof(struct task_struct, stack)), \ |
29481 |
+- [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ |
29482 |
++ [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \ |
29483 |
++ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \ |
29484 |
++ [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary)) \ |
29485 |
+ : "memory", "cc" __EXTRA_CLOBBER) |
29486 |
+ |
29487 |
+ extern void load_gs_index(unsigned); |
29488 |
+@@ -139,6 +143,21 @@ static inline void write_cr8(unsigned lo |
29489 |
+ #define wbinvd() \ |
29490 |
+ __asm__ __volatile__ ("wbinvd": : :"memory") |
29491 |
+ |
29492 |
++#define pax_open_kernel(cr0) \ |
29493 |
++do { \ |
29494 |
++ typecheck(unsigned long, cr0); \ |
29495 |
++ preempt_disable(); \ |
29496 |
++ cr0 = read_cr0(); \ |
29497 |
++ write_cr0(cr0 & ~X86_CR0_WP); \ |
29498 |
++} while (0) |
29499 |
++ |
29500 |
++#define pax_close_kernel(cr0) \ |
29501 |
++do { \ |
29502 |
++ typecheck(unsigned long, cr0); \ |
29503 |
++ write_cr0(cr0); \ |
29504 |
++ preempt_enable_no_resched(); \ |
29505 |
++} while (0) |
29506 |
++ |
29507 |
+ #endif /* __KERNEL__ */ |
29508 |
+ |
29509 |
+ static inline void clflush(volatile void *__p) |
29510 |
+@@ -179,7 +198,7 @@ static inline void clflush(volatile void |
29511 |
+ |
29512 |
+ void cpu_idle_wait(void); |
29513 |
+ |
29514 |
+-extern unsigned long arch_align_stack(unsigned long sp); |
29515 |
++#define arch_align_stack(x) (x) |
29516 |
+ extern void free_init_pages(char *what, unsigned long begin, unsigned long end); |
29517 |
+ |
29518 |
+ #endif |
29519 |
+diff -urNp linux-2.6.24.4/include/asm-x86/uaccess_32.h linux-2.6.24.4/include/asm-x86/uaccess_32.h |
29520 |
+--- linux-2.6.24.4/include/asm-x86/uaccess_32.h 2008-03-24 14:49:18.000000000 -0400 |
29521 |
++++ linux-2.6.24.4/include/asm-x86/uaccess_32.h 2008-03-26 17:56:56.000000000 -0400 |
29522 |
+@@ -9,6 +9,7 @@ |
29523 |
+ #include <linux/prefetch.h> |
29524 |
+ #include <linux/string.h> |
29525 |
+ #include <asm/page.h> |
29526 |
++#include <asm/segment.h> |
29527 |
+ |
29528 |
+ #define VERIFY_READ 0 |
29529 |
+ #define VERIFY_WRITE 1 |
29530 |
+@@ -29,7 +30,8 @@ |
29531 |
+ |
29532 |
+ #define get_ds() (KERNEL_DS) |
29533 |
+ #define get_fs() (current_thread_info()->addr_limit) |
29534 |
+-#define set_fs(x) (current_thread_info()->addr_limit = (x)) |
29535 |
++void __set_fs(mm_segment_t x, int cpu); |
29536 |
++void set_fs(mm_segment_t x); |
29537 |
+ |
29538 |
+ #define segment_eq(a,b) ((a).seg == (b).seg) |
29539 |
+ |
29540 |
+@@ -101,6 +103,7 @@ struct exception_table_entry |
29541 |
+ }; |
29542 |
+ |
29543 |
+ extern int fixup_exception(struct pt_regs *regs); |
29544 |
++#define ARCH_HAS_SORT_EXTABLE |
29545 |
+ |
29546 |
+ /* |
29547 |
+ * These are the main single-value transfer routines. They automatically |
29548 |
+@@ -280,9 +283,12 @@ extern void __put_user_8(void); |
29549 |
+ |
29550 |
+ #define __put_user_u64(x, addr, err) \ |
29551 |
+ __asm__ __volatile__( \ |
29552 |
+- "1: movl %%eax,0(%2)\n" \ |
29553 |
+- "2: movl %%edx,4(%2)\n" \ |
29554 |
++ " movw %w5,%%ds\n" \ |
29555 |
++ "1: movl %%eax,%%ds:0(%2)\n" \ |
29556 |
++ "2: movl %%edx,%%ds:4(%2)\n" \ |
29557 |
+ "3:\n" \ |
29558 |
++ " pushl %%ss\n" \ |
29559 |
++ " popl %%ds\n" \ |
29560 |
+ ".section .fixup,\"ax\"\n" \ |
29561 |
+ "4: movl %3,%0\n" \ |
29562 |
+ " jmp 3b\n" \ |
29563 |
+@@ -293,7 +299,8 @@ extern void __put_user_8(void); |
29564 |
+ " .long 2b,4b\n" \ |
29565 |
+ ".previous" \ |
29566 |
+ : "=r"(err) \ |
29567 |
+- : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err)) |
29568 |
++ : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \ |
29569 |
++ "r"(__USER_DS)) |
29570 |
+ |
29571 |
+ #ifdef CONFIG_X86_WP_WORKS_OK |
29572 |
+ |
29573 |
+@@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu |
29574 |
+ */ |
29575 |
+ #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ |
29576 |
+ __asm__ __volatile__( \ |
29577 |
+- "1: mov"itype" %"rtype"1,%2\n" \ |
29578 |
++ " movw %w5,%%ds\n" \ |
29579 |
++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \ |
29580 |
+ "2:\n" \ |
29581 |
++ " pushl %%ss\n" \ |
29582 |
++ " popl %%ds\n" \ |
29583 |
+ ".section .fixup,\"ax\"\n" \ |
29584 |
+ "3: movl %3,%0\n" \ |
29585 |
+ " jmp 2b\n" \ |
29586 |
+@@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu |
29587 |
+ " .long 1b,3b\n" \ |
29588 |
+ ".previous" \ |
29589 |
+ : "=r"(err) \ |
29590 |
+- : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err)) |
29591 |
++ : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \ |
29592 |
++ "r"(__USER_DS)) |
29593 |
+ |
29594 |
+ |
29595 |
+ #define __get_user_nocheck(x,ptr,size) \ |
29596 |
+@@ -371,8 +382,11 @@ do { \ |
29597 |
+ |
29598 |
+ #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \ |
29599 |
+ __asm__ __volatile__( \ |
29600 |
+- "1: mov"itype" %2,%"rtype"1\n" \ |
29601 |
++ " movw %w5,%%ds\n" \ |
29602 |
++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \ |
29603 |
+ "2:\n" \ |
29604 |
++ " pushl %%ss\n" \ |
29605 |
++ " popl %%ds\n" \ |
29606 |
+ ".section .fixup,\"ax\"\n" \ |
29607 |
+ "3: movl %3,%0\n" \ |
29608 |
+ " xor"itype" %"rtype"1,%"rtype"1\n" \ |
29609 |
+@@ -383,7 +397,7 @@ do { \ |
29610 |
+ " .long 1b,3b\n" \ |
29611 |
+ ".previous" \ |
29612 |
+ : "=r"(err), ltype (x) \ |
29613 |
+- : "m"(__m(addr)), "i"(errret), "0"(err)) |
29614 |
++ : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS)) |
29615 |
+ |
29616 |
+ |
29617 |
+ unsigned long __must_check __copy_to_user_ll(void __user *to, |
29618 |
+diff -urNp linux-2.6.24.4/include/asm-x86/uaccess_64.h linux-2.6.24.4/include/asm-x86/uaccess_64.h |
29619 |
+--- linux-2.6.24.4/include/asm-x86/uaccess_64.h 2008-03-24 14:49:18.000000000 -0400 |
29620 |
++++ linux-2.6.24.4/include/asm-x86/uaccess_64.h 2008-03-26 17:56:56.000000000 -0400 |
29621 |
+@@ -66,6 +66,7 @@ struct exception_table_entry |
29622 |
+ }; |
29623 |
+ |
29624 |
+ #define ARCH_HAS_SEARCH_EXTABLE |
29625 |
++#define ARCH_HAS_SORT_EXTABLE |
29626 |
+ |
29627 |
+ /* |
29628 |
+ * These are the main single-value transfer routines. They automatically |
29629 |
+diff -urNp linux-2.6.24.4/include/asm-xtensa/kmap_types.h linux-2.6.24.4/include/asm-xtensa/kmap_types.h |
29630 |
+--- linux-2.6.24.4/include/asm-xtensa/kmap_types.h 2008-03-24 14:49:18.000000000 -0400 |
29631 |
++++ linux-2.6.24.4/include/asm-xtensa/kmap_types.h 2008-03-26 17:56:56.000000000 -0400 |
29632 |
+@@ -25,6 +25,7 @@ enum km_type { |
29633 |
+ KM_IRQ1, |
29634 |
+ KM_SOFTIRQ0, |
29635 |
+ KM_SOFTIRQ1, |
29636 |
++ KM_CLEARPAGE, |
29637 |
+ KM_TYPE_NR |
29638 |
+ }; |
29639 |
+ |
29640 |
+diff -urNp linux-2.6.24.4/include/linux/a.out.h linux-2.6.24.4/include/linux/a.out.h |
29641 |
+--- linux-2.6.24.4/include/linux/a.out.h 2008-03-24 14:49:18.000000000 -0400 |
29642 |
++++ linux-2.6.24.4/include/linux/a.out.h 2008-03-26 17:56:56.000000000 -0400 |
29643 |
+@@ -7,6 +7,16 @@ |
29644 |
+ |
29645 |
+ #include <asm/a.out.h> |
29646 |
+ |
29647 |
++#ifdef CONFIG_PAX_RANDUSTACK |
29648 |
++#define __DELTA_STACK (current->mm->delta_stack) |
29649 |
++#else |
29650 |
++#define __DELTA_STACK 0UL |
29651 |
++#endif |
29652 |
++ |
29653 |
++#ifndef STACK_TOP |
29654 |
++#define STACK_TOP (__STACK_TOP - __DELTA_STACK) |
29655 |
++#endif |
29656 |
++ |
29657 |
+ #endif /* __STRUCT_EXEC_OVERRIDE__ */ |
29658 |
+ |
29659 |
+ /* these go in the N_MACHTYPE field */ |
29660 |
+@@ -37,6 +47,14 @@ enum machine_type { |
29661 |
+ M_MIPS2 = 152 /* MIPS R6000/R4000 binary */ |
29662 |
+ }; |
29663 |
+ |
29664 |
++/* Constants for the N_FLAGS field */ |
29665 |
++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */ |
29666 |
++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */ |
29667 |
++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */ |
29668 |
++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */ |
29669 |
++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */ |
29670 |
++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */ |
29671 |
++ |
29672 |
+ #if !defined (N_MAGIC) |
29673 |
+ #define N_MAGIC(exec) ((exec).a_info & 0xffff) |
29674 |
+ #endif |
29675 |
+diff -urNp linux-2.6.24.4/include/linux/binfmts.h linux-2.6.24.4/include/linux/binfmts.h |
29676 |
+--- linux-2.6.24.4/include/linux/binfmts.h 2008-03-24 14:49:18.000000000 -0400 |
29677 |
++++ linux-2.6.24.4/include/linux/binfmts.h 2008-03-26 17:56:56.000000000 -0400 |
29678 |
+@@ -49,6 +49,7 @@ struct linux_binprm{ |
29679 |
+ unsigned interp_data; |
29680 |
+ unsigned long loader, exec; |
29681 |
+ unsigned long argv_len; |
29682 |
++ int misc; |
29683 |
+ }; |
29684 |
+ |
29685 |
+ #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 |
29686 |
+@@ -100,5 +101,8 @@ extern void compute_creds(struct linux_b |
29687 |
+ extern int do_coredump(long signr, int exit_code, struct pt_regs * regs); |
29688 |
+ extern int set_binfmt(struct linux_binfmt *new); |
29689 |
+ |
29690 |
++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp); |
29691 |
++void pax_report_insns(void *pc, void *sp); |
29692 |
++ |
29693 |
+ #endif /* __KERNEL__ */ |
29694 |
+ #endif /* _LINUX_BINFMTS_H */ |
29695 |
+diff -urNp linux-2.6.24.4/include/linux/cache.h linux-2.6.24.4/include/linux/cache.h |
29696 |
+--- linux-2.6.24.4/include/linux/cache.h 2008-03-24 14:49:18.000000000 -0400 |
29697 |
++++ linux-2.6.24.4/include/linux/cache.h 2008-03-26 17:56:56.000000000 -0400 |
29698 |
+@@ -16,6 +16,10 @@ |
29699 |
+ #define __read_mostly |
29700 |
+ #endif |
29701 |
+ |
29702 |
++#ifndef __read_only |
29703 |
++#define __read_only __read_mostly |
29704 |
++#endif |
29705 |
++ |
29706 |
+ #ifndef ____cacheline_aligned |
29707 |
+ #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES))) |
29708 |
+ #endif |
29709 |
+diff -urNp linux-2.6.24.4/include/linux/capability.h linux-2.6.24.4/include/linux/capability.h |
29710 |
+--- linux-2.6.24.4/include/linux/capability.h 2008-03-24 14:49:18.000000000 -0400 |
29711 |
++++ linux-2.6.24.4/include/linux/capability.h 2008-03-26 17:56:56.000000000 -0400 |
29712 |
+@@ -373,6 +373,7 @@ static inline kernel_cap_t cap_invert(ke |
29713 |
+ #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK) |
29714 |
+ |
29715 |
+ int capable(int cap); |
29716 |
++int capable_nolog(int cap); |
29717 |
+ int __capable(struct task_struct *t, int cap); |
29718 |
+ |
29719 |
+ #endif /* __KERNEL__ */ |
29720 |
+diff -urNp linux-2.6.24.4/include/linux/elf.h linux-2.6.24.4/include/linux/elf.h |
29721 |
+--- linux-2.6.24.4/include/linux/elf.h 2008-03-24 14:49:18.000000000 -0400 |
29722 |
++++ linux-2.6.24.4/include/linux/elf.h 2008-03-26 17:56:56.000000000 -0400 |
29723 |
+@@ -7,6 +7,10 @@ |
29724 |
+ |
29725 |
+ struct file; |
29726 |
+ |
29727 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
29728 |
++#undef elf_read_implies_exec |
29729 |
++#endif |
29730 |
++ |
29731 |
+ #ifndef elf_read_implies_exec |
29732 |
+ /* Executables for which elf_read_implies_exec() returns TRUE will |
29733 |
+ have the READ_IMPLIES_EXEC personality flag set automatically. |
29734 |
+@@ -48,6 +52,16 @@ typedef __s64 Elf64_Sxword; |
29735 |
+ |
29736 |
+ #define PT_GNU_STACK (PT_LOOS + 0x474e551) |
29737 |
+ |
29738 |
++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580) |
29739 |
++ |
29740 |
++/* Constants for the e_flags field */ |
29741 |
++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */ |
29742 |
++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */ |
29743 |
++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */ |
29744 |
++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */ |
29745 |
++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */ |
29746 |
++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */ |
29747 |
++ |
29748 |
+ /* These constants define the different elf file types */ |
29749 |
+ #define ET_NONE 0 |
29750 |
+ #define ET_REL 1 |
29751 |
+@@ -82,6 +96,8 @@ typedef __s64 Elf64_Sxword; |
29752 |
+ #define DT_DEBUG 21 |
29753 |
+ #define DT_TEXTREL 22 |
29754 |
+ #define DT_JMPREL 23 |
29755 |
++#define DT_FLAGS 30 |
29756 |
++ #define DF_TEXTREL 0x00000004 |
29757 |
+ #define DT_ENCODING 32 |
29758 |
+ #define OLD_DT_LOOS 0x60000000 |
29759 |
+ #define DT_LOOS 0x6000000d |
29760 |
+@@ -228,6 +244,19 @@ typedef struct elf64_hdr { |
29761 |
+ #define PF_W 0x2 |
29762 |
+ #define PF_X 0x1 |
29763 |
+ |
29764 |
++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */ |
29765 |
++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */ |
29766 |
++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */ |
29767 |
++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */ |
29768 |
++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */ |
29769 |
++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */ |
29770 |
++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */ |
29771 |
++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */ |
29772 |
++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */ |
29773 |
++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */ |
29774 |
++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */ |
29775 |
++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */ |
29776 |
++ |
29777 |
+ typedef struct elf32_phdr{ |
29778 |
+ Elf32_Word p_type; |
29779 |
+ Elf32_Off p_offset; |
29780 |
+@@ -320,6 +349,8 @@ typedef struct elf64_shdr { |
29781 |
+ #define EI_OSABI 7 |
29782 |
+ #define EI_PAD 8 |
29783 |
+ |
29784 |
++#define EI_PAX 14 |
29785 |
++ |
29786 |
+ #define ELFMAG0 0x7f /* EI_MAG */ |
29787 |
+ #define ELFMAG1 'E' |
29788 |
+ #define ELFMAG2 'L' |
29789 |
+@@ -378,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC []; |
29790 |
+ #define elf_phdr elf32_phdr |
29791 |
+ #define elf_note elf32_note |
29792 |
+ #define elf_addr_t Elf32_Off |
29793 |
++#define elf_dyn Elf32_Dyn |
29794 |
+ |
29795 |
+ #else |
29796 |
+ |
29797 |
+@@ -386,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC []; |
29798 |
+ #define elf_phdr elf64_phdr |
29799 |
+ #define elf_note elf64_note |
29800 |
+ #define elf_addr_t Elf64_Off |
29801 |
++#define elf_dyn Elf64_Dyn |
29802 |
+ |
29803 |
+ #endif |
29804 |
+ |
29805 |
+diff -urNp linux-2.6.24.4/include/linux/ext4_fs_extents.h linux-2.6.24.4/include/linux/ext4_fs_extents.h |
29806 |
+--- linux-2.6.24.4/include/linux/ext4_fs_extents.h 2008-03-24 14:49:18.000000000 -0400 |
29807 |
++++ linux-2.6.24.4/include/linux/ext4_fs_extents.h 2008-03-26 17:56:56.000000000 -0400 |
29808 |
+@@ -50,7 +50,7 @@ |
29809 |
+ #ifdef EXT_DEBUG |
29810 |
+ #define ext_debug(a...) printk(a) |
29811 |
+ #else |
29812 |
+-#define ext_debug(a...) |
29813 |
++#define ext_debug(a...) do {} while (0) |
29814 |
+ #endif |
29815 |
+ |
29816 |
+ /* |
29817 |
+diff -urNp linux-2.6.24.4/include/linux/gracl.h linux-2.6.24.4/include/linux/gracl.h |
29818 |
+--- linux-2.6.24.4/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500 |
29819 |
++++ linux-2.6.24.4/include/linux/gracl.h 2008-03-26 17:56:56.000000000 -0400 |
29820 |
+@@ -0,0 +1,317 @@ |
29821 |
++#ifndef GR_ACL_H |
29822 |
++#define GR_ACL_H |
29823 |
++ |
29824 |
++#include <linux/grdefs.h> |
29825 |
++#include <linux/resource.h> |
29826 |
++#include <linux/dcache.h> |
29827 |
++#include <asm/resource.h> |
29828 |
++ |
29829 |
++/* Major status information */ |
29830 |
++ |
29831 |
++#define GR_VERSION "grsecurity 2.1.11" |
29832 |
++#define GRSECURITY_VERSION 0x2111 |
29833 |
++ |
29834 |
++enum { |
29835 |
++ |
29836 |
++ SHUTDOWN = 0, |
29837 |
++ ENABLE = 1, |
29838 |
++ SPROLE = 2, |
29839 |
++ RELOAD = 3, |
29840 |
++ SEGVMOD = 4, |
29841 |
++ STATUS = 5, |
29842 |
++ UNSPROLE = 6, |
29843 |
++ PASSSET = 7, |
29844 |
++ SPROLEPAM = 8 |
29845 |
++}; |
29846 |
++ |
29847 |
++/* Password setup definitions |
29848 |
++ * kernel/grhash.c */ |
29849 |
++enum { |
29850 |
++ GR_PW_LEN = 128, |
29851 |
++ GR_SALT_LEN = 16, |
29852 |
++ GR_SHA_LEN = 32, |
29853 |
++}; |
29854 |
++ |
29855 |
++enum { |
29856 |
++ GR_SPROLE_LEN = 64, |
29857 |
++}; |
29858 |
++ |
29859 |
++#define GR_NLIMITS (RLIMIT_LOCKS + 2) |
29860 |
++ |
29861 |
++/* Begin Data Structures */ |
29862 |
++ |
29863 |
++struct sprole_pw { |
29864 |
++ unsigned char *rolename; |
29865 |
++ unsigned char salt[GR_SALT_LEN]; |
29866 |
++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */ |
29867 |
++}; |
29868 |
++ |
29869 |
++struct name_entry { |
29870 |
++ __u32 key; |
29871 |
++ ino_t inode; |
29872 |
++ dev_t device; |
29873 |
++ char *name; |
29874 |
++ __u16 len; |
29875 |
++ __u8 deleted; |
29876 |
++ struct name_entry *prev; |
29877 |
++ struct name_entry *next; |
29878 |
++}; |
29879 |
++ |
29880 |
++struct inodev_entry { |
29881 |
++ struct name_entry *nentry; |
29882 |
++ struct inodev_entry *prev; |
29883 |
++ struct inodev_entry *next; |
29884 |
++}; |
29885 |
++ |
29886 |
++struct acl_role_db { |
29887 |
++ struct acl_role_label **r_hash; |
29888 |
++ __u32 r_size; |
29889 |
++}; |
29890 |
++ |
29891 |
++struct inodev_db { |
29892 |
++ struct inodev_entry **i_hash; |
29893 |
++ __u32 i_size; |
29894 |
++}; |
29895 |
++ |
29896 |
++struct name_db { |
29897 |
++ struct name_entry **n_hash; |
29898 |
++ __u32 n_size; |
29899 |
++}; |
29900 |
++ |
29901 |
++struct crash_uid { |
29902 |
++ uid_t uid; |
29903 |
++ unsigned long expires; |
29904 |
++}; |
29905 |
++ |
29906 |
++struct gr_hash_struct { |
29907 |
++ void **table; |
29908 |
++ void **nametable; |
29909 |
++ void *first; |
29910 |
++ __u32 table_size; |
29911 |
++ __u32 used_size; |
29912 |
++ int type; |
29913 |
++}; |
29914 |
++ |
29915 |
++/* Userspace Grsecurity ACL data structures */ |
29916 |
++ |
29917 |
++struct acl_subject_label { |
29918 |
++ char *filename; |
29919 |
++ ino_t inode; |
29920 |
++ dev_t device; |
29921 |
++ __u32 mode; |
29922 |
++ __u32 cap_mask; |
29923 |
++ __u32 cap_lower; |
29924 |
++ |
29925 |
++ struct rlimit res[GR_NLIMITS]; |
29926 |
++ __u16 resmask; |
29927 |
++ |
29928 |
++ __u8 user_trans_type; |
29929 |
++ __u8 group_trans_type; |
29930 |
++ uid_t *user_transitions; |
29931 |
++ gid_t *group_transitions; |
29932 |
++ __u16 user_trans_num; |
29933 |
++ __u16 group_trans_num; |
29934 |
++ |
29935 |
++ __u32 ip_proto[8]; |
29936 |
++ __u32 ip_type; |
29937 |
++ struct acl_ip_label **ips; |
29938 |
++ __u32 ip_num; |
29939 |
++ |
29940 |
++ __u32 crashes; |
29941 |
++ unsigned long expires; |
29942 |
++ |
29943 |
++ struct acl_subject_label *parent_subject; |
29944 |
++ struct gr_hash_struct *hash; |
29945 |
++ struct acl_subject_label *prev; |
29946 |
++ struct acl_subject_label *next; |
29947 |
++ |
29948 |
++ struct acl_object_label **obj_hash; |
29949 |
++ __u32 obj_hash_size; |
29950 |
++ __u16 pax_flags; |
29951 |
++}; |
29952 |
++ |
29953 |
++struct role_allowed_ip { |
29954 |
++ __u32 addr; |
29955 |
++ __u32 netmask; |
29956 |
++ |
29957 |
++ struct role_allowed_ip *prev; |
29958 |
++ struct role_allowed_ip *next; |
29959 |
++}; |
29960 |
++ |
29961 |
++struct role_transition { |
29962 |
++ char *rolename; |
29963 |
++ |
29964 |
++ struct role_transition *prev; |
29965 |
++ struct role_transition *next; |
29966 |
++}; |
29967 |
++ |
29968 |
++struct acl_role_label { |
29969 |
++ char *rolename; |
29970 |
++ uid_t uidgid; |
29971 |
++ __u16 roletype; |
29972 |
++ |
29973 |
++ __u16 auth_attempts; |
29974 |
++ unsigned long expires; |
29975 |
++ |
29976 |
++ struct acl_subject_label *root_label; |
29977 |
++ struct gr_hash_struct *hash; |
29978 |
++ |
29979 |
++ struct acl_role_label *prev; |
29980 |
++ struct acl_role_label *next; |
29981 |
++ |
29982 |
++ struct role_transition *transitions; |
29983 |
++ struct role_allowed_ip *allowed_ips; |
29984 |
++ uid_t *domain_children; |
29985 |
++ __u16 domain_child_num; |
29986 |
++ |
29987 |
++ struct acl_subject_label **subj_hash; |
29988 |
++ __u32 subj_hash_size; |
29989 |
++}; |
29990 |
++ |
29991 |
++struct user_acl_role_db { |
29992 |
++ struct acl_role_label **r_table; |
29993 |
++ __u32 num_pointers; /* Number of allocations to track */ |
29994 |
++ __u32 num_roles; /* Number of roles */ |
29995 |
++ __u32 num_domain_children; /* Number of domain children */ |
29996 |
++ __u32 num_subjects; /* Number of subjects */ |
29997 |
++ __u32 num_objects; /* Number of objects */ |
29998 |
++}; |
29999 |
++ |
30000 |
++struct acl_object_label { |
30001 |
++ char *filename; |
30002 |
++ ino_t inode; |
30003 |
++ dev_t device; |
30004 |
++ __u32 mode; |
30005 |
++ |
30006 |
++ struct acl_subject_label *nested; |
30007 |
++ struct acl_object_label *globbed; |
30008 |
++ |
30009 |
++ /* next two structures not used */ |
30010 |
++ |
30011 |
++ struct acl_object_label *prev; |
30012 |
++ struct acl_object_label *next; |
30013 |
++}; |
30014 |
++ |
30015 |
++struct acl_ip_label { |
30016 |
++ char *iface; |
30017 |
++ __u32 addr; |
30018 |
++ __u32 netmask; |
30019 |
++ __u16 low, high; |
30020 |
++ __u8 mode; |
30021 |
++ __u32 type; |
30022 |
++ __u32 proto[8]; |
30023 |
++ |
30024 |
++ /* next two structures not used */ |
30025 |
++ |
30026 |
++ struct acl_ip_label *prev; |
30027 |
++ struct acl_ip_label *next; |
30028 |
++}; |
30029 |
++ |
30030 |
++struct gr_arg { |
30031 |
++ struct user_acl_role_db role_db; |
30032 |
++ unsigned char pw[GR_PW_LEN]; |
30033 |
++ unsigned char salt[GR_SALT_LEN]; |
30034 |
++ unsigned char sum[GR_SHA_LEN]; |
30035 |
++ unsigned char sp_role[GR_SPROLE_LEN]; |
30036 |
++ struct sprole_pw *sprole_pws; |
30037 |
++ dev_t segv_device; |
30038 |
++ ino_t segv_inode; |
30039 |
++ uid_t segv_uid; |
30040 |
++ __u16 num_sprole_pws; |
30041 |
++ __u16 mode; |
30042 |
++}; |
30043 |
++ |
30044 |
++struct gr_arg_wrapper { |
30045 |
++ struct gr_arg *arg; |
30046 |
++ __u32 version; |
30047 |
++ __u32 size; |
30048 |
++}; |
30049 |
++ |
30050 |
++struct subject_map { |
30051 |
++ struct acl_subject_label *user; |
30052 |
++ struct acl_subject_label *kernel; |
30053 |
++ struct subject_map *prev; |
30054 |
++ struct subject_map *next; |
30055 |
++}; |
30056 |
++ |
30057 |
++struct acl_subj_map_db { |
30058 |
++ struct subject_map **s_hash; |
30059 |
++ __u32 s_size; |
30060 |
++}; |
30061 |
++ |
30062 |
++/* End Data Structures Section */ |
30063 |
++ |
30064 |
++/* Hash functions generated by empirical testing by Brad Spengler |
30065 |
++ Makes good use of the low bits of the inode. Generally 0-1 times |
30066 |
++ in loop for successful match. 0-3 for unsuccessful match. |
30067 |
++ Shift/add algorithm with modulus of table size and an XOR*/ |
30068 |
++ |
30069 |
++static __inline__ unsigned int |
30070 |
++rhash(const uid_t uid, const __u16 type, const unsigned int sz) |
30071 |
++{ |
30072 |
++ return (((uid << type) + (uid ^ type)) % sz); |
30073 |
++} |
30074 |
++ |
30075 |
++ static __inline__ unsigned int |
30076 |
++shash(const struct acl_subject_label *userp, const unsigned int sz) |
30077 |
++{ |
30078 |
++ return ((const unsigned long)userp % sz); |
30079 |
++} |
30080 |
++ |
30081 |
++static __inline__ unsigned int |
30082 |
++fhash(const ino_t ino, const dev_t dev, const unsigned int sz) |
30083 |
++{ |
30084 |
++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz); |
30085 |
++} |
30086 |
++ |
30087 |
++static __inline__ unsigned int |
30088 |
++nhash(const char *name, const __u16 len, const unsigned int sz) |
30089 |
++{ |
30090 |
++ return full_name_hash(name, len) % sz; |
30091 |
++} |
30092 |
++ |
30093 |
++#define FOR_EACH_ROLE_START(role,iter) \ |
30094 |
++ role = NULL; \ |
30095 |
++ iter = 0; \ |
30096 |
++ while (iter < acl_role_set.r_size) { \ |
30097 |
++ if (role == NULL) \ |
30098 |
++ role = acl_role_set.r_hash[iter]; \ |
30099 |
++ if (role == NULL) { \ |
30100 |
++ iter++; \ |
30101 |
++ continue; \ |
30102 |
++ } |
30103 |
++ |
30104 |
++#define FOR_EACH_ROLE_END(role,iter) \ |
30105 |
++ role = role->next; \ |
30106 |
++ if (role == NULL) \ |
30107 |
++ iter++; \ |
30108 |
++ } |
30109 |
++ |
30110 |
++#define FOR_EACH_SUBJECT_START(role,subj,iter) \ |
30111 |
++ subj = NULL; \ |
30112 |
++ iter = 0; \ |
30113 |
++ while (iter < role->subj_hash_size) { \ |
30114 |
++ if (subj == NULL) \ |
30115 |
++ subj = role->subj_hash[iter]; \ |
30116 |
++ if (subj == NULL) { \ |
30117 |
++ iter++; \ |
30118 |
++ continue; \ |
30119 |
++ } |
30120 |
++ |
30121 |
++#define FOR_EACH_SUBJECT_END(subj,iter) \ |
30122 |
++ subj = subj->next; \ |
30123 |
++ if (subj == NULL) \ |
30124 |
++ iter++; \ |
30125 |
++ } |
30126 |
++ |
30127 |
++ |
30128 |
++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \ |
30129 |
++ subj = role->hash->first; \ |
30130 |
++ while (subj != NULL) { |
30131 |
++ |
30132 |
++#define FOR_EACH_NESTED_SUBJECT_END(subj) \ |
30133 |
++ subj = subj->next; \ |
30134 |
++ } |
30135 |
++ |
30136 |
++#endif |
30137 |
++ |
30138 |
+diff -urNp linux-2.6.24.4/include/linux/gralloc.h linux-2.6.24.4/include/linux/gralloc.h |
30139 |
+--- linux-2.6.24.4/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500 |
30140 |
++++ linux-2.6.24.4/include/linux/gralloc.h 2008-03-26 17:56:56.000000000 -0400 |
30141 |
+@@ -0,0 +1,8 @@ |
30142 |
++#ifndef __GRALLOC_H |
30143 |
++#define __GRALLOC_H |
30144 |
++ |
30145 |
++void acl_free_all(void); |
30146 |
++int acl_alloc_stack_init(unsigned long size); |
30147 |
++void *acl_alloc(unsigned long len); |
30148 |
++ |
30149 |
++#endif |
30150 |
+diff -urNp linux-2.6.24.4/include/linux/grdefs.h linux-2.6.24.4/include/linux/grdefs.h |
30151 |
+--- linux-2.6.24.4/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500 |
30152 |
++++ linux-2.6.24.4/include/linux/grdefs.h 2008-03-26 17:56:56.000000000 -0400 |
30153 |
+@@ -0,0 +1,131 @@ |
30154 |
++#ifndef GRDEFS_H |
30155 |
++#define GRDEFS_H |
30156 |
++ |
30157 |
++/* Begin grsecurity status declarations */ |
30158 |
++ |
30159 |
++enum { |
30160 |
++ GR_READY = 0x01, |
30161 |
++ GR_STATUS_INIT = 0x00 // disabled state |
30162 |
++}; |
30163 |
++ |
30164 |
++/* Begin ACL declarations */ |
30165 |
++ |
30166 |
++/* Role flags */ |
30167 |
++ |
30168 |
++enum { |
30169 |
++ GR_ROLE_USER = 0x0001, |
30170 |
++ GR_ROLE_GROUP = 0x0002, |
30171 |
++ GR_ROLE_DEFAULT = 0x0004, |
30172 |
++ GR_ROLE_SPECIAL = 0x0008, |
30173 |
++ GR_ROLE_AUTH = 0x0010, |
30174 |
++ GR_ROLE_NOPW = 0x0020, |
30175 |
++ GR_ROLE_GOD = 0x0040, |
30176 |
++ GR_ROLE_LEARN = 0x0080, |
30177 |
++ GR_ROLE_TPE = 0x0100, |
30178 |
++ GR_ROLE_DOMAIN = 0x0200, |
30179 |
++ GR_ROLE_PAM = 0x0400 |
30180 |
++}; |
30181 |
++ |
30182 |
++/* ACL Subject and Object mode flags */ |
30183 |
++enum { |
30184 |
++ GR_DELETED = 0x80000000 |
30185 |
++}; |
30186 |
++ |
30187 |
++/* ACL Object-only mode flags */ |
30188 |
++enum { |
30189 |
++ GR_READ = 0x00000001, |
30190 |
++ GR_APPEND = 0x00000002, |
30191 |
++ GR_WRITE = 0x00000004, |
30192 |
++ GR_EXEC = 0x00000008, |
30193 |
++ GR_FIND = 0x00000010, |
30194 |
++ GR_INHERIT = 0x00000020, |
30195 |
++ GR_SETID = 0x00000040, |
30196 |
++ GR_CREATE = 0x00000080, |
30197 |
++ GR_DELETE = 0x00000100, |
30198 |
++ GR_LINK = 0x00000200, |
30199 |
++ GR_AUDIT_READ = 0x00000400, |
30200 |
++ GR_AUDIT_APPEND = 0x00000800, |
30201 |
++ GR_AUDIT_WRITE = 0x00001000, |
30202 |
++ GR_AUDIT_EXEC = 0x00002000, |
30203 |
++ GR_AUDIT_FIND = 0x00004000, |
30204 |
++ GR_AUDIT_INHERIT= 0x00008000, |
30205 |
++ GR_AUDIT_SETID = 0x00010000, |
30206 |
++ GR_AUDIT_CREATE = 0x00020000, |
30207 |
++ GR_AUDIT_DELETE = 0x00040000, |
30208 |
++ GR_AUDIT_LINK = 0x00080000, |
30209 |
++ GR_PTRACERD = 0x00100000, |
30210 |
++ GR_NOPTRACE = 0x00200000, |
30211 |
++ GR_SUPPRESS = 0x00400000, |
30212 |
++ GR_NOLEARN = 0x00800000 |
30213 |
++}; |
30214 |
++ |
30215 |
++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \ |
30216 |
++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \ |
30217 |
++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK) |
30218 |
++ |
30219 |
++/* ACL subject-only mode flags */ |
30220 |
++enum { |
30221 |
++ GR_KILL = 0x00000001, |
30222 |
++ GR_VIEW = 0x00000002, |
30223 |
++ GR_PROTECTED = 0x00000004, |
30224 |
++ GR_LEARN = 0x00000008, |
30225 |
++ GR_OVERRIDE = 0x00000010, |
30226 |
++ /* just a placeholder, this mode is only used in userspace */ |
30227 |
++ GR_DUMMY = 0x00000020, |
30228 |
++ GR_PROTSHM = 0x00000040, |
30229 |
++ GR_KILLPROC = 0x00000080, |
30230 |
++ GR_KILLIPPROC = 0x00000100, |
30231 |
++ /* just a placeholder, this mode is only used in userspace */ |
30232 |
++ GR_NOTROJAN = 0x00000200, |
30233 |
++ GR_PROTPROCFD = 0x00000400, |
30234 |
++ GR_PROCACCT = 0x00000800, |
30235 |
++ GR_RELAXPTRACE = 0x00001000, |
30236 |
++ GR_NESTED = 0x00002000, |
30237 |
++ GR_INHERITLEARN = 0x00004000, |
30238 |
++ GR_PROCFIND = 0x00008000, |
30239 |
++ GR_POVERRIDE = 0x00010000, |
30240 |
++ GR_KERNELAUTH = 0x00020000, |
30241 |
++}; |
30242 |
++ |
30243 |
++enum { |
30244 |
++ GR_PAX_ENABLE_SEGMEXEC = 0x0001, |
30245 |
++ GR_PAX_ENABLE_PAGEEXEC = 0x0002, |
30246 |
++ GR_PAX_ENABLE_MPROTECT = 0x0004, |
30247 |
++ GR_PAX_ENABLE_RANDMMAP = 0x0008, |
30248 |
++ GR_PAX_ENABLE_EMUTRAMP = 0x0010, |
30249 |
++ GR_PAX_DISABLE_SEGMEXEC = 0x0100, |
30250 |
++ GR_PAX_DISABLE_PAGEEXEC = 0x0200, |
30251 |
++ GR_PAX_DISABLE_MPROTECT = 0x0400, |
30252 |
++ GR_PAX_DISABLE_RANDMMAP = 0x0800, |
30253 |
++ GR_PAX_DISABLE_EMUTRAMP = 0x1000, |
30254 |
++}; |
30255 |
++ |
30256 |
++enum { |
30257 |
++ GR_ID_USER = 0x01, |
30258 |
++ GR_ID_GROUP = 0x02, |
30259 |
++}; |
30260 |
++ |
30261 |
++enum { |
30262 |
++ GR_ID_ALLOW = 0x01, |
30263 |
++ GR_ID_DENY = 0x02, |
30264 |
++}; |
30265 |
++ |
30266 |
++#define GR_CRASH_RES 11 |
30267 |
++#define GR_UIDTABLE_MAX 500 |
30268 |
++ |
30269 |
++/* begin resource learning section */ |
30270 |
++enum { |
30271 |
++ GR_RLIM_CPU_BUMP = 60, |
30272 |
++ GR_RLIM_FSIZE_BUMP = 50000, |
30273 |
++ GR_RLIM_DATA_BUMP = 10000, |
30274 |
++ GR_RLIM_STACK_BUMP = 1000, |
30275 |
++ GR_RLIM_CORE_BUMP = 10000, |
30276 |
++ GR_RLIM_RSS_BUMP = 500000, |
30277 |
++ GR_RLIM_NPROC_BUMP = 1, |
30278 |
++ GR_RLIM_NOFILE_BUMP = 5, |
30279 |
++ GR_RLIM_MEMLOCK_BUMP = 50000, |
30280 |
++ GR_RLIM_AS_BUMP = 500000, |
30281 |
++ GR_RLIM_LOCKS_BUMP = 2 |
30282 |
++}; |
30283 |
++ |
30284 |
++#endif |
30285 |
+diff -urNp linux-2.6.24.4/include/linux/grinternal.h linux-2.6.24.4/include/linux/grinternal.h |
30286 |
+--- linux-2.6.24.4/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500 |
30287 |
++++ linux-2.6.24.4/include/linux/grinternal.h 2008-03-26 17:56:56.000000000 -0400 |
30288 |
+@@ -0,0 +1,210 @@ |
30289 |
++#ifndef __GRINTERNAL_H |
30290 |
++#define __GRINTERNAL_H |
30291 |
++ |
30292 |
++#ifdef CONFIG_GRKERNSEC |
30293 |
++ |
30294 |
++#include <linux/fs.h> |
30295 |
++#include <linux/gracl.h> |
30296 |
++#include <linux/grdefs.h> |
30297 |
++#include <linux/grmsg.h> |
30298 |
++ |
30299 |
++void gr_add_learn_entry(const char *fmt, ...); |
30300 |
++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode, |
30301 |
++ const struct vfsmount *mnt); |
30302 |
++__u32 gr_check_create(const struct dentry *new_dentry, |
30303 |
++ const struct dentry *parent, |
30304 |
++ const struct vfsmount *mnt, const __u32 mode); |
30305 |
++int gr_check_protected_task(const struct task_struct *task); |
30306 |
++__u32 to_gr_audit(const __u32 reqmode); |
30307 |
++int gr_set_acls(const int type); |
30308 |
++ |
30309 |
++int gr_acl_is_enabled(void); |
30310 |
++char gr_roletype_to_char(void); |
30311 |
++ |
30312 |
++void gr_handle_alertkill(struct task_struct *task); |
30313 |
++char *gr_to_filename(const struct dentry *dentry, |
30314 |
++ const struct vfsmount *mnt); |
30315 |
++char *gr_to_filename1(const struct dentry *dentry, |
30316 |
++ const struct vfsmount *mnt); |
30317 |
++char *gr_to_filename2(const struct dentry *dentry, |
30318 |
++ const struct vfsmount *mnt); |
30319 |
++char *gr_to_filename3(const struct dentry *dentry, |
30320 |
++ const struct vfsmount *mnt); |
30321 |
++ |
30322 |
++extern int grsec_enable_link; |
30323 |
++extern int grsec_enable_fifo; |
30324 |
++extern int grsec_enable_execve; |
30325 |
++extern int grsec_enable_shm; |
30326 |
++extern int grsec_enable_execlog; |
30327 |
++extern int grsec_enable_signal; |
30328 |
++extern int grsec_enable_forkfail; |
30329 |
++extern int grsec_enable_time; |
30330 |
++extern int grsec_enable_chroot_shmat; |
30331 |
++extern int grsec_enable_chroot_findtask; |
30332 |
++extern int grsec_enable_chroot_mount; |
30333 |
++extern int grsec_enable_chroot_double; |
30334 |
++extern int grsec_enable_chroot_pivot; |
30335 |
++extern int grsec_enable_chroot_chdir; |
30336 |
++extern int grsec_enable_chroot_chmod; |
30337 |
++extern int grsec_enable_chroot_mknod; |
30338 |
++extern int grsec_enable_chroot_fchdir; |
30339 |
++extern int grsec_enable_chroot_nice; |
30340 |
++extern int grsec_enable_chroot_execlog; |
30341 |
++extern int grsec_enable_chroot_caps; |
30342 |
++extern int grsec_enable_chroot_sysctl; |
30343 |
++extern int grsec_enable_chroot_unix; |
30344 |
++extern int grsec_enable_tpe; |
30345 |
++extern int grsec_tpe_gid; |
30346 |
++extern int grsec_enable_tpe_all; |
30347 |
++extern int grsec_enable_sidcaps; |
30348 |
++extern int grsec_enable_socket_all; |
30349 |
++extern int grsec_socket_all_gid; |
30350 |
++extern int grsec_enable_socket_client; |
30351 |
++extern int grsec_socket_client_gid; |
30352 |
++extern int grsec_enable_socket_server; |
30353 |
++extern int grsec_socket_server_gid; |
30354 |
++extern int grsec_audit_gid; |
30355 |
++extern int grsec_enable_group; |
30356 |
++extern int grsec_enable_audit_ipc; |
30357 |
++extern int grsec_enable_audit_textrel; |
30358 |
++extern int grsec_enable_mount; |
30359 |
++extern int grsec_enable_chdir; |
30360 |
++extern int grsec_resource_logging; |
30361 |
++extern int grsec_lock; |
30362 |
++ |
30363 |
++extern spinlock_t grsec_alert_lock; |
30364 |
++extern unsigned long grsec_alert_wtime; |
30365 |
++extern unsigned long grsec_alert_fyet; |
30366 |
++ |
30367 |
++extern spinlock_t grsec_audit_lock; |
30368 |
++ |
30369 |
++extern rwlock_t grsec_exec_file_lock; |
30370 |
++ |
30371 |
++#define gr_task_fullpath(tsk) (tsk->exec_file ? \ |
30372 |
++ gr_to_filename2(tsk->exec_file->f_dentry, \ |
30373 |
++ tsk->exec_file->f_vfsmnt) : "/") |
30374 |
++ |
30375 |
++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \ |
30376 |
++ gr_to_filename3(tsk->parent->exec_file->f_dentry, \ |
30377 |
++ tsk->parent->exec_file->f_vfsmnt) : "/") |
30378 |
++ |
30379 |
++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \ |
30380 |
++ gr_to_filename(tsk->exec_file->f_dentry, \ |
30381 |
++ tsk->exec_file->f_vfsmnt) : "/") |
30382 |
++ |
30383 |
++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \ |
30384 |
++ gr_to_filename1(tsk->parent->exec_file->f_dentry, \ |
30385 |
++ tsk->parent->exec_file->f_vfsmnt) : "/") |
30386 |
++ |
30387 |
++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \ |
30388 |
++ ((tsk_a->fs->root->d_inode->i_sb->s_dev != \ |
30389 |
++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root->d_inode->i_sb->s_dev) || \ |
30390 |
++ (tsk_a->fs->root->d_inode->i_ino != \ |
30391 |
++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root->d_inode->i_ino))) |
30392 |
++ |
30393 |
++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \ |
30394 |
++ (tsk_a->fs->root->d_inode->i_sb->s_dev == \ |
30395 |
++ tsk_b->fs->root->d_inode->i_sb->s_dev) && \ |
30396 |
++ (tsk_a->fs->root->d_inode->i_ino == \ |
30397 |
++ tsk_b->fs->root->d_inode->i_ino)) |
30398 |
++ |
30399 |
++#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \ |
30400 |
++ task->pid, task->uid, \ |
30401 |
++ task->euid, task->gid, task->egid, \ |
30402 |
++ gr_parent_task_fullpath(task), \ |
30403 |
++ task->parent->comm, task->parent->pid, \ |
30404 |
++ task->parent->uid, task->parent->euid, \ |
30405 |
++ task->parent->gid, task->parent->egid |
30406 |
++ |
30407 |
++#define GR_CHROOT_CAPS ( \ |
30408 |
++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \ |
30409 |
++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \ |
30410 |
++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \ |
30411 |
++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \ |
30412 |
++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \ |
30413 |
++ CAP_TO_MASK(CAP_IPC_OWNER)) |
30414 |
++ |
30415 |
++#define security_learn(normal_msg,args...) \ |
30416 |
++({ \ |
30417 |
++ read_lock(&grsec_exec_file_lock); \ |
30418 |
++ gr_add_learn_entry(normal_msg "\n", ## args); \ |
30419 |
++ read_unlock(&grsec_exec_file_lock); \ |
30420 |
++}) |
30421 |
++ |
30422 |
++enum { |
30423 |
++ GR_DO_AUDIT, |
30424 |
++ GR_DONT_AUDIT, |
30425 |
++ GR_DONT_AUDIT_GOOD |
30426 |
++}; |
30427 |
++ |
30428 |
++enum { |
30429 |
++ GR_TTYSNIFF, |
30430 |
++ GR_RBAC, |
30431 |
++ GR_RBAC_STR, |
30432 |
++ GR_STR_RBAC, |
30433 |
++ GR_RBAC_MODE2, |
30434 |
++ GR_RBAC_MODE3, |
30435 |
++ GR_FILENAME, |
30436 |
++ GR_SYSCTL_HIDDEN, |
30437 |
++ GR_NOARGS, |
30438 |
++ GR_ONE_INT, |
30439 |
++ GR_ONE_INT_TWO_STR, |
30440 |
++ GR_ONE_STR, |
30441 |
++ GR_STR_INT, |
30442 |
++ GR_TWO_INT, |
30443 |
++ GR_THREE_INT, |
30444 |
++ GR_FIVE_INT_TWO_STR, |
30445 |
++ GR_TWO_STR, |
30446 |
++ GR_THREE_STR, |
30447 |
++ GR_FOUR_STR, |
30448 |
++ GR_STR_FILENAME, |
30449 |
++ GR_FILENAME_STR, |
30450 |
++ GR_FILENAME_TWO_INT, |
30451 |
++ GR_FILENAME_TWO_INT_STR, |
30452 |
++ GR_TEXTREL, |
30453 |
++ GR_PTRACE, |
30454 |
++ GR_RESOURCE, |
30455 |
++ GR_CAP, |
30456 |
++ GR_SIG, |
30457 |
++ GR_CRASH1, |
30458 |
++ GR_CRASH2, |
30459 |
++ GR_PSACCT |
30460 |
++}; |
30461 |
++ |
30462 |
++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str) |
30463 |
++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task) |
30464 |
++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt) |
30465 |
++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str) |
30466 |
++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt) |
30467 |
++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2) |
30468 |
++#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) |
30469 |
++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt) |
30470 |
++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS) |
30471 |
++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num) |
30472 |
++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2) |
30473 |
++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str) |
30474 |
++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num) |
30475 |
++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2) |
30476 |
++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3) |
30477 |
++#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) |
30478 |
++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2) |
30479 |
++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3) |
30480 |
++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4) |
30481 |
++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt) |
30482 |
++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str) |
30483 |
++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2) |
30484 |
++#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) |
30485 |
++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2) |
30486 |
++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task) |
30487 |
++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2) |
30488 |
++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str) |
30489 |
++#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num) |
30490 |
++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong) |
30491 |
++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1) |
30492 |
++#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) |
30493 |
++ |
30494 |
++void gr_log_varargs(int audit, const char *msg, int argtypes, ...); |
30495 |
++ |
30496 |
++#endif |
30497 |
++ |
30498 |
++#endif |
30499 |
+diff -urNp linux-2.6.24.4/include/linux/grmsg.h linux-2.6.24.4/include/linux/grmsg.h |
30500 |
+--- linux-2.6.24.4/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500 |
30501 |
++++ linux-2.6.24.4/include/linux/grmsg.h 2008-03-26 17:56:56.000000000 -0400 |
30502 |
+@@ -0,0 +1,108 @@ |
30503 |
++#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" |
30504 |
++#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" |
30505 |
++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " |
30506 |
++#define GR_STOPMOD_MSG "denied modification of module state by " |
30507 |
++#define GR_IOPERM_MSG "denied use of ioperm() by " |
30508 |
++#define GR_IOPL_MSG "denied use of iopl() by " |
30509 |
++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " |
30510 |
++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by " |
30511 |
++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " |
30512 |
++#define GR_KMEM_MSG "denied write of /dev/kmem by " |
30513 |
++#define GR_PORT_OPEN_MSG "denied open of /dev/port by " |
30514 |
++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by " |
30515 |
++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by " |
30516 |
++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " |
30517 |
++#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" |
30518 |
++#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" |
30519 |
++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " |
30520 |
++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " |
30521 |
++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " |
30522 |
++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " |
30523 |
++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by " |
30524 |
++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " |
30525 |
++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by " |
30526 |
++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against " |
30527 |
++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " |
30528 |
++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " |
30529 |
++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " |
30530 |
++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " |
30531 |
++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " |
30532 |
++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " |
30533 |
++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " |
30534 |
++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " |
30535 |
++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " |
30536 |
++#define GR_NPROC_MSG "denied overstep of process limit by " |
30537 |
++#define GR_EXEC_ACL_MSG "%s execution of %.950s by " |
30538 |
++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " |
30539 |
++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds" |
30540 |
++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds" |
30541 |
++#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by " |
30542 |
++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by " |
30543 |
++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " |
30544 |
++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " |
30545 |
++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " |
30546 |
++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by " |
30547 |
++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " |
30548 |
++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by " |
30549 |
++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " |
30550 |
++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by " |
30551 |
++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " |
30552 |
++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " |
30553 |
++#define GR_INITF_ACL_MSG "init_variables() failed %s by " |
30554 |
++#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" |
30555 |
++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by " |
30556 |
++#define GR_SHUTS_ACL_MSG "shutdown auth success for " |
30557 |
++#define GR_SHUTF_ACL_MSG "shutdown auth failure for " |
30558 |
++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " |
30559 |
++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " |
30560 |
++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " |
30561 |
++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " |
30562 |
++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by " |
30563 |
++#define GR_ENABLEF_ACL_MSG "unable to load %s for " |
30564 |
++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system" |
30565 |
++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by " |
30566 |
++#define GR_RELOADF_ACL_MSG "failed reload of %s for " |
30567 |
++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for " |
30568 |
++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " |
30569 |
++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " |
30570 |
++#define GR_SPROLEF_ACL_MSG "special role %s failure for " |
30571 |
++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for " |
30572 |
++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " |
30573 |
++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " |
30574 |
++#define GR_INVMODE_ACL_MSG "invalid mode %d by " |
30575 |
++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by " |
30576 |
++#define GR_FAILFORK_MSG "failed fork with errno %d by " |
30577 |
++#define GR_NICE_CHROOT_MSG "denied priority change by " |
30578 |
++#define GR_UNISIGLOG_MSG "signal %d sent to " |
30579 |
++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " |
30580 |
++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by " |
30581 |
++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by " |
30582 |
++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " |
30583 |
++#define GR_TIME_MSG "time set by " |
30584 |
++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by " |
30585 |
++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " |
30586 |
++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " |
30587 |
++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by " |
30588 |
++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by " |
30589 |
++#define GR_BIND_MSG "denied bind() by " |
30590 |
++#define GR_CONNECT_MSG "denied connect() by " |
30591 |
++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " |
30592 |
++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " |
30593 |
++#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" |
30594 |
++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " |
30595 |
++#define GR_CAP_ACL_MSG "use of %s denied for " |
30596 |
++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for " |
30597 |
++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for " |
30598 |
++#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " |
30599 |
++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " |
30600 |
++#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by " |
30601 |
++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " |
30602 |
++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by " |
30603 |
++#define GR_MSGQ_AUDIT_MSG "message queue created by " |
30604 |
++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by " |
30605 |
++#define GR_SEM_AUDIT_MSG "semaphore created by " |
30606 |
++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by " |
30607 |
++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " |
30608 |
++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by " |
30609 |
++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for " |
30610 |
++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by " |
30611 |
+diff -urNp linux-2.6.24.4/include/linux/grsecurity.h linux-2.6.24.4/include/linux/grsecurity.h |
30612 |
+--- linux-2.6.24.4/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500 |
30613 |
++++ linux-2.6.24.4/include/linux/grsecurity.h 2008-03-26 17:56:56.000000000 -0400 |
30614 |
+@@ -0,0 +1,197 @@ |
30615 |
++#ifndef GR_SECURITY_H |
30616 |
++#define GR_SECURITY_H |
30617 |
++#include <linux/fs.h> |
30618 |
++#include <linux/binfmts.h> |
30619 |
++#include <linux/gracl.h> |
30620 |
++ |
30621 |
++/* notify of brain-dead configs */ |
30622 |
++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) |
30623 |
++#error "CONFIG_PAX_NOEXEC enabled, but neither PAGEEXEC nor SEGMEXEC are enabled." |
30624 |
++#endif |
30625 |
++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS) |
30626 |
++#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled." |
30627 |
++#endif |
30628 |
++#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP) |
30629 |
++#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled." |
30630 |
++#endif |
30631 |
++#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR) |
30632 |
++#error "CONFIG_PAX enabled, but no PaX options are enabled." |
30633 |
++#endif |
30634 |
++ |
30635 |
++void gr_handle_brute_attach(struct task_struct *p); |
30636 |
++void gr_handle_brute_check(void); |
30637 |
++ |
30638 |
++char gr_roletype_to_char(void); |
30639 |
++ |
30640 |
++int gr_check_user_change(int real, int effective, int fs); |
30641 |
++int gr_check_group_change(int real, int effective, int fs); |
30642 |
++ |
30643 |
++void gr_del_task_from_ip_table(struct task_struct *p); |
30644 |
++ |
30645 |
++int gr_pid_is_chrooted(struct task_struct *p); |
30646 |
++int gr_handle_chroot_nice(void); |
30647 |
++int gr_handle_chroot_sysctl(const int op); |
30648 |
++int gr_handle_chroot_setpriority(struct task_struct *p, |
30649 |
++ const int niceval); |
30650 |
++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt); |
30651 |
++int gr_handle_chroot_chroot(const struct dentry *dentry, |
30652 |
++ const struct vfsmount *mnt); |
30653 |
++void gr_handle_chroot_caps(struct task_struct *task); |
30654 |
++void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt); |
30655 |
++int gr_handle_chroot_chmod(const struct dentry *dentry, |
30656 |
++ const struct vfsmount *mnt, const int mode); |
30657 |
++int gr_handle_chroot_mknod(const struct dentry *dentry, |
30658 |
++ const struct vfsmount *mnt, const int mode); |
30659 |
++int gr_handle_chroot_mount(const struct dentry *dentry, |
30660 |
++ const struct vfsmount *mnt, |
30661 |
++ const char *dev_name); |
30662 |
++int gr_handle_chroot_pivot(void); |
30663 |
++int gr_handle_chroot_unix(const pid_t pid); |
30664 |
++ |
30665 |
++int gr_handle_rawio(const struct inode *inode); |
30666 |
++int gr_handle_nproc(void); |
30667 |
++ |
30668 |
++void gr_handle_ioperm(void); |
30669 |
++void gr_handle_iopl(void); |
30670 |
++ |
30671 |
++int gr_tpe_allow(const struct file *file); |
30672 |
++ |
30673 |
++int gr_random_pid(void); |
30674 |
++ |
30675 |
++void gr_log_forkfail(const int retval); |
30676 |
++void gr_log_timechange(void); |
30677 |
++void gr_log_signal(const int sig, const struct task_struct *t); |
30678 |
++void gr_log_chdir(const struct dentry *dentry, |
30679 |
++ const struct vfsmount *mnt); |
30680 |
++void gr_log_chroot_exec(const struct dentry *dentry, |
30681 |
++ const struct vfsmount *mnt); |
30682 |
++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv); |
30683 |
++void gr_log_remount(const char *devname, const int retval); |
30684 |
++void gr_log_unmount(const char *devname, const int retval); |
30685 |
++void gr_log_mount(const char *from, const char *to, const int retval); |
30686 |
++void gr_log_msgget(const int ret, const int msgflg); |
30687 |
++void gr_log_msgrm(const uid_t uid, const uid_t cuid); |
30688 |
++void gr_log_semget(const int err, const int semflg); |
30689 |
++void gr_log_semrm(const uid_t uid, const uid_t cuid); |
30690 |
++void gr_log_shmget(const int err, const int shmflg, const size_t size); |
30691 |
++void gr_log_shmrm(const uid_t uid, const uid_t cuid); |
30692 |
++void gr_log_textrel(struct vm_area_struct *vma); |
30693 |
++ |
30694 |
++int gr_handle_follow_link(const struct inode *parent, |
30695 |
++ const struct inode *inode, |
30696 |
++ const struct dentry *dentry, |
30697 |
++ const struct vfsmount *mnt); |
30698 |
++int gr_handle_fifo(const struct dentry *dentry, |
30699 |
++ const struct vfsmount *mnt, |
30700 |
++ const struct dentry *dir, const int flag, |
30701 |
++ const int acc_mode); |
30702 |
++int gr_handle_hardlink(const struct dentry *dentry, |
30703 |
++ const struct vfsmount *mnt, |
30704 |
++ struct inode *inode, |
30705 |
++ const int mode, const char *to); |
30706 |
++ |
30707 |
++int gr_task_is_capable(struct task_struct *task, const int cap); |
30708 |
++int gr_is_capable_nolog(const int cap); |
30709 |
++void gr_learn_resource(const struct task_struct *task, const int limit, |
30710 |
++ const unsigned long wanted, const int gt); |
30711 |
++void gr_copy_label(struct task_struct *tsk); |
30712 |
++void gr_handle_crash(struct task_struct *task, const int sig); |
30713 |
++int gr_handle_signal(const struct task_struct *p, const int sig); |
30714 |
++int gr_check_crash_uid(const uid_t uid); |
30715 |
++int gr_check_protected_task(const struct task_struct *task); |
30716 |
++int gr_acl_handle_mmap(const struct file *file, |
30717 |
++ const unsigned long prot); |
30718 |
++int gr_acl_handle_mprotect(const struct file *file, |
30719 |
++ const unsigned long prot); |
30720 |
++int gr_check_hidden_task(const struct task_struct *tsk); |
30721 |
++__u32 gr_acl_handle_truncate(const struct dentry *dentry, |
30722 |
++ const struct vfsmount *mnt); |
30723 |
++__u32 gr_acl_handle_utime(const struct dentry *dentry, |
30724 |
++ const struct vfsmount *mnt); |
30725 |
++__u32 gr_acl_handle_access(const struct dentry *dentry, |
30726 |
++ const struct vfsmount *mnt, const int fmode); |
30727 |
++__u32 gr_acl_handle_fchmod(const struct dentry *dentry, |
30728 |
++ const struct vfsmount *mnt, mode_t mode); |
30729 |
++__u32 gr_acl_handle_chmod(const struct dentry *dentry, |
30730 |
++ const struct vfsmount *mnt, mode_t mode); |
30731 |
++__u32 gr_acl_handle_chown(const struct dentry *dentry, |
30732 |
++ const struct vfsmount *mnt); |
30733 |
++int gr_handle_ptrace(struct task_struct *task, const long request); |
30734 |
++int gr_handle_proc_ptrace(struct task_struct *task); |
30735 |
++__u32 gr_acl_handle_execve(const struct dentry *dentry, |
30736 |
++ const struct vfsmount *mnt); |
30737 |
++int gr_check_crash_exec(const struct file *filp); |
30738 |
++int gr_acl_is_enabled(void); |
30739 |
++void gr_set_kernel_label(struct task_struct *task); |
30740 |
++void gr_set_role_label(struct task_struct *task, const uid_t uid, |
30741 |
++ const gid_t gid); |
30742 |
++int gr_set_proc_label(const struct dentry *dentry, |
30743 |
++ const struct vfsmount *mnt); |
30744 |
++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry, |
30745 |
++ const struct vfsmount *mnt); |
30746 |
++__u32 gr_acl_handle_open(const struct dentry *dentry, |
30747 |
++ const struct vfsmount *mnt, const int fmode); |
30748 |
++__u32 gr_acl_handle_creat(const struct dentry *dentry, |
30749 |
++ const struct dentry *p_dentry, |
30750 |
++ const struct vfsmount *p_mnt, const int fmode, |
30751 |
++ const int imode); |
30752 |
++void gr_handle_create(const struct dentry *dentry, |
30753 |
++ const struct vfsmount *mnt); |
30754 |
++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry, |
30755 |
++ const struct dentry *parent_dentry, |
30756 |
++ const struct vfsmount *parent_mnt, |
30757 |
++ const int mode); |
30758 |
++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry, |
30759 |
++ const struct dentry *parent_dentry, |
30760 |
++ const struct vfsmount *parent_mnt); |
30761 |
++__u32 gr_acl_handle_rmdir(const struct dentry *dentry, |
30762 |
++ const struct vfsmount *mnt); |
30763 |
++void gr_handle_delete(const ino_t ino, const dev_t dev); |
30764 |
++__u32 gr_acl_handle_unlink(const struct dentry *dentry, |
30765 |
++ const struct vfsmount *mnt); |
30766 |
++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry, |
30767 |
++ const struct dentry *parent_dentry, |
30768 |
++ const struct vfsmount *parent_mnt, |
30769 |
++ const char *from); |
30770 |
++__u32 gr_acl_handle_link(const struct dentry *new_dentry, |
30771 |
++ const struct dentry *parent_dentry, |
30772 |
++ const struct vfsmount *parent_mnt, |
30773 |
++ const struct dentry *old_dentry, |
30774 |
++ const struct vfsmount *old_mnt, const char *to); |
30775 |
++int gr_acl_handle_rename(struct dentry *new_dentry, |
30776 |
++ struct dentry *parent_dentry, |
30777 |
++ const struct vfsmount *parent_mnt, |
30778 |
++ struct dentry *old_dentry, |
30779 |
++ struct inode *old_parent_inode, |
30780 |
++ struct vfsmount *old_mnt, const char *newname); |
30781 |
++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir, |
30782 |
++ struct dentry *old_dentry, |
30783 |
++ struct dentry *new_dentry, |
30784 |
++ struct vfsmount *mnt, const __u8 replace); |
30785 |
++__u32 gr_check_link(const struct dentry *new_dentry, |
30786 |
++ const struct dentry *parent_dentry, |
30787 |
++ const struct vfsmount *parent_mnt, |
30788 |
++ const struct dentry *old_dentry, |
30789 |
++ const struct vfsmount *old_mnt); |
30790 |
++int gr_acl_handle_filldir(const struct file *file, const char *name, |
30791 |
++ const unsigned int namelen, const ino_t ino); |
30792 |
++ |
30793 |
++__u32 gr_acl_handle_unix(const struct dentry *dentry, |
30794 |
++ const struct vfsmount *mnt); |
30795 |
++void gr_acl_handle_exit(void); |
30796 |
++void gr_acl_handle_psacct(struct task_struct *task, const long code); |
30797 |
++int gr_acl_handle_procpidmem(const struct task_struct *task); |
30798 |
++ |
30799 |
++#ifdef CONFIG_GRKERNSEC |
30800 |
++void gr_handle_mem_write(void); |
30801 |
++void gr_handle_kmem_write(void); |
30802 |
++void gr_handle_open_port(void); |
30803 |
++int gr_handle_mem_mmap(const unsigned long offset, |
30804 |
++ struct vm_area_struct *vma); |
30805 |
++ |
30806 |
++extern int grsec_enable_dmesg; |
30807 |
++extern int grsec_enable_randsrc; |
30808 |
++extern int grsec_enable_shm; |
30809 |
++#endif |
30810 |
++ |
30811 |
++#endif |
30812 |
+diff -urNp linux-2.6.24.4/include/linux/highmem.h linux-2.6.24.4/include/linux/highmem.h |
30813 |
+--- linux-2.6.24.4/include/linux/highmem.h 2008-03-24 14:49:18.000000000 -0400 |
30814 |
++++ linux-2.6.24.4/include/linux/highmem.h 2008-03-26 17:56:56.000000000 -0400 |
30815 |
+@@ -124,6 +124,13 @@ static inline void clear_highpage(struct |
30816 |
+ kunmap_atomic(kaddr, KM_USER0); |
30817 |
+ } |
30818 |
+ |
30819 |
++static inline void sanitize_highpage(struct page *page) |
30820 |
++{ |
30821 |
++ void *kaddr = kmap_atomic(page, KM_CLEARPAGE); |
30822 |
++ clear_page(kaddr); |
30823 |
++ kunmap_atomic(kaddr, KM_CLEARPAGE); |
30824 |
++} |
30825 |
++ |
30826 |
+ /* |
30827 |
+ * Same but also flushes aliased cache contents to RAM. |
30828 |
+ * |
30829 |
+@@ -132,14 +139,14 @@ static inline void clear_highpage(struct |
30830 |
+ */ |
30831 |
+ #define zero_user_page(page, offset, size, km_type) \ |
30832 |
+ do { \ |
30833 |
+- void *kaddr; \ |
30834 |
++ void *__kaddr; \ |
30835 |
+ \ |
30836 |
+ BUG_ON((offset) + (size) > PAGE_SIZE); \ |
30837 |
+ \ |
30838 |
+- kaddr = kmap_atomic(page, km_type); \ |
30839 |
+- memset((char *)kaddr + (offset), 0, (size)); \ |
30840 |
++ __kaddr = kmap_atomic(page, km_type); \ |
30841 |
++ memset((char *)__kaddr + (offset), 0, (size)); \ |
30842 |
+ flush_dcache_page(page); \ |
30843 |
+- kunmap_atomic(kaddr, (km_type)); \ |
30844 |
++ kunmap_atomic(__kaddr, (km_type)); \ |
30845 |
+ } while (0) |
30846 |
+ |
30847 |
+ static inline void __deprecated memclear_highpage_flush(struct page *page, |
30848 |
+diff -urNp linux-2.6.24.4/include/linux/init_task.h linux-2.6.24.4/include/linux/init_task.h |
30849 |
+--- linux-2.6.24.4/include/linux/init_task.h 2008-03-24 14:49:18.000000000 -0400 |
30850 |
++++ linux-2.6.24.4/include/linux/init_task.h 2008-03-26 17:56:56.000000000 -0400 |
30851 |
+@@ -121,7 +121,7 @@ extern struct group_info init_groups; |
30852 |
+ #define INIT_TASK(tsk) \ |
30853 |
+ { \ |
30854 |
+ .state = 0, \ |
30855 |
+- .stack = &init_thread_info, \ |
30856 |
++ .stack = &init_thread_union, \ |
30857 |
+ .usage = ATOMIC_INIT(2), \ |
30858 |
+ .flags = 0, \ |
30859 |
+ .lock_depth = -1, \ |
30860 |
+diff -urNp linux-2.6.24.4/include/linux/irqflags.h linux-2.6.24.4/include/linux/irqflags.h |
30861 |
+--- linux-2.6.24.4/include/linux/irqflags.h 2008-03-24 14:49:18.000000000 -0400 |
30862 |
++++ linux-2.6.24.4/include/linux/irqflags.h 2008-03-26 17:56:56.000000000 -0400 |
30863 |
+@@ -84,10 +84,10 @@ |
30864 |
+ |
30865 |
+ #define irqs_disabled() \ |
30866 |
+ ({ \ |
30867 |
+- unsigned long flags; \ |
30868 |
++ unsigned long __flags; \ |
30869 |
+ \ |
30870 |
+- raw_local_save_flags(flags); \ |
30871 |
+- raw_irqs_disabled_flags(flags); \ |
30872 |
++ raw_local_save_flags(__flags); \ |
30873 |
++ raw_irqs_disabled_flags(__flags); \ |
30874 |
+ }) |
30875 |
+ |
30876 |
+ #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) |
30877 |
+diff -urNp linux-2.6.24.4/include/linux/jbd2.h linux-2.6.24.4/include/linux/jbd2.h |
30878 |
+--- linux-2.6.24.4/include/linux/jbd2.h 2008-03-24 14:49:18.000000000 -0400 |
30879 |
++++ linux-2.6.24.4/include/linux/jbd2.h 2008-03-26 17:56:56.000000000 -0400 |
30880 |
+@@ -68,7 +68,7 @@ extern u8 jbd2_journal_enable_debug; |
30881 |
+ } \ |
30882 |
+ } while (0) |
30883 |
+ #else |
30884 |
+-#define jbd_debug(f, a...) /**/ |
30885 |
++#define jbd_debug(f, a...) do {} while (0) |
30886 |
+ #endif |
30887 |
+ |
30888 |
+ static inline void *jbd2_alloc(size_t size, gfp_t flags) |
30889 |
+diff -urNp linux-2.6.24.4/include/linux/jbd.h linux-2.6.24.4/include/linux/jbd.h |
30890 |
+--- linux-2.6.24.4/include/linux/jbd.h 2008-03-24 14:49:18.000000000 -0400 |
30891 |
++++ linux-2.6.24.4/include/linux/jbd.h 2008-03-26 17:56:56.000000000 -0400 |
30892 |
+@@ -69,7 +69,7 @@ extern u8 journal_enable_debug; |
30893 |
+ } \ |
30894 |
+ } while (0) |
30895 |
+ #else |
30896 |
+-#define jbd_debug(f, a...) /**/ |
30897 |
++#define jbd_debug(f, a...) do {} while (0) |
30898 |
+ #endif |
30899 |
+ |
30900 |
+ static inline void *jbd_alloc(size_t size, gfp_t flags) |
30901 |
+diff -urNp linux-2.6.24.4/include/linux/libata.h linux-2.6.24.4/include/linux/libata.h |
30902 |
+--- linux-2.6.24.4/include/linux/libata.h 2008-03-24 14:49:18.000000000 -0400 |
30903 |
++++ linux-2.6.24.4/include/linux/libata.h 2008-03-26 17:56:56.000000000 -0400 |
30904 |
+@@ -62,11 +62,11 @@ |
30905 |
+ #ifdef ATA_VERBOSE_DEBUG |
30906 |
+ #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) |
30907 |
+ #else |
30908 |
+-#define VPRINTK(fmt, args...) |
30909 |
++#define VPRINTK(fmt, args...) do {} while (0) |
30910 |
+ #endif /* ATA_VERBOSE_DEBUG */ |
30911 |
+ #else |
30912 |
+-#define DPRINTK(fmt, args...) |
30913 |
+-#define VPRINTK(fmt, args...) |
30914 |
++#define DPRINTK(fmt, args...) do {} while (0) |
30915 |
++#define VPRINTK(fmt, args...) do {} while (0) |
30916 |
+ #endif /* ATA_DEBUG */ |
30917 |
+ |
30918 |
+ #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) |
30919 |
+diff -urNp linux-2.6.24.4/include/linux/mm.h linux-2.6.24.4/include/linux/mm.h |
30920 |
+--- linux-2.6.24.4/include/linux/mm.h 2008-03-24 14:49:18.000000000 -0400 |
30921 |
++++ linux-2.6.24.4/include/linux/mm.h 2008-03-26 17:56:56.000000000 -0400 |
30922 |
+@@ -37,6 +37,7 @@ extern int sysctl_legacy_va_layout; |
30923 |
+ #include <asm/page.h> |
30924 |
+ #include <asm/pgtable.h> |
30925 |
+ #include <asm/processor.h> |
30926 |
++#include <asm/mman.h> |
30927 |
+ |
30928 |
+ #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) |
30929 |
+ |
30930 |
+@@ -107,6 +108,14 @@ extern unsigned int kobjsize(const void |
30931 |
+ |
30932 |
+ #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */ |
30933 |
+ |
30934 |
++#ifdef CONFIG_PAX_PAGEEXEC |
30935 |
++#define VM_PAGEEXEC 0x10000000 /* vma->vm_page_prot needs special handling */ |
30936 |
++#endif |
30937 |
++ |
30938 |
++#ifdef CONFIG_PAX_MPROTECT |
30939 |
++#define VM_MAYNOTWRITE 0x20000000 /* vma cannot be granted VM_WRITE any more */ |
30940 |
++#endif |
30941 |
++ |
30942 |
+ #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ |
30943 |
+ #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS |
30944 |
+ #endif |
30945 |
+@@ -792,6 +801,8 @@ struct shrinker { |
30946 |
+ extern void register_shrinker(struct shrinker *); |
30947 |
+ extern void unregister_shrinker(struct shrinker *); |
30948 |
+ |
30949 |
++pgprot_t vm_get_page_prot(unsigned long vm_flags); |
30950 |
++ |
30951 |
+ int vma_wants_writenotify(struct vm_area_struct *vma); |
30952 |
+ |
30953 |
+ extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)); |
30954 |
+@@ -1018,6 +1029,7 @@ out: |
30955 |
+ } |
30956 |
+ |
30957 |
+ extern int do_munmap(struct mm_struct *, unsigned long, size_t); |
30958 |
++extern int __do_munmap(struct mm_struct *, unsigned long, size_t); |
30959 |
+ |
30960 |
+ extern unsigned long do_brk(unsigned long, unsigned long); |
30961 |
+ |
30962 |
+@@ -1070,6 +1082,10 @@ extern struct vm_area_struct * find_vma( |
30963 |
+ extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr, |
30964 |
+ struct vm_area_struct **pprev); |
30965 |
+ |
30966 |
++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma); |
30967 |
++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma); |
30968 |
++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl); |
30969 |
++ |
30970 |
+ /* Look up the first VMA which intersects the interval start_addr..end_addr-1, |
30971 |
+ NULL if none. Assume start_addr < end_addr. */ |
30972 |
+ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr) |
30973 |
+@@ -1086,7 +1102,6 @@ static inline unsigned long vma_pages(st |
30974 |
+ return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
30975 |
+ } |
30976 |
+ |
30977 |
+-pgprot_t vm_get_page_prot(unsigned long vm_flags); |
30978 |
+ struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr); |
30979 |
+ struct page *vmalloc_to_page(void *addr); |
30980 |
+ unsigned long vmalloc_to_pfn(void *addr); |
30981 |
+@@ -1157,5 +1172,11 @@ int vmemmap_populate_basepages(struct pa |
30982 |
+ unsigned long pages, int node); |
30983 |
+ int vmemmap_populate(struct page *start_page, unsigned long pages, int node); |
30984 |
+ |
30985 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
30986 |
++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot); |
30987 |
++#else |
30988 |
++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {} |
30989 |
++#endif |
30990 |
++ |
30991 |
+ #endif /* __KERNEL__ */ |
30992 |
+ #endif /* _LINUX_MM_H */ |
30993 |
+diff -urNp linux-2.6.24.4/include/linux/mm_types.h linux-2.6.24.4/include/linux/mm_types.h |
30994 |
+--- linux-2.6.24.4/include/linux/mm_types.h 2008-03-24 14:49:18.000000000 -0400 |
30995 |
++++ linux-2.6.24.4/include/linux/mm_types.h 2008-03-26 17:56:56.000000000 -0400 |
30996 |
+@@ -151,6 +151,8 @@ struct vm_area_struct { |
30997 |
+ #ifdef CONFIG_NUMA |
30998 |
+ struct mempolicy *vm_policy; /* NUMA policy for the VMA */ |
30999 |
+ #endif |
31000 |
++ |
31001 |
++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */ |
31002 |
+ }; |
31003 |
+ |
31004 |
+ struct mm_struct { |
31005 |
+@@ -219,6 +221,24 @@ struct mm_struct { |
31006 |
+ /* aio bits */ |
31007 |
+ rwlock_t ioctx_list_lock; |
31008 |
+ struct kioctx *ioctx_list; |
31009 |
++ |
31010 |
++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
31011 |
++ unsigned long pax_flags; |
31012 |
++#endif |
31013 |
++ |
31014 |
++#ifdef CONFIG_PAX_DLRESOLVE |
31015 |
++ unsigned long call_dl_resolve; |
31016 |
++#endif |
31017 |
++ |
31018 |
++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT) |
31019 |
++ unsigned long call_syscall; |
31020 |
++#endif |
31021 |
++ |
31022 |
++#ifdef CONFIG_PAX_ASLR |
31023 |
++ unsigned long delta_mmap; /* randomized offset */ |
31024 |
++ unsigned long delta_stack; /* randomized offset */ |
31025 |
++#endif |
31026 |
++ |
31027 |
+ }; |
31028 |
+ |
31029 |
+ #endif /* _LINUX_MM_TYPES_H */ |
31030 |
+diff -urNp linux-2.6.24.4/include/linux/module.h linux-2.6.24.4/include/linux/module.h |
31031 |
+--- linux-2.6.24.4/include/linux/module.h 2008-03-24 14:49:18.000000000 -0400 |
31032 |
++++ linux-2.6.24.4/include/linux/module.h 2008-03-26 17:56:56.000000000 -0400 |
31033 |
+@@ -296,16 +296,16 @@ struct module |
31034 |
+ int (*init)(void); |
31035 |
+ |
31036 |
+ /* If this is non-NULL, vfree after init() returns */ |
31037 |
+- void *module_init; |
31038 |
++ void *module_init_rx, *module_init_rw; |
31039 |
+ |
31040 |
+ /* Here is the actual code + data, vfree'd on unload. */ |
31041 |
+- void *module_core; |
31042 |
++ void *module_core_rx, *module_core_rw; |
31043 |
+ |
31044 |
+ /* Here are the sizes of the init and core sections */ |
31045 |
+- unsigned long init_size, core_size; |
31046 |
++ unsigned long init_size_rw, core_size_rw; |
31047 |
+ |
31048 |
+ /* The size of the executable code in each section. */ |
31049 |
+- unsigned long init_text_size, core_text_size; |
31050 |
++ unsigned long init_size_rx, core_size_rx; |
31051 |
+ |
31052 |
+ /* The handle returned from unwind_add_table. */ |
31053 |
+ void *unwind_info; |
31054 |
+diff -urNp linux-2.6.24.4/include/linux/moduleloader.h linux-2.6.24.4/include/linux/moduleloader.h |
31055 |
+--- linux-2.6.24.4/include/linux/moduleloader.h 2008-03-24 14:49:18.000000000 -0400 |
31056 |
++++ linux-2.6.24.4/include/linux/moduleloader.h 2008-03-26 17:56:56.000000000 -0400 |
31057 |
+@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr * |
31058 |
+ sections. Returns NULL on failure. */ |
31059 |
+ void *module_alloc(unsigned long size); |
31060 |
+ |
31061 |
++#ifdef CONFIG_PAX_KERNEXEC |
31062 |
++void *module_alloc_exec(unsigned long size); |
31063 |
++#else |
31064 |
++#define module_alloc_exec(x) module_alloc(x) |
31065 |
++#endif |
31066 |
++ |
31067 |
+ /* Free memory returned from module_alloc. */ |
31068 |
+ void module_free(struct module *mod, void *module_region); |
31069 |
+ |
31070 |
++#ifdef CONFIG_PAX_KERNEXEC |
31071 |
++void module_free_exec(struct module *mod, void *module_region); |
31072 |
++#else |
31073 |
++#define module_free_exec(x, y) module_free(x, y) |
31074 |
++#endif |
31075 |
++ |
31076 |
+ /* Apply the given relocation to the (simplified) ELF. Return -error |
31077 |
+ or 0. */ |
31078 |
+ int apply_relocate(Elf_Shdr *sechdrs, |
31079 |
+diff -urNp linux-2.6.24.4/include/linux/namei.h linux-2.6.24.4/include/linux/namei.h |
31080 |
+--- linux-2.6.24.4/include/linux/namei.h 2008-03-24 14:49:18.000000000 -0400 |
31081 |
++++ linux-2.6.24.4/include/linux/namei.h 2008-03-26 17:56:56.000000000 -0400 |
31082 |
+@@ -21,7 +21,7 @@ struct nameidata { |
31083 |
+ unsigned int flags; |
31084 |
+ int last_type; |
31085 |
+ unsigned depth; |
31086 |
+- char *saved_names[MAX_NESTED_LINKS + 1]; |
31087 |
++ const char *saved_names[MAX_NESTED_LINKS + 1]; |
31088 |
+ |
31089 |
+ /* Intent data */ |
31090 |
+ union { |
31091 |
+@@ -90,12 +90,12 @@ extern int follow_up(struct vfsmount **, |
31092 |
+ extern struct dentry *lock_rename(struct dentry *, struct dentry *); |
31093 |
+ extern void unlock_rename(struct dentry *, struct dentry *); |
31094 |
+ |
31095 |
+-static inline void nd_set_link(struct nameidata *nd, char *path) |
31096 |
++static inline void nd_set_link(struct nameidata *nd, const char *path) |
31097 |
+ { |
31098 |
+ nd->saved_names[nd->depth] = path; |
31099 |
+ } |
31100 |
+ |
31101 |
+-static inline char *nd_get_link(struct nameidata *nd) |
31102 |
++static inline const char *nd_get_link(struct nameidata *nd) |
31103 |
+ { |
31104 |
+ return nd->saved_names[nd->depth]; |
31105 |
+ } |
31106 |
+diff -urNp linux-2.6.24.4/include/linux/percpu.h linux-2.6.24.4/include/linux/percpu.h |
31107 |
+--- linux-2.6.24.4/include/linux/percpu.h 2008-03-24 14:49:18.000000000 -0400 |
31108 |
++++ linux-2.6.24.4/include/linux/percpu.h 2008-03-26 17:56:56.000000000 -0400 |
31109 |
+@@ -18,7 +18,7 @@ |
31110 |
+ #endif |
31111 |
+ |
31112 |
+ #define PERCPU_ENOUGH_ROOM \ |
31113 |
+- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE) |
31114 |
++ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)) |
31115 |
+ #endif /* PERCPU_ENOUGH_ROOM */ |
31116 |
+ |
31117 |
+ /* |
31118 |
+diff -urNp linux-2.6.24.4/include/linux/poison.h linux-2.6.24.4/include/linux/poison.h |
31119 |
+--- linux-2.6.24.4/include/linux/poison.h 2008-03-24 14:49:18.000000000 -0400 |
31120 |
++++ linux-2.6.24.4/include/linux/poison.h 2008-03-26 17:56:56.000000000 -0400 |
31121 |
+@@ -7,8 +7,8 @@ |
31122 |
+ * under normal circumstances, used to verify that nobody uses |
31123 |
+ * non-initialized list entries. |
31124 |
+ */ |
31125 |
+-#define LIST_POISON1 ((void *) 0x00100100) |
31126 |
+-#define LIST_POISON2 ((void *) 0x00200200) |
31127 |
++#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL) |
31128 |
++#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL) |
31129 |
+ |
31130 |
+ /********** mm/slab.c **********/ |
31131 |
+ /* |
31132 |
+diff -urNp linux-2.6.24.4/include/linux/random.h linux-2.6.24.4/include/linux/random.h |
31133 |
+--- linux-2.6.24.4/include/linux/random.h 2008-03-24 14:49:18.000000000 -0400 |
31134 |
++++ linux-2.6.24.4/include/linux/random.h 2008-03-26 17:56:56.000000000 -0400 |
31135 |
+@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l |
31136 |
+ u32 random32(void); |
31137 |
+ void srandom32(u32 seed); |
31138 |
+ |
31139 |
++static inline unsigned long pax_get_random_long(void) |
31140 |
++{ |
31141 |
++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0); |
31142 |
++} |
31143 |
++ |
31144 |
+ #endif /* __KERNEL___ */ |
31145 |
+ |
31146 |
+ #endif /* _LINUX_RANDOM_H */ |
31147 |
+diff -urNp linux-2.6.24.4/include/linux/sched.h linux-2.6.24.4/include/linux/sched.h |
31148 |
+--- linux-2.6.24.4/include/linux/sched.h 2008-03-24 14:49:18.000000000 -0400 |
31149 |
++++ linux-2.6.24.4/include/linux/sched.h 2008-03-26 17:56:56.000000000 -0400 |
31150 |
+@@ -94,6 +94,7 @@ struct sched_param { |
31151 |
+ struct exec_domain; |
31152 |
+ struct futex_pi_state; |
31153 |
+ struct bio; |
31154 |
++struct linux_binprm; |
31155 |
+ |
31156 |
+ /* |
31157 |
+ * List of flags we want to share for kernel threads, |
31158 |
+@@ -507,6 +508,15 @@ struct signal_struct { |
31159 |
+ unsigned audit_tty; |
31160 |
+ struct tty_audit_buf *tty_audit_buf; |
31161 |
+ #endif |
31162 |
++ |
31163 |
++#ifdef CONFIG_GRKERNSEC |
31164 |
++ u32 curr_ip; |
31165 |
++ u32 gr_saddr; |
31166 |
++ u32 gr_daddr; |
31167 |
++ u16 gr_sport; |
31168 |
++ u16 gr_dport; |
31169 |
++ u8 used_accept:1; |
31170 |
++#endif |
31171 |
+ }; |
31172 |
+ |
31173 |
+ /* Context switch must be unlocked if interrupts are to be enabled */ |
31174 |
+@@ -916,7 +926,7 @@ struct sched_entity { |
31175 |
+ |
31176 |
+ struct task_struct { |
31177 |
+ volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ |
31178 |
+- void *stack; |
31179 |
++ union thread_union *stack; |
31180 |
+ atomic_t usage; |
31181 |
+ unsigned int flags; /* per process flags, defined below */ |
31182 |
+ unsigned int ptrace; |
31183 |
+@@ -983,10 +993,9 @@ struct task_struct { |
31184 |
+ pid_t pid; |
31185 |
+ pid_t tgid; |
31186 |
+ |
31187 |
+-#ifdef CONFIG_CC_STACKPROTECTOR |
31188 |
+ /* Canary value for the -fstack-protector gcc feature */ |
31189 |
+ unsigned long stack_canary; |
31190 |
+-#endif |
31191 |
++ |
31192 |
+ /* |
31193 |
+ * pointers to (original) parent process, youngest child, younger sibling, |
31194 |
+ * older sibling, respectively. (p->father can be replaced with |
31195 |
+@@ -1007,8 +1016,8 @@ struct task_struct { |
31196 |
+ struct list_head thread_group; |
31197 |
+ |
31198 |
+ struct completion *vfork_done; /* for vfork() */ |
31199 |
+- int __user *set_child_tid; /* CLONE_CHILD_SETTID */ |
31200 |
+- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ |
31201 |
++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */ |
31202 |
++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ |
31203 |
+ |
31204 |
+ unsigned int rt_priority; |
31205 |
+ cputime_t utime, stime, utimescaled, stimescaled; |
31206 |
+@@ -1178,8 +1187,60 @@ struct task_struct { |
31207 |
+ int make_it_fail; |
31208 |
+ #endif |
31209 |
+ struct prop_local_single dirties; |
31210 |
++ |
31211 |
++#ifdef CONFIG_GRKERNSEC |
31212 |
++ /* grsecurity */ |
31213 |
++ struct acl_subject_label *acl; |
31214 |
++ struct acl_role_label *role; |
31215 |
++ struct file *exec_file; |
31216 |
++ u16 acl_role_id; |
31217 |
++ u8 acl_sp_role; |
31218 |
++ u8 is_writable; |
31219 |
++ u8 brute; |
31220 |
++#endif |
31221 |
++ |
31222 |
+ }; |
31223 |
+ |
31224 |
++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */ |
31225 |
++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */ |
31226 |
++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */ |
31227 |
++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */ |
31228 |
++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */ |
31229 |
++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */ |
31230 |
++ |
31231 |
++#ifdef CONFIG_PAX_SOFTMODE |
31232 |
++extern unsigned int pax_softmode; |
31233 |
++#endif |
31234 |
++ |
31235 |
++extern int pax_check_flags(unsigned long *); |
31236 |
++ |
31237 |
++/* if tsk != current then task_lock must be held on it */ |
31238 |
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
31239 |
++static inline unsigned long pax_get_flags(struct task_struct *tsk) |
31240 |
++{ |
31241 |
++ if (likely(tsk->mm)) |
31242 |
++ return tsk->mm->pax_flags; |
31243 |
++ else |
31244 |
++ return 0UL; |
31245 |
++} |
31246 |
++ |
31247 |
++/* if tsk != current then task_lock must be held on it */ |
31248 |
++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags) |
31249 |
++{ |
31250 |
++ if (likely(tsk->mm)) { |
31251 |
++ tsk->mm->pax_flags = flags; |
31252 |
++ return 0; |
31253 |
++ } |
31254 |
++ return -EINVAL; |
31255 |
++} |
31256 |
++#endif |
31257 |
++ |
31258 |
++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS |
31259 |
++extern void pax_set_initial_flags(struct linux_binprm *bprm); |
31260 |
++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS) |
31261 |
++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm); |
31262 |
++#endif |
31263 |
++ |
31264 |
+ /* |
31265 |
+ * Priority of a process goes from 0..MAX_PRIO-1, valid RT |
31266 |
+ * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH |
31267 |
+@@ -1779,8 +1840,8 @@ static inline void unlock_task_sighand(s |
31268 |
+ |
31269 |
+ #ifndef __HAVE_THREAD_FUNCTIONS |
31270 |
+ |
31271 |
+-#define task_thread_info(task) ((struct thread_info *)(task)->stack) |
31272 |
+-#define task_stack_page(task) ((task)->stack) |
31273 |
++#define task_thread_info(task) (&(task)->stack->thread_info) |
31274 |
++#define task_stack_page(task) ((void *)(task)->stack) |
31275 |
+ |
31276 |
+ static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org) |
31277 |
+ { |
31278 |
+@@ -1917,6 +1978,12 @@ extern void arch_pick_mmap_layout(struct |
31279 |
+ static inline void arch_pick_mmap_layout(struct mm_struct *mm) |
31280 |
+ { |
31281 |
+ mm->mmap_base = TASK_UNMAPPED_BASE; |
31282 |
++ |
31283 |
++#ifdef CONFIG_PAX_RANDMMAP |
31284 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
31285 |
++ mm->mmap_base += mm->delta_mmap; |
31286 |
++#endif |
31287 |
++ |
31288 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
31289 |
+ mm->unmap_area = arch_unmap_area; |
31290 |
+ } |
31291 |
+diff -urNp linux-2.6.24.4/include/linux/screen_info.h linux-2.6.24.4/include/linux/screen_info.h |
31292 |
+--- linux-2.6.24.4/include/linux/screen_info.h 2008-03-24 14:49:18.000000000 -0400 |
31293 |
++++ linux-2.6.24.4/include/linux/screen_info.h 2008-03-26 17:56:56.000000000 -0400 |
31294 |
+@@ -42,7 +42,8 @@ struct screen_info { |
31295 |
+ __u16 pages; /* 0x32 */ |
31296 |
+ __u16 vesa_attributes; /* 0x34 */ |
31297 |
+ __u32 capabilities; /* 0x36 */ |
31298 |
+- __u8 _reserved[6]; /* 0x3a */ |
31299 |
++ __u16 vesapm_size; /* 0x3a */ |
31300 |
++ __u8 _reserved[4]; /* 0x3c */ |
31301 |
+ } __attribute__((packed)); |
31302 |
+ |
31303 |
+ #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ |
31304 |
+diff -urNp linux-2.6.24.4/include/linux/security.h linux-2.6.24.4/include/linux/security.h |
31305 |
+--- linux-2.6.24.4/include/linux/security.h 2008-03-24 14:49:18.000000000 -0400 |
31306 |
++++ linux-2.6.24.4/include/linux/security.h 2008-03-26 17:56:56.000000000 -0400 |
31307 |
+@@ -2266,7 +2266,7 @@ static inline struct dentry *securityfs_ |
31308 |
+ mode_t mode, |
31309 |
+ struct dentry *parent, |
31310 |
+ void *data, |
31311 |
+- struct file_operations *fops) |
31312 |
++ const struct file_operations *fops) |
31313 |
+ { |
31314 |
+ return ERR_PTR(-ENODEV); |
31315 |
+ } |
31316 |
+diff -urNp linux-2.6.24.4/include/linux/shm.h linux-2.6.24.4/include/linux/shm.h |
31317 |
+--- linux-2.6.24.4/include/linux/shm.h 2008-03-24 14:49:18.000000000 -0400 |
31318 |
++++ linux-2.6.24.4/include/linux/shm.h 2008-03-26 17:56:56.000000000 -0400 |
31319 |
+@@ -87,6 +87,10 @@ struct shmid_kernel /* private to the ke |
31320 |
+ pid_t shm_cprid; |
31321 |
+ pid_t shm_lprid; |
31322 |
+ struct user_struct *mlock_user; |
31323 |
++#ifdef CONFIG_GRKERNSEC |
31324 |
++ time_t shm_createtime; |
31325 |
++ pid_t shm_lapid; |
31326 |
++#endif |
31327 |
+ }; |
31328 |
+ |
31329 |
+ /* shm_mode upper byte flags */ |
31330 |
+diff -urNp linux-2.6.24.4/include/linux/sysctl.h linux-2.6.24.4/include/linux/sysctl.h |
31331 |
+--- linux-2.6.24.4/include/linux/sysctl.h 2008-03-24 14:49:18.000000000 -0400 |
31332 |
++++ linux-2.6.24.4/include/linux/sysctl.h 2008-03-26 17:56:56.000000000 -0400 |
31333 |
+@@ -164,9 +164,21 @@ enum |
31334 |
+ KERN_MAX_LOCK_DEPTH=74, |
31335 |
+ KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */ |
31336 |
+ KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */ |
31337 |
+-}; |
31338 |
++#ifdef CONFIG_GRKERNSEC |
31339 |
++ KERN_GRSECURITY=98, /* grsecurity */ |
31340 |
++#endif |
31341 |
++ |
31342 |
++#ifdef CONFIG_PAX_SOFTMODE |
31343 |
++ KERN_PAX=99, /* PaX control */ |
31344 |
++#endif |
31345 |
+ |
31346 |
++}; |
31347 |
+ |
31348 |
++#ifdef CONFIG_PAX_SOFTMODE |
31349 |
++enum { |
31350 |
++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */ |
31351 |
++}; |
31352 |
++#endif |
31353 |
+ |
31354 |
+ /* CTL_VM names: */ |
31355 |
+ enum |
31356 |
+diff -urNp linux-2.6.24.4/include/linux/uaccess.h linux-2.6.24.4/include/linux/uaccess.h |
31357 |
+--- linux-2.6.24.4/include/linux/uaccess.h 2008-03-24 14:49:18.000000000 -0400 |
31358 |
++++ linux-2.6.24.4/include/linux/uaccess.h 2008-03-26 17:56:56.000000000 -0400 |
31359 |
+@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_ |
31360 |
+ long ret; \ |
31361 |
+ mm_segment_t old_fs = get_fs(); \ |
31362 |
+ \ |
31363 |
+- set_fs(KERNEL_DS); \ |
31364 |
+ pagefault_disable(); \ |
31365 |
++ set_fs(KERNEL_DS); \ |
31366 |
+ ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \ |
31367 |
+- pagefault_enable(); \ |
31368 |
+ set_fs(old_fs); \ |
31369 |
++ pagefault_enable(); \ |
31370 |
+ ret; \ |
31371 |
+ }) |
31372 |
+ |
31373 |
+diff -urNp linux-2.6.24.4/include/linux/udf_fs.h linux-2.6.24.4/include/linux/udf_fs.h |
31374 |
+--- linux-2.6.24.4/include/linux/udf_fs.h 2008-03-24 14:49:18.000000000 -0400 |
31375 |
++++ linux-2.6.24.4/include/linux/udf_fs.h 2008-03-26 17:56:56.000000000 -0400 |
31376 |
+@@ -45,7 +45,7 @@ |
31377 |
+ printk (f, ##a); \ |
31378 |
+ } |
31379 |
+ #else |
31380 |
+-#define udf_debug(f, a...) /**/ |
31381 |
++#define udf_debug(f, a...) do {} while (0) |
31382 |
+ #endif |
31383 |
+ |
31384 |
+ #define udf_info(f, a...) \ |
31385 |
+diff -urNp linux-2.6.24.4/include/net/sctp/sctp.h linux-2.6.24.4/include/net/sctp/sctp.h |
31386 |
+--- linux-2.6.24.4/include/net/sctp/sctp.h 2008-03-24 14:49:18.000000000 -0400 |
31387 |
++++ linux-2.6.24.4/include/net/sctp/sctp.h 2008-03-26 17:56:56.000000000 -0400 |
31388 |
+@@ -316,8 +316,8 @@ extern int sctp_debug_flag; |
31389 |
+ |
31390 |
+ #else /* SCTP_DEBUG */ |
31391 |
+ |
31392 |
+-#define SCTP_DEBUG_PRINTK(whatever...) |
31393 |
+-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) |
31394 |
++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0) |
31395 |
++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0) |
31396 |
+ #define SCTP_ENABLE_DEBUG |
31397 |
+ #define SCTP_DISABLE_DEBUG |
31398 |
+ #define SCTP_ASSERT(expr, str, func) |
31399 |
+diff -urNp linux-2.6.24.4/include/sound/core.h linux-2.6.24.4/include/sound/core.h |
31400 |
+--- linux-2.6.24.4/include/sound/core.h 2008-03-24 14:49:18.000000000 -0400 |
31401 |
++++ linux-2.6.24.4/include/sound/core.h 2008-03-26 17:56:56.000000000 -0400 |
31402 |
+@@ -396,9 +396,9 @@ void snd_verbose_printd(const char *file |
31403 |
+ |
31404 |
+ #else /* !CONFIG_SND_DEBUG */ |
31405 |
+ |
31406 |
+-#define snd_printd(fmt, args...) /* nothing */ |
31407 |
++#define snd_printd(fmt, args...) do {} while (0) |
31408 |
+ #define snd_assert(expr, args...) (void)(expr) |
31409 |
+-#define snd_BUG() /* nothing */ |
31410 |
++#define snd_BUG() do {} while (0) |
31411 |
+ |
31412 |
+ #endif /* CONFIG_SND_DEBUG */ |
31413 |
+ |
31414 |
+@@ -412,7 +412,7 @@ void snd_verbose_printd(const char *file |
31415 |
+ */ |
31416 |
+ #define snd_printdd(format, args...) snd_printk(format, ##args) |
31417 |
+ #else |
31418 |
+-#define snd_printdd(format, args...) /* nothing */ |
31419 |
++#define snd_printdd(format, args...) do {} while (0) |
31420 |
+ #endif |
31421 |
+ |
31422 |
+ |
31423 |
+diff -urNp linux-2.6.24.4/init/do_mounts.c linux-2.6.24.4/init/do_mounts.c |
31424 |
+--- linux-2.6.24.4/init/do_mounts.c 2008-03-24 14:49:18.000000000 -0400 |
31425 |
++++ linux-2.6.24.4/init/do_mounts.c 2008-03-26 17:56:56.000000000 -0400 |
31426 |
+@@ -68,11 +68,12 @@ static dev_t try_name(char *name, int pa |
31427 |
+ |
31428 |
+ /* read device number from .../dev */ |
31429 |
+ |
31430 |
+- sprintf(path, "/sys/block/%s/dev", name); |
31431 |
+- fd = sys_open(path, 0, 0); |
31432 |
++ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name)) |
31433 |
++ goto fail; |
31434 |
++ fd = sys_open((char __user *)path, 0, 0); |
31435 |
+ if (fd < 0) |
31436 |
+ goto fail; |
31437 |
+- len = sys_read(fd, buf, 32); |
31438 |
++ len = sys_read(fd, (char __user *)buf, 32); |
31439 |
+ sys_close(fd); |
31440 |
+ if (len <= 0 || len == 32 || buf[len - 1] != '\n') |
31441 |
+ goto fail; |
31442 |
+@@ -98,11 +99,12 @@ static dev_t try_name(char *name, int pa |
31443 |
+ return res; |
31444 |
+ |
31445 |
+ /* otherwise read range from .../range */ |
31446 |
+- sprintf(path, "/sys/block/%s/range", name); |
31447 |
+- fd = sys_open(path, 0, 0); |
31448 |
++ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name)) |
31449 |
++ goto fail; |
31450 |
++ fd = sys_open((char __user *)path, 0, 0); |
31451 |
+ if (fd < 0) |
31452 |
+ goto fail; |
31453 |
+- len = sys_read(fd, buf, 32); |
31454 |
++ len = sys_read(fd, (char __user *)buf, 32); |
31455 |
+ sys_close(fd); |
31456 |
+ if (len <= 0 || len == 32 || buf[len - 1] != '\n') |
31457 |
+ goto fail; |
31458 |
+@@ -145,8 +147,8 @@ dev_t name_to_dev_t(char *name) |
31459 |
+ int part; |
31460 |
+ |
31461 |
+ #ifdef CONFIG_SYSFS |
31462 |
+- int mkdir_err = sys_mkdir("/sys", 0700); |
31463 |
+- if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0) |
31464 |
++ int mkdir_err = sys_mkdir((char __user *)"/sys", 0700); |
31465 |
++ if (sys_mount((char __user *)"sysfs", (char __user *)"/sys", (char __user *)"sysfs", 0, NULL) < 0) |
31466 |
+ goto out; |
31467 |
+ #endif |
31468 |
+ |
31469 |
+@@ -198,10 +200,10 @@ dev_t name_to_dev_t(char *name) |
31470 |
+ res = try_name(s, part); |
31471 |
+ done: |
31472 |
+ #ifdef CONFIG_SYSFS |
31473 |
+- sys_umount("/sys", 0); |
31474 |
++ sys_umount((char __user *)"/sys", 0); |
31475 |
+ out: |
31476 |
+ if (!mkdir_err) |
31477 |
+- sys_rmdir("/sys"); |
31478 |
++ sys_rmdir((char __user *)"/sys"); |
31479 |
+ #endif |
31480 |
+ return res; |
31481 |
+ fail: |
31482 |
+@@ -281,11 +283,11 @@ static void __init get_fs_names(char *pa |
31483 |
+ |
31484 |
+ static int __init do_mount_root(char *name, char *fs, int flags, void *data) |
31485 |
+ { |
31486 |
+- int err = sys_mount(name, "/root", fs, flags, data); |
31487 |
++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data); |
31488 |
+ if (err) |
31489 |
+ return err; |
31490 |
+ |
31491 |
+- sys_chdir("/root"); |
31492 |
++ sys_chdir((char __user *)"/root"); |
31493 |
+ ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev; |
31494 |
+ printk("VFS: Mounted root (%s filesystem)%s.\n", |
31495 |
+ current->fs->pwdmnt->mnt_sb->s_type->name, |
31496 |
+@@ -371,18 +373,18 @@ void __init change_floppy(char *fmt, ... |
31497 |
+ va_start(args, fmt); |
31498 |
+ vsprintf(buf, fmt, args); |
31499 |
+ va_end(args); |
31500 |
+- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); |
31501 |
++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0); |
31502 |
+ if (fd >= 0) { |
31503 |
+ sys_ioctl(fd, FDEJECT, 0); |
31504 |
+ sys_close(fd); |
31505 |
+ } |
31506 |
+ printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); |
31507 |
+- fd = sys_open("/dev/console", O_RDWR, 0); |
31508 |
++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0); |
31509 |
+ if (fd >= 0) { |
31510 |
+ sys_ioctl(fd, TCGETS, (long)&termios); |
31511 |
+ termios.c_lflag &= ~ICANON; |
31512 |
+ sys_ioctl(fd, TCSETSF, (long)&termios); |
31513 |
+- sys_read(fd, &c, 1); |
31514 |
++ sys_read(fd, (char __user *)&c, 1); |
31515 |
+ termios.c_lflag |= ICANON; |
31516 |
+ sys_ioctl(fd, TCSETSF, (long)&termios); |
31517 |
+ sys_close(fd); |
31518 |
+@@ -468,8 +470,8 @@ void __init prepare_namespace(void) |
31519 |
+ |
31520 |
+ mount_root(); |
31521 |
+ out: |
31522 |
+- sys_mount(".", "/", NULL, MS_MOVE, NULL); |
31523 |
+- sys_chroot("."); |
31524 |
++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL); |
31525 |
++ sys_chroot((char __user *)"."); |
31526 |
+ security_sb_post_mountroot(); |
31527 |
+ } |
31528 |
+ |
31529 |
+diff -urNp linux-2.6.24.4/init/do_mounts.h linux-2.6.24.4/init/do_mounts.h |
31530 |
+--- linux-2.6.24.4/init/do_mounts.h 2008-03-24 14:49:18.000000000 -0400 |
31531 |
++++ linux-2.6.24.4/init/do_mounts.h 2008-03-26 17:56:56.000000000 -0400 |
31532 |
+@@ -15,15 +15,15 @@ extern char *root_device_name; |
31533 |
+ |
31534 |
+ static inline int create_dev(char *name, dev_t dev) |
31535 |
+ { |
31536 |
+- sys_unlink(name); |
31537 |
+- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); |
31538 |
++ sys_unlink((char __user *)name); |
31539 |
++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev)); |
31540 |
+ } |
31541 |
+ |
31542 |
+ #if BITS_PER_LONG == 32 |
31543 |
+ static inline u32 bstat(char *name) |
31544 |
+ { |
31545 |
+ struct stat64 stat; |
31546 |
+- if (sys_stat64(name, &stat) != 0) |
31547 |
++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0) |
31548 |
+ return 0; |
31549 |
+ if (!S_ISBLK(stat.st_mode)) |
31550 |
+ return 0; |
31551 |
+diff -urNp linux-2.6.24.4/init/do_mounts_md.c linux-2.6.24.4/init/do_mounts_md.c |
31552 |
+--- linux-2.6.24.4/init/do_mounts_md.c 2008-03-24 14:49:18.000000000 -0400 |
31553 |
++++ linux-2.6.24.4/init/do_mounts_md.c 2008-03-26 17:56:56.000000000 -0400 |
31554 |
+@@ -167,7 +167,7 @@ static void __init md_setup_drive(void) |
31555 |
+ partitioned ? "_d" : "", minor, |
31556 |
+ md_setup_args[ent].device_names); |
31557 |
+ |
31558 |
+- fd = sys_open(name, 0, 0); |
31559 |
++ fd = sys_open((char __user *)name, 0, 0); |
31560 |
+ if (fd < 0) { |
31561 |
+ printk(KERN_ERR "md: open failed - cannot start " |
31562 |
+ "array %s\n", name); |
31563 |
+@@ -230,7 +230,7 @@ static void __init md_setup_drive(void) |
31564 |
+ * array without it |
31565 |
+ */ |
31566 |
+ sys_close(fd); |
31567 |
+- fd = sys_open(name, 0, 0); |
31568 |
++ fd = sys_open((char __user *)name, 0, 0); |
31569 |
+ sys_ioctl(fd, BLKRRPART, 0); |
31570 |
+ } |
31571 |
+ sys_close(fd); |
31572 |
+@@ -271,7 +271,7 @@ void __init md_run_setup(void) |
31573 |
+ if (raid_noautodetect) |
31574 |
+ printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n"); |
31575 |
+ else { |
31576 |
+- int fd = sys_open("/dev/md0", 0, 0); |
31577 |
++ int fd = sys_open((char __user *)"/dev/md0", 0, 0); |
31578 |
+ if (fd >= 0) { |
31579 |
+ sys_ioctl(fd, RAID_AUTORUN, raid_autopart); |
31580 |
+ sys_close(fd); |
31581 |
+diff -urNp linux-2.6.24.4/init/initramfs.c linux-2.6.24.4/init/initramfs.c |
31582 |
+--- linux-2.6.24.4/init/initramfs.c 2008-03-24 14:49:18.000000000 -0400 |
31583 |
++++ linux-2.6.24.4/init/initramfs.c 2008-03-26 17:56:56.000000000 -0400 |
31584 |
+@@ -240,7 +240,7 @@ static int __init maybe_link(void) |
31585 |
+ if (nlink >= 2) { |
31586 |
+ char *old = find_link(major, minor, ino, mode, collected); |
31587 |
+ if (old) |
31588 |
+- return (sys_link(old, collected) < 0) ? -1 : 1; |
31589 |
++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1; |
31590 |
+ } |
31591 |
+ return 0; |
31592 |
+ } |
31593 |
+@@ -249,11 +249,11 @@ static void __init clean_path(char *path |
31594 |
+ { |
31595 |
+ struct stat st; |
31596 |
+ |
31597 |
+- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) { |
31598 |
++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) { |
31599 |
+ if (S_ISDIR(st.st_mode)) |
31600 |
+- sys_rmdir(path); |
31601 |
++ sys_rmdir((char __user *)path); |
31602 |
+ else |
31603 |
+- sys_unlink(path); |
31604 |
++ sys_unlink((char __user *)path); |
31605 |
+ } |
31606 |
+ } |
31607 |
+ |
31608 |
+@@ -276,7 +276,7 @@ static int __init do_name(void) |
31609 |
+ int openflags = O_WRONLY|O_CREAT; |
31610 |
+ if (ml != 1) |
31611 |
+ openflags |= O_TRUNC; |
31612 |
+- wfd = sys_open(collected, openflags, mode); |
31613 |
++ wfd = sys_open((char __user *)collected, openflags, mode); |
31614 |
+ |
31615 |
+ if (wfd >= 0) { |
31616 |
+ sys_fchown(wfd, uid, gid); |
31617 |
+@@ -285,15 +285,15 @@ static int __init do_name(void) |
31618 |
+ } |
31619 |
+ } |
31620 |
+ } else if (S_ISDIR(mode)) { |
31621 |
+- sys_mkdir(collected, mode); |
31622 |
+- sys_chown(collected, uid, gid); |
31623 |
+- sys_chmod(collected, mode); |
31624 |
++ sys_mkdir((char __user *)collected, mode); |
31625 |
++ sys_chown((char __user *)collected, uid, gid); |
31626 |
++ sys_chmod((char __user *)collected, mode); |
31627 |
+ } else if (S_ISBLK(mode) || S_ISCHR(mode) || |
31628 |
+ S_ISFIFO(mode) || S_ISSOCK(mode)) { |
31629 |
+ if (maybe_link() == 0) { |
31630 |
+- sys_mknod(collected, mode, rdev); |
31631 |
+- sys_chown(collected, uid, gid); |
31632 |
+- sys_chmod(collected, mode); |
31633 |
++ sys_mknod((char __user *)collected, mode, rdev); |
31634 |
++ sys_chown((char __user *)collected, uid, gid); |
31635 |
++ sys_chmod((char __user *)collected, mode); |
31636 |
+ } |
31637 |
+ } |
31638 |
+ return 0; |
31639 |
+@@ -302,13 +302,13 @@ static int __init do_name(void) |
31640 |
+ static int __init do_copy(void) |
31641 |
+ { |
31642 |
+ if (count >= body_len) { |
31643 |
+- sys_write(wfd, victim, body_len); |
31644 |
++ sys_write(wfd, (char __user *)victim, body_len); |
31645 |
+ sys_close(wfd); |
31646 |
+ eat(body_len); |
31647 |
+ state = SkipIt; |
31648 |
+ return 0; |
31649 |
+ } else { |
31650 |
+- sys_write(wfd, victim, count); |
31651 |
++ sys_write(wfd, (char __user *)victim, count); |
31652 |
+ body_len -= count; |
31653 |
+ eat(count); |
31654 |
+ return 1; |
31655 |
+@@ -319,8 +319,8 @@ static int __init do_symlink(void) |
31656 |
+ { |
31657 |
+ collected[N_ALIGN(name_len) + body_len] = '\0'; |
31658 |
+ clean_path(collected, 0); |
31659 |
+- sys_symlink(collected + N_ALIGN(name_len), collected); |
31660 |
+- sys_lchown(collected, uid, gid); |
31661 |
++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected); |
31662 |
++ sys_lchown((char __user *)collected, uid, gid); |
31663 |
+ state = SkipIt; |
31664 |
+ next_state = Reset; |
31665 |
+ return 0; |
31666 |
+diff -urNp linux-2.6.24.4/init/Kconfig linux-2.6.24.4/init/Kconfig |
31667 |
+--- linux-2.6.24.4/init/Kconfig 2008-03-24 14:49:18.000000000 -0400 |
31668 |
++++ linux-2.6.24.4/init/Kconfig 2008-03-26 17:56:56.000000000 -0400 |
31669 |
+@@ -469,6 +469,7 @@ config SYSCTL_SYSCALL |
31670 |
+ config KALLSYMS |
31671 |
+ bool "Load all symbols for debugging/ksymoops" if EMBEDDED |
31672 |
+ default y |
31673 |
++ depends on !GRKERNSEC_HIDESYM |
31674 |
+ help |
31675 |
+ Say Y here to let the kernel print out symbolic crash information and |
31676 |
+ symbolic stack backtraces. This increases the size of the kernel |
31677 |
+diff -urNp linux-2.6.24.4/init/main.c linux-2.6.24.4/init/main.c |
31678 |
+--- linux-2.6.24.4/init/main.c 2008-03-24 14:49:18.000000000 -0400 |
31679 |
++++ linux-2.6.24.4/init/main.c 2008-03-26 17:56:56.000000000 -0400 |
31680 |
+@@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void) |
31681 |
+ #ifdef CONFIG_TC |
31682 |
+ extern void tc_init(void); |
31683 |
+ #endif |
31684 |
++extern void grsecurity_init(void); |
31685 |
+ |
31686 |
+ enum system_states system_state; |
31687 |
+ EXPORT_SYMBOL(system_state); |
31688 |
+@@ -187,6 +188,17 @@ static int __init set_reset_devices(char |
31689 |
+ |
31690 |
+ __setup("reset_devices", set_reset_devices); |
31691 |
+ |
31692 |
++#ifdef CONFIG_PAX_SOFTMODE |
31693 |
++unsigned int pax_softmode; |
31694 |
++ |
31695 |
++static int __init setup_pax_softmode(char *str) |
31696 |
++{ |
31697 |
++ get_option(&str, &pax_softmode); |
31698 |
++ return 1; |
31699 |
++} |
31700 |
++__setup("pax_softmode=", setup_pax_softmode); |
31701 |
++#endif |
31702 |
++ |
31703 |
+ static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; |
31704 |
+ char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; |
31705 |
+ static const char *panic_later, *panic_param; |
31706 |
+@@ -847,6 +859,8 @@ static int __init kernel_init(void * unu |
31707 |
+ prepare_namespace(); |
31708 |
+ } |
31709 |
+ |
31710 |
++ grsecurity_init(); |
31711 |
++ |
31712 |
+ /* |
31713 |
+ * Ok, we have completed the initial bootup, and |
31714 |
+ * we're essentially up and running. Get rid of the |
31715 |
+diff -urNp linux-2.6.24.4/init/noinitramfs.c linux-2.6.24.4/init/noinitramfs.c |
31716 |
+--- linux-2.6.24.4/init/noinitramfs.c 2008-03-24 14:49:18.000000000 -0400 |
31717 |
++++ linux-2.6.24.4/init/noinitramfs.c 2008-03-26 17:56:56.000000000 -0400 |
31718 |
+@@ -29,7 +29,7 @@ static int __init default_rootfs(void) |
31719 |
+ { |
31720 |
+ int err; |
31721 |
+ |
31722 |
+- err = sys_mkdir("/dev", 0755); |
31723 |
++ err = sys_mkdir((const char __user *)"/dev", 0755); |
31724 |
+ if (err < 0) |
31725 |
+ goto out; |
31726 |
+ |
31727 |
+@@ -39,7 +39,7 @@ static int __init default_rootfs(void) |
31728 |
+ if (err < 0) |
31729 |
+ goto out; |
31730 |
+ |
31731 |
+- err = sys_mkdir("/root", 0700); |
31732 |
++ err = sys_mkdir((const char __user *)"/root", 0700); |
31733 |
+ if (err < 0) |
31734 |
+ goto out; |
31735 |
+ |
31736 |
+diff -urNp linux-2.6.24.4/ipc/ipc_sysctl.c linux-2.6.24.4/ipc/ipc_sysctl.c |
31737 |
+--- linux-2.6.24.4/ipc/ipc_sysctl.c 2008-03-24 14:49:18.000000000 -0400 |
31738 |
++++ linux-2.6.24.4/ipc/ipc_sysctl.c 2008-03-26 17:56:56.000000000 -0400 |
31739 |
+@@ -157,7 +157,7 @@ static struct ctl_table ipc_kern_table[] |
31740 |
+ .proc_handler = proc_ipc_dointvec, |
31741 |
+ .strategy = sysctl_ipc_data, |
31742 |
+ }, |
31743 |
+- {} |
31744 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
31745 |
+ }; |
31746 |
+ |
31747 |
+ static struct ctl_table ipc_root_table[] = { |
31748 |
+@@ -167,7 +167,7 @@ static struct ctl_table ipc_root_table[] |
31749 |
+ .mode = 0555, |
31750 |
+ .child = ipc_kern_table, |
31751 |
+ }, |
31752 |
+- {} |
31753 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
31754 |
+ }; |
31755 |
+ |
31756 |
+ static int __init ipc_sysctl_init(void) |
31757 |
+diff -urNp linux-2.6.24.4/ipc/msg.c linux-2.6.24.4/ipc/msg.c |
31758 |
+--- linux-2.6.24.4/ipc/msg.c 2008-03-24 14:49:18.000000000 -0400 |
31759 |
++++ linux-2.6.24.4/ipc/msg.c 2008-03-26 17:56:56.000000000 -0400 |
31760 |
+@@ -36,6 +36,7 @@ |
31761 |
+ #include <linux/seq_file.h> |
31762 |
+ #include <linux/rwsem.h> |
31763 |
+ #include <linux/nsproxy.h> |
31764 |
++#include <linux/grsecurity.h> |
31765 |
+ |
31766 |
+ #include <asm/current.h> |
31767 |
+ #include <asm/uaccess.h> |
31768 |
+@@ -315,6 +316,7 @@ asmlinkage long sys_msgget(key_t key, in |
31769 |
+ struct ipc_namespace *ns; |
31770 |
+ struct ipc_ops msg_ops; |
31771 |
+ struct ipc_params msg_params; |
31772 |
++ long err; |
31773 |
+ |
31774 |
+ ns = current->nsproxy->ipc_ns; |
31775 |
+ |
31776 |
+@@ -325,7 +327,11 @@ asmlinkage long sys_msgget(key_t key, in |
31777 |
+ msg_params.key = key; |
31778 |
+ msg_params.flg = msgflg; |
31779 |
+ |
31780 |
+- return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params); |
31781 |
++ err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params); |
31782 |
++ |
31783 |
++ gr_log_msgget(err, msgflg); |
31784 |
++ |
31785 |
++ return err; |
31786 |
+ } |
31787 |
+ |
31788 |
+ static inline unsigned long |
31789 |
+@@ -586,6 +592,7 @@ asmlinkage long sys_msgctl(int msqid, in |
31790 |
+ break; |
31791 |
+ } |
31792 |
+ case IPC_RMID: |
31793 |
++ gr_log_msgrm(ipcp->uid, ipcp->cuid); |
31794 |
+ freeque(ns, msq); |
31795 |
+ break; |
31796 |
+ } |
31797 |
+diff -urNp linux-2.6.24.4/ipc/sem.c linux-2.6.24.4/ipc/sem.c |
31798 |
+--- linux-2.6.24.4/ipc/sem.c 2008-03-24 14:49:18.000000000 -0400 |
31799 |
++++ linux-2.6.24.4/ipc/sem.c 2008-03-26 17:56:56.000000000 -0400 |
31800 |
+@@ -82,6 +82,7 @@ |
31801 |
+ #include <linux/seq_file.h> |
31802 |
+ #include <linux/rwsem.h> |
31803 |
+ #include <linux/nsproxy.h> |
31804 |
++#include <linux/grsecurity.h> |
31805 |
+ |
31806 |
+ #include <asm/uaccess.h> |
31807 |
+ #include "util.h" |
31808 |
+@@ -334,6 +335,7 @@ asmlinkage long sys_semget(key_t key, in |
31809 |
+ struct ipc_namespace *ns; |
31810 |
+ struct ipc_ops sem_ops; |
31811 |
+ struct ipc_params sem_params; |
31812 |
++ long err; |
31813 |
+ |
31814 |
+ ns = current->nsproxy->ipc_ns; |
31815 |
+ |
31816 |
+@@ -348,7 +350,11 @@ asmlinkage long sys_semget(key_t key, in |
31817 |
+ sem_params.flg = semflg; |
31818 |
+ sem_params.u.nsems = nsems; |
31819 |
+ |
31820 |
+- return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params); |
31821 |
++ err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params); |
31822 |
++ |
31823 |
++ gr_log_semget(err, semflg); |
31824 |
++ |
31825 |
++ return err; |
31826 |
+ } |
31827 |
+ |
31828 |
+ /* Manage the doubly linked list sma->sem_pending as a FIFO: |
31829 |
+@@ -936,6 +942,7 @@ static int semctl_down(struct ipc_namesp |
31830 |
+ |
31831 |
+ switch(cmd){ |
31832 |
+ case IPC_RMID: |
31833 |
++ gr_log_semrm(ipcp->uid, ipcp->cuid); |
31834 |
+ freeary(ns, sma); |
31835 |
+ err = 0; |
31836 |
+ break; |
31837 |
+diff -urNp linux-2.6.24.4/ipc/shm.c linux-2.6.24.4/ipc/shm.c |
31838 |
+--- linux-2.6.24.4/ipc/shm.c 2008-03-24 14:49:18.000000000 -0400 |
31839 |
++++ linux-2.6.24.4/ipc/shm.c 2008-03-26 17:56:56.000000000 -0400 |
31840 |
+@@ -38,6 +38,7 @@ |
31841 |
+ #include <linux/rwsem.h> |
31842 |
+ #include <linux/nsproxy.h> |
31843 |
+ #include <linux/mount.h> |
31844 |
++#include <linux/grsecurity.h> |
31845 |
+ |
31846 |
+ #include <asm/uaccess.h> |
31847 |
+ |
31848 |
+@@ -71,6 +72,14 @@ static void shm_destroy (struct ipc_name |
31849 |
+ static int sysvipc_shm_proc_show(struct seq_file *s, void *it); |
31850 |
+ #endif |
31851 |
+ |
31852 |
++#ifdef CONFIG_GRKERNSEC |
31853 |
++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, |
31854 |
++ const time_t shm_createtime, const uid_t cuid, |
31855 |
++ const int shmid); |
31856 |
++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid, |
31857 |
++ const time_t shm_createtime); |
31858 |
++#endif |
31859 |
++ |
31860 |
+ static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids) |
31861 |
+ { |
31862 |
+ ns->ids[IPC_SHM_IDS] = ids; |
31863 |
+@@ -87,6 +96,8 @@ static void __shm_init_ns(struct ipc_nam |
31864 |
+ */ |
31865 |
+ static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp) |
31866 |
+ { |
31867 |
++ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid); |
31868 |
++ |
31869 |
+ if (shp->shm_nattch){ |
31870 |
+ shp->shm_perm.mode |= SHM_DEST; |
31871 |
+ /* Do not find it any more */ |
31872 |
+@@ -443,6 +454,14 @@ static int newseg(struct ipc_namespace * |
31873 |
+ shp->shm_lprid = 0; |
31874 |
+ shp->shm_atim = shp->shm_dtim = 0; |
31875 |
+ shp->shm_ctim = get_seconds(); |
31876 |
++#ifdef CONFIG_GRKERNSEC |
31877 |
++ { |
31878 |
++ struct timespec timeval; |
31879 |
++ do_posix_clock_monotonic_gettime(&timeval); |
31880 |
++ |
31881 |
++ shp->shm_createtime = timeval.tv_sec; |
31882 |
++ } |
31883 |
++#endif |
31884 |
+ shp->shm_segsz = size; |
31885 |
+ shp->shm_nattch = 0; |
31886 |
+ shp->shm_perm.id = shm_buildid(id, shp->shm_perm.seq); |
31887 |
+@@ -497,6 +516,7 @@ asmlinkage long sys_shmget (key_t key, s |
31888 |
+ struct ipc_namespace *ns; |
31889 |
+ struct ipc_ops shm_ops; |
31890 |
+ struct ipc_params shm_params; |
31891 |
++ long err; |
31892 |
+ |
31893 |
+ ns = current->nsproxy->ipc_ns; |
31894 |
+ |
31895 |
+@@ -508,7 +528,11 @@ asmlinkage long sys_shmget (key_t key, s |
31896 |
+ shm_params.flg = shmflg; |
31897 |
+ shm_params.u.size = size; |
31898 |
+ |
31899 |
+- return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params); |
31900 |
++ err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params); |
31901 |
++ |
31902 |
++ gr_log_shmget(err, shmflg, size); |
31903 |
++ |
31904 |
++ return err; |
31905 |
+ } |
31906 |
+ |
31907 |
+ static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version) |
31908 |
+@@ -974,9 +998,21 @@ long do_shmat(int shmid, char __user *sh |
31909 |
+ if (err) |
31910 |
+ goto out_unlock; |
31911 |
+ |
31912 |
++#ifdef CONFIG_GRKERNSEC |
31913 |
++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime, |
31914 |
++ shp->shm_perm.cuid, shmid) || |
31915 |
++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) { |
31916 |
++ err = -EACCES; |
31917 |
++ goto out_unlock; |
31918 |
++ } |
31919 |
++#endif |
31920 |
++ |
31921 |
+ path.dentry = dget(shp->shm_file->f_path.dentry); |
31922 |
+ path.mnt = shp->shm_file->f_path.mnt; |
31923 |
+ shp->shm_nattch++; |
31924 |
++#ifdef CONFIG_GRKERNSEC |
31925 |
++ shp->shm_lapid = current->pid; |
31926 |
++#endif |
31927 |
+ size = i_size_read(path.dentry->d_inode); |
31928 |
+ shm_unlock(shp); |
31929 |
+ |
31930 |
+diff -urNp linux-2.6.24.4/kernel/acct.c linux-2.6.24.4/kernel/acct.c |
31931 |
+--- linux-2.6.24.4/kernel/acct.c 2008-03-24 14:49:18.000000000 -0400 |
31932 |
++++ linux-2.6.24.4/kernel/acct.c 2008-03-26 17:56:56.000000000 -0400 |
31933 |
+@@ -511,7 +511,7 @@ static void do_acct_process(struct file |
31934 |
+ */ |
31935 |
+ flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; |
31936 |
+ current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; |
31937 |
+- file->f_op->write(file, (char *)&ac, |
31938 |
++ file->f_op->write(file, (char __user *)&ac, |
31939 |
+ sizeof(acct_t), &file->f_pos); |
31940 |
+ current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim; |
31941 |
+ set_fs(fs); |
31942 |
+diff -urNp linux-2.6.24.4/kernel/capability.c linux-2.6.24.4/kernel/capability.c |
31943 |
+--- linux-2.6.24.4/kernel/capability.c 2008-03-24 14:49:18.000000000 -0400 |
31944 |
++++ linux-2.6.24.4/kernel/capability.c 2008-03-26 17:56:56.000000000 -0400 |
31945 |
+@@ -13,6 +13,7 @@ |
31946 |
+ #include <linux/security.h> |
31947 |
+ #include <linux/syscalls.h> |
31948 |
+ #include <linux/pid_namespace.h> |
31949 |
++#include <linux/grsecurity.h> |
31950 |
+ #include <asm/uaccess.h> |
31951 |
+ |
31952 |
+ /* |
31953 |
+@@ -233,15 +234,25 @@ out: |
31954 |
+ |
31955 |
+ int __capable(struct task_struct *t, int cap) |
31956 |
+ { |
31957 |
+- if (security_capable(t, cap) == 0) { |
31958 |
++ if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) { |
31959 |
+ t->flags |= PF_SUPERPRIV; |
31960 |
+ return 1; |
31961 |
+ } |
31962 |
+ return 0; |
31963 |
+ } |
31964 |
+ |
31965 |
++int capable_nolog(int cap) |
31966 |
++{ |
31967 |
++ if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) { |
31968 |
++ current->flags |= PF_SUPERPRIV; |
31969 |
++ return 1; |
31970 |
++ } |
31971 |
++ return 0; |
31972 |
++} |
31973 |
++ |
31974 |
+ int capable(int cap) |
31975 |
+ { |
31976 |
+ return __capable(current, cap); |
31977 |
+ } |
31978 |
+ EXPORT_SYMBOL(capable); |
31979 |
++EXPORT_SYMBOL(capable_nolog); |
31980 |
+diff -urNp linux-2.6.24.4/kernel/configs.c linux-2.6.24.4/kernel/configs.c |
31981 |
+--- linux-2.6.24.4/kernel/configs.c 2008-03-24 14:49:18.000000000 -0400 |
31982 |
++++ linux-2.6.24.4/kernel/configs.c 2008-03-26 17:56:56.000000000 -0400 |
31983 |
+@@ -79,8 +79,16 @@ static int __init ikconfig_init(void) |
31984 |
+ struct proc_dir_entry *entry; |
31985 |
+ |
31986 |
+ /* create the current config file */ |
31987 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
31988 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
31989 |
++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root); |
31990 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
31991 |
++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root); |
31992 |
++#endif |
31993 |
++#else |
31994 |
+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO, |
31995 |
+ &proc_root); |
31996 |
++#endif |
31997 |
+ if (!entry) |
31998 |
+ return -ENOMEM; |
31999 |
+ |
32000 |
+diff -urNp linux-2.6.24.4/kernel/exit.c linux-2.6.24.4/kernel/exit.c |
32001 |
+--- linux-2.6.24.4/kernel/exit.c 2008-03-24 14:49:18.000000000 -0400 |
32002 |
++++ linux-2.6.24.4/kernel/exit.c 2008-03-26 17:56:56.000000000 -0400 |
32003 |
+@@ -44,6 +44,11 @@ |
32004 |
+ #include <linux/resource.h> |
32005 |
+ #include <linux/blkdev.h> |
32006 |
+ #include <linux/task_io_accounting_ops.h> |
32007 |
++#include <linux/grsecurity.h> |
32008 |
++ |
32009 |
++#ifdef CONFIG_GRKERNSEC |
32010 |
++extern rwlock_t grsec_exec_file_lock; |
32011 |
++#endif |
32012 |
+ |
32013 |
+ #include <asm/uaccess.h> |
32014 |
+ #include <asm/unistd.h> |
32015 |
+@@ -122,6 +127,7 @@ static void __exit_signal(struct task_st |
32016 |
+ |
32017 |
+ __unhash_process(tsk); |
32018 |
+ |
32019 |
++ gr_del_task_from_ip_table(tsk); |
32020 |
+ tsk->signal = NULL; |
32021 |
+ tsk->sighand = NULL; |
32022 |
+ spin_unlock(&sighand->siglock); |
32023 |
+@@ -273,12 +279,23 @@ static void reparent_to_kthreadd(void) |
32024 |
+ { |
32025 |
+ write_lock_irq(&tasklist_lock); |
32026 |
+ |
32027 |
++#ifdef CONFIG_GRKERNSEC |
32028 |
++ write_lock(&grsec_exec_file_lock); |
32029 |
++ if (current->exec_file) { |
32030 |
++ fput(current->exec_file); |
32031 |
++ current->exec_file = NULL; |
32032 |
++ } |
32033 |
++ write_unlock(&grsec_exec_file_lock); |
32034 |
++#endif |
32035 |
++ |
32036 |
+ ptrace_unlink(current); |
32037 |
+ /* Reparent to init */ |
32038 |
+ remove_parent(current); |
32039 |
+ current->real_parent = current->parent = kthreadd_task; |
32040 |
+ add_parent(current); |
32041 |
+ |
32042 |
++ gr_set_kernel_label(current); |
32043 |
++ |
32044 |
+ /* Set the exit signal to SIGCHLD so we signal init on exit */ |
32045 |
+ current->exit_signal = SIGCHLD; |
32046 |
+ |
32047 |
+@@ -373,6 +390,17 @@ void daemonize(const char *name, ...) |
32048 |
+ vsnprintf(current->comm, sizeof(current->comm), name, args); |
32049 |
+ va_end(args); |
32050 |
+ |
32051 |
++#ifdef CONFIG_GRKERNSEC |
32052 |
++ write_lock(&grsec_exec_file_lock); |
32053 |
++ if (current->exec_file) { |
32054 |
++ fput(current->exec_file); |
32055 |
++ current->exec_file = NULL; |
32056 |
++ } |
32057 |
++ write_unlock(&grsec_exec_file_lock); |
32058 |
++#endif |
32059 |
++ |
32060 |
++ gr_set_kernel_label(current); |
32061 |
++ |
32062 |
+ /* |
32063 |
+ * If we were started as result of loading a module, close all of the |
32064 |
+ * user space pages. We don't need them, and if we didn't close them |
32065 |
+@@ -990,6 +1018,9 @@ fastcall NORET_TYPE void do_exit(long co |
32066 |
+ tsk->exit_code = code; |
32067 |
+ taskstats_exit(tsk, group_dead); |
32068 |
+ |
32069 |
++ gr_acl_handle_psacct(tsk, code); |
32070 |
++ gr_acl_handle_exit(); |
32071 |
++ |
32072 |
+ exit_mm(tsk); |
32073 |
+ |
32074 |
+ if (group_dead) |
32075 |
+@@ -1200,7 +1231,7 @@ static int wait_task_zombie(struct task_ |
32076 |
+ pid_t pid = task_pid_nr_ns(p, ns); |
32077 |
+ uid_t uid = p->uid; |
32078 |
+ int exit_code = p->exit_code; |
32079 |
+- int why, status; |
32080 |
++ int why; |
32081 |
+ |
32082 |
+ if (unlikely(p->exit_state != EXIT_ZOMBIE)) |
32083 |
+ return 0; |
32084 |
+diff -urNp linux-2.6.24.4/kernel/fork.c linux-2.6.24.4/kernel/fork.c |
32085 |
+--- linux-2.6.24.4/kernel/fork.c 2008-03-24 14:49:18.000000000 -0400 |
32086 |
++++ linux-2.6.24.4/kernel/fork.c 2008-03-26 17:56:56.000000000 -0400 |
32087 |
+@@ -51,6 +51,7 @@ |
32088 |
+ #include <linux/random.h> |
32089 |
+ #include <linux/tty.h> |
32090 |
+ #include <linux/proc_fs.h> |
32091 |
++#include <linux/grsecurity.h> |
32092 |
+ |
32093 |
+ #include <asm/pgtable.h> |
32094 |
+ #include <asm/pgalloc.h> |
32095 |
+@@ -180,7 +181,7 @@ static struct task_struct *dup_task_stru |
32096 |
+ } |
32097 |
+ |
32098 |
+ *tsk = *orig; |
32099 |
+- tsk->stack = ti; |
32100 |
++ tsk->stack = (union thread_union *)ti; |
32101 |
+ |
32102 |
+ err = prop_local_init_single(&tsk->dirties); |
32103 |
+ if (err) { |
32104 |
+@@ -192,7 +193,7 @@ static struct task_struct *dup_task_stru |
32105 |
+ setup_thread_stack(tsk, orig); |
32106 |
+ |
32107 |
+ #ifdef CONFIG_CC_STACKPROTECTOR |
32108 |
+- tsk->stack_canary = get_random_int(); |
32109 |
++ tsk->stack_canary = pax_get_random_long(); |
32110 |
+ #endif |
32111 |
+ |
32112 |
+ /* One for us, one for whoever does the "release_task()" (usually parent) */ |
32113 |
+@@ -224,8 +225,8 @@ static int dup_mmap(struct mm_struct *mm |
32114 |
+ mm->locked_vm = 0; |
32115 |
+ mm->mmap = NULL; |
32116 |
+ mm->mmap_cache = NULL; |
32117 |
+- mm->free_area_cache = oldmm->mmap_base; |
32118 |
+- mm->cached_hole_size = ~0UL; |
32119 |
++ mm->free_area_cache = oldmm->free_area_cache; |
32120 |
++ mm->cached_hole_size = oldmm->cached_hole_size; |
32121 |
+ mm->map_count = 0; |
32122 |
+ cpus_clear(mm->cpu_vm_mask); |
32123 |
+ mm->mm_rb = RB_ROOT; |
32124 |
+@@ -262,6 +263,7 @@ static int dup_mmap(struct mm_struct *mm |
32125 |
+ tmp->vm_flags &= ~VM_LOCKED; |
32126 |
+ tmp->vm_mm = mm; |
32127 |
+ tmp->vm_next = NULL; |
32128 |
++ tmp->vm_mirror = NULL; |
32129 |
+ anon_vma_link(tmp); |
32130 |
+ file = tmp->vm_file; |
32131 |
+ if (file) { |
32132 |
+@@ -298,6 +300,31 @@ static int dup_mmap(struct mm_struct *mm |
32133 |
+ if (retval) |
32134 |
+ goto out; |
32135 |
+ } |
32136 |
++ |
32137 |
++#ifdef CONFIG_PAX_SEGMEXEC |
32138 |
++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) { |
32139 |
++ struct vm_area_struct *mpnt_m; |
32140 |
++ |
32141 |
++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) { |
32142 |
++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm); |
32143 |
++ |
32144 |
++ if (!mpnt->vm_mirror) |
32145 |
++ continue; |
32146 |
++ |
32147 |
++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) { |
32148 |
++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt); |
32149 |
++ mpnt->vm_mirror = mpnt_m; |
32150 |
++ } else { |
32151 |
++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm); |
32152 |
++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror; |
32153 |
++ mpnt_m->vm_mirror->vm_mirror = mpnt_m; |
32154 |
++ mpnt->vm_mirror->vm_mirror = mpnt; |
32155 |
++ } |
32156 |
++ } |
32157 |
++ BUG_ON(mpnt_m); |
32158 |
++ } |
32159 |
++#endif |
32160 |
++ |
32161 |
+ /* a new mm has just been created */ |
32162 |
+ arch_dup_mmap(oldmm, mm); |
32163 |
+ retval = 0; |
32164 |
+@@ -475,7 +502,7 @@ void mm_release(struct task_struct *tsk, |
32165 |
+ if (tsk->clear_child_tid |
32166 |
+ && !(tsk->flags & PF_SIGNALED) |
32167 |
+ && atomic_read(&mm->mm_users) > 1) { |
32168 |
+- u32 __user * tidptr = tsk->clear_child_tid; |
32169 |
++ pid_t __user * tidptr = tsk->clear_child_tid; |
32170 |
+ tsk->clear_child_tid = NULL; |
32171 |
+ |
32172 |
+ /* |
32173 |
+@@ -483,7 +510,7 @@ void mm_release(struct task_struct *tsk, |
32174 |
+ * not set up a proper pointer then tough luck. |
32175 |
+ */ |
32176 |
+ put_user(0, tidptr); |
32177 |
+- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0); |
32178 |
++ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0); |
32179 |
+ } |
32180 |
+ } |
32181 |
+ |
32182 |
+@@ -1015,6 +1042,9 @@ static struct task_struct *copy_process( |
32183 |
+ DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); |
32184 |
+ #endif |
32185 |
+ retval = -EAGAIN; |
32186 |
++ |
32187 |
++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0); |
32188 |
++ |
32189 |
+ if (atomic_read(&p->user->processes) >= |
32190 |
+ p->signal->rlim[RLIMIT_NPROC].rlim_cur) { |
32191 |
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && |
32192 |
+@@ -1169,6 +1199,8 @@ static struct task_struct *copy_process( |
32193 |
+ if (clone_flags & CLONE_THREAD) |
32194 |
+ p->tgid = current->tgid; |
32195 |
+ |
32196 |
++ gr_copy_label(p); |
32197 |
++ |
32198 |
+ p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; |
32199 |
+ /* |
32200 |
+ * Clear TID on mm_release()? |
32201 |
+@@ -1356,6 +1388,8 @@ bad_fork_cleanup_count: |
32202 |
+ bad_fork_free: |
32203 |
+ free_task(p); |
32204 |
+ fork_out: |
32205 |
++ gr_log_forkfail(retval); |
32206 |
++ |
32207 |
+ return ERR_PTR(retval); |
32208 |
+ } |
32209 |
+ |
32210 |
+@@ -1437,6 +1471,8 @@ long do_fork(unsigned long clone_flags, |
32211 |
+ if (clone_flags & CLONE_PARENT_SETTID) |
32212 |
+ put_user(nr, parent_tidptr); |
32213 |
+ |
32214 |
++ gr_handle_brute_check(); |
32215 |
++ |
32216 |
+ if (clone_flags & CLONE_VFORK) { |
32217 |
+ p->vfork_done = &vfork; |
32218 |
+ init_completion(&vfork); |
32219 |
+diff -urNp linux-2.6.24.4/kernel/futex.c linux-2.6.24.4/kernel/futex.c |
32220 |
+--- linux-2.6.24.4/kernel/futex.c 2008-03-24 14:49:18.000000000 -0400 |
32221 |
++++ linux-2.6.24.4/kernel/futex.c 2008-03-26 17:56:56.000000000 -0400 |
32222 |
+@@ -192,6 +192,11 @@ static int get_futex_key(u32 __user *uad |
32223 |
+ struct page *page; |
32224 |
+ int err; |
32225 |
+ |
32226 |
++#ifdef CONFIG_PAX_SEGMEXEC |
32227 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE) |
32228 |
++ return -EFAULT; |
32229 |
++#endif |
32230 |
++ |
32231 |
+ /* |
32232 |
+ * The futex address must be "naturally" aligned. |
32233 |
+ */ |
32234 |
+@@ -218,8 +223,8 @@ static int get_futex_key(u32 __user *uad |
32235 |
+ * The futex is hashed differently depending on whether |
32236 |
+ * it's in a shared or private mapping. So check vma first. |
32237 |
+ */ |
32238 |
+- vma = find_extend_vma(mm, address); |
32239 |
+- if (unlikely(!vma)) |
32240 |
++ vma = find_vma(mm, address); |
32241 |
++ if (unlikely(!vma || address < vma->vm_start)) |
32242 |
+ return -EFAULT; |
32243 |
+ |
32244 |
+ /* |
32245 |
+@@ -1962,7 +1967,7 @@ retry: |
32246 |
+ */ |
32247 |
+ static inline int fetch_robust_entry(struct robust_list __user **entry, |
32248 |
+ struct robust_list __user * __user *head, |
32249 |
+- int *pi) |
32250 |
++ unsigned int *pi) |
32251 |
+ { |
32252 |
+ unsigned long uentry; |
32253 |
+ |
32254 |
+diff -urNp linux-2.6.24.4/kernel/irq/handle.c linux-2.6.24.4/kernel/irq/handle.c |
32255 |
+--- linux-2.6.24.4/kernel/irq/handle.c 2008-03-24 14:49:18.000000000 -0400 |
32256 |
++++ linux-2.6.24.4/kernel/irq/handle.c 2008-03-26 17:56:56.000000000 -0400 |
32257 |
+@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach |
32258 |
+ .depth = 1, |
32259 |
+ .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), |
32260 |
+ #ifdef CONFIG_SMP |
32261 |
+- .affinity = CPU_MASK_ALL |
32262 |
++ .affinity = CPU_MASK_ALL, |
32263 |
++ .cpu = 0, |
32264 |
+ #endif |
32265 |
+ } |
32266 |
+ }; |
32267 |
+diff -urNp linux-2.6.24.4/kernel/kallsyms.c linux-2.6.24.4/kernel/kallsyms.c |
32268 |
+--- linux-2.6.24.4/kernel/kallsyms.c 2008-03-24 14:49:18.000000000 -0400 |
32269 |
++++ linux-2.6.24.4/kernel/kallsyms.c 2008-03-26 17:56:56.000000000 -0400 |
32270 |
+@@ -70,6 +70,19 @@ static inline int is_kernel_text(unsigne |
32271 |
+ |
32272 |
+ static inline int is_kernel(unsigned long addr) |
32273 |
+ { |
32274 |
++ |
32275 |
++#ifdef CONFIG_PAX_KERNEXEC |
32276 |
++ |
32277 |
++#ifdef CONFIG_MODULES |
32278 |
++ if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) && |
32279 |
++ ktla_ktva(addr) < (unsigned long)MODULES_END) |
32280 |
++ return 0; |
32281 |
++#endif |
32282 |
++ |
32283 |
++ if (is_kernel_inittext(addr)) |
32284 |
++ return 1; |
32285 |
++#endif |
32286 |
++ |
32287 |
+ if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end) |
32288 |
+ return 1; |
32289 |
+ return in_gate_area_no_task(addr); |
32290 |
+@@ -378,7 +391,6 @@ static unsigned long get_ksymbol_core(st |
32291 |
+ |
32292 |
+ static void reset_iter(struct kallsym_iter *iter, loff_t new_pos) |
32293 |
+ { |
32294 |
+- iter->name[0] = '\0'; |
32295 |
+ iter->nameoff = get_symbol_offset(new_pos); |
32296 |
+ iter->pos = new_pos; |
32297 |
+ } |
32298 |
+@@ -462,7 +474,7 @@ static int kallsyms_open(struct inode *i |
32299 |
+ struct kallsym_iter *iter; |
32300 |
+ int ret; |
32301 |
+ |
32302 |
+- iter = kmalloc(sizeof(*iter), GFP_KERNEL); |
32303 |
++ iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
32304 |
+ if (!iter) |
32305 |
+ return -ENOMEM; |
32306 |
+ reset_iter(iter, 0); |
32307 |
+@@ -486,7 +498,15 @@ static int __init kallsyms_init(void) |
32308 |
+ { |
32309 |
+ struct proc_dir_entry *entry; |
32310 |
+ |
32311 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
32312 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
32313 |
++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL); |
32314 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
32315 |
++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL); |
32316 |
++#endif |
32317 |
++#else |
32318 |
+ entry = create_proc_entry("kallsyms", 0444, NULL); |
32319 |
++#endif |
32320 |
+ if (entry) |
32321 |
+ entry->proc_fops = &kallsyms_operations; |
32322 |
+ return 0; |
32323 |
+diff -urNp linux-2.6.24.4/kernel/kmod.c linux-2.6.24.4/kernel/kmod.c |
32324 |
+--- linux-2.6.24.4/kernel/kmod.c 2008-03-24 14:49:18.000000000 -0400 |
32325 |
++++ linux-2.6.24.4/kernel/kmod.c 2008-03-26 17:56:56.000000000 -0400 |
32326 |
+@@ -107,7 +107,7 @@ int request_module(const char *fmt, ...) |
32327 |
+ return -ENOMEM; |
32328 |
+ } |
32329 |
+ |
32330 |
+- ret = call_usermodehelper(modprobe_path, argv, envp, 1); |
32331 |
++ ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC); |
32332 |
+ atomic_dec(&kmod_concurrent); |
32333 |
+ return ret; |
32334 |
+ } |
32335 |
+diff -urNp linux-2.6.24.4/kernel/kprobes.c linux-2.6.24.4/kernel/kprobes.c |
32336 |
+--- linux-2.6.24.4/kernel/kprobes.c 2008-03-24 14:49:18.000000000 -0400 |
32337 |
++++ linux-2.6.24.4/kernel/kprobes.c 2008-03-26 17:56:56.000000000 -0400 |
32338 |
+@@ -162,7 +162,7 @@ kprobe_opcode_t __kprobes *get_insn_slot |
32339 |
+ * kernel image and loaded module images reside. This is required |
32340 |
+ * so x86_64 can correctly handle the %rip-relative fixups. |
32341 |
+ */ |
32342 |
+- kip->insns = module_alloc(PAGE_SIZE); |
32343 |
++ kip->insns = module_alloc_exec(PAGE_SIZE); |
32344 |
+ if (!kip->insns) { |
32345 |
+ kfree(kip); |
32346 |
+ return NULL; |
32347 |
+@@ -194,7 +194,7 @@ static int __kprobes collect_one_slot(st |
32348 |
+ hlist_add_head(&kip->hlist, |
32349 |
+ &kprobe_insn_pages); |
32350 |
+ } else { |
32351 |
+- module_free(NULL, kip->insns); |
32352 |
++ module_free_exec(NULL, kip->insns); |
32353 |
+ kfree(kip); |
32354 |
+ } |
32355 |
+ return 1; |
32356 |
+diff -urNp linux-2.6.24.4/kernel/module.c linux-2.6.24.4/kernel/module.c |
32357 |
+--- linux-2.6.24.4/kernel/module.c 2008-03-24 14:49:18.000000000 -0400 |
32358 |
++++ linux-2.6.24.4/kernel/module.c 2008-03-26 17:56:56.000000000 -0400 |
32359 |
+@@ -45,6 +45,11 @@ |
32360 |
+ #include <asm/uaccess.h> |
32361 |
+ #include <asm/semaphore.h> |
32362 |
+ #include <asm/cacheflush.h> |
32363 |
++ |
32364 |
++#ifdef CONFIG_PAX_KERNEXEC |
32365 |
++#include <asm/desc.h> |
32366 |
++#endif |
32367 |
++ |
32368 |
+ #include <linux/license.h> |
32369 |
+ |
32370 |
+ extern int module_sysfs_initialized; |
32371 |
+@@ -69,6 +74,8 @@ static LIST_HEAD(modules); |
32372 |
+ |
32373 |
+ static BLOCKING_NOTIFIER_HEAD(module_notify_list); |
32374 |
+ |
32375 |
++extern int gr_check_modstop(void); |
32376 |
++ |
32377 |
+ int register_module_notifier(struct notifier_block * nb) |
32378 |
+ { |
32379 |
+ return blocking_notifier_chain_register(&module_notify_list, nb); |
32380 |
+@@ -349,7 +356,7 @@ static void *percpu_modalloc(unsigned lo |
32381 |
+ unsigned int i; |
32382 |
+ void *ptr; |
32383 |
+ |
32384 |
+- if (align > PAGE_SIZE) { |
32385 |
++ if (align-1 >= PAGE_SIZE) { |
32386 |
+ printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n", |
32387 |
+ name, align, PAGE_SIZE); |
32388 |
+ align = PAGE_SIZE; |
32389 |
+@@ -662,6 +669,9 @@ sys_delete_module(const char __user *nam |
32390 |
+ char name[MODULE_NAME_LEN]; |
32391 |
+ int ret, forced = 0; |
32392 |
+ |
32393 |
++ if (gr_check_modstop()) |
32394 |
++ return -EPERM; |
32395 |
++ |
32396 |
+ if (!capable(CAP_SYS_MODULE)) |
32397 |
+ return -EPERM; |
32398 |
+ |
32399 |
+@@ -1310,16 +1320,19 @@ static void free_module(struct module *m |
32400 |
+ module_unload_free(mod); |
32401 |
+ |
32402 |
+ /* This may be NULL, but that's OK */ |
32403 |
+- module_free(mod, mod->module_init); |
32404 |
++ module_free(mod, mod->module_init_rw); |
32405 |
++ module_free_exec(mod, mod->module_init_rx); |
32406 |
+ kfree(mod->args); |
32407 |
+ if (mod->percpu) |
32408 |
+ percpu_modfree(mod->percpu); |
32409 |
+ |
32410 |
+ /* Free lock-classes: */ |
32411 |
+- lockdep_free_key_range(mod->module_core, mod->core_size); |
32412 |
++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx); |
32413 |
++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw); |
32414 |
+ |
32415 |
+ /* Finally, free the core (containing the module structure) */ |
32416 |
+- module_free(mod, mod->module_core); |
32417 |
++ module_free_exec(mod, mod->module_core_rx); |
32418 |
++ module_free(mod, mod->module_core_rw); |
32419 |
+ } |
32420 |
+ |
32421 |
+ void *__symbol_get(const char *symbol) |
32422 |
+@@ -1380,10 +1393,14 @@ static int simplify_symbols(Elf_Shdr *se |
32423 |
+ struct module *mod) |
32424 |
+ { |
32425 |
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; |
32426 |
+- unsigned long secbase; |
32427 |
++ unsigned long secbase, symbol; |
32428 |
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym); |
32429 |
+ int ret = 0; |
32430 |
+ |
32431 |
++#ifdef CONFIG_PAX_KERNEXEC |
32432 |
++ unsigned long cr0; |
32433 |
++#endif |
32434 |
++ |
32435 |
+ for (i = 1; i < n; i++) { |
32436 |
+ switch (sym[i].st_shndx) { |
32437 |
+ case SHN_COMMON: |
32438 |
+@@ -1402,10 +1419,19 @@ static int simplify_symbols(Elf_Shdr *se |
32439 |
+ break; |
32440 |
+ |
32441 |
+ case SHN_UNDEF: |
32442 |
+- sym[i].st_value |
32443 |
+- = resolve_symbol(sechdrs, versindex, |
32444 |
++ symbol = resolve_symbol(sechdrs, versindex, |
32445 |
+ strtab + sym[i].st_name, mod); |
32446 |
+ |
32447 |
++#ifdef CONFIG_PAX_KERNEXEC |
32448 |
++ pax_open_kernel(cr0); |
32449 |
++#endif |
32450 |
++ |
32451 |
++ sym[i].st_value = symbol; |
32452 |
++ |
32453 |
++#ifdef CONFIG_PAX_KERNEXEC |
32454 |
++ pax_close_kernel(cr0); |
32455 |
++#endif |
32456 |
++ |
32457 |
+ /* Ok if resolved. */ |
32458 |
+ if (sym[i].st_value != 0) |
32459 |
+ break; |
32460 |
+@@ -1420,11 +1446,27 @@ static int simplify_symbols(Elf_Shdr *se |
32461 |
+ |
32462 |
+ default: |
32463 |
+ /* Divert to percpu allocation if a percpu var. */ |
32464 |
+- if (sym[i].st_shndx == pcpuindex) |
32465 |
++ if (sym[i].st_shndx == pcpuindex) { |
32466 |
++ |
32467 |
++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP) |
32468 |
++ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start; |
32469 |
++#else |
32470 |
+ secbase = (unsigned long)mod->percpu; |
32471 |
+- else |
32472 |
++#endif |
32473 |
++ |
32474 |
++ } else |
32475 |
+ secbase = sechdrs[sym[i].st_shndx].sh_addr; |
32476 |
++ |
32477 |
++#ifdef CONFIG_PAX_KERNEXEC |
32478 |
++ pax_open_kernel(cr0); |
32479 |
++#endif |
32480 |
++ |
32481 |
+ sym[i].st_value += secbase; |
32482 |
++ |
32483 |
++#ifdef CONFIG_PAX_KERNEXEC |
32484 |
++ pax_close_kernel(cr0); |
32485 |
++#endif |
32486 |
++ |
32487 |
+ break; |
32488 |
+ } |
32489 |
+ } |
32490 |
+@@ -1476,11 +1518,14 @@ static void layout_sections(struct modul |
32491 |
+ || strncmp(secstrings + s->sh_name, |
32492 |
+ ".init", 5) == 0) |
32493 |
+ continue; |
32494 |
+- s->sh_entsize = get_offset(&mod->core_size, s); |
32495 |
++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC)) |
32496 |
++ s->sh_entsize = get_offset(&mod->core_size_rw, s); |
32497 |
++ else |
32498 |
++ s->sh_entsize = get_offset(&mod->core_size_rx, s); |
32499 |
+ DEBUGP("\t%s\n", secstrings + s->sh_name); |
32500 |
+ } |
32501 |
+ if (m == 0) |
32502 |
+- mod->core_text_size = mod->core_size; |
32503 |
++ mod->core_size_rx = mod->core_size_rx; |
32504 |
+ } |
32505 |
+ |
32506 |
+ DEBUGP("Init section allocation order:\n"); |
32507 |
+@@ -1494,12 +1539,15 @@ static void layout_sections(struct modul |
32508 |
+ || strncmp(secstrings + s->sh_name, |
32509 |
+ ".init", 5) != 0) |
32510 |
+ continue; |
32511 |
+- s->sh_entsize = (get_offset(&mod->init_size, s) |
32512 |
+- | INIT_OFFSET_MASK); |
32513 |
++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC)) |
32514 |
++ s->sh_entsize = get_offset(&mod->init_size_rw, s); |
32515 |
++ else |
32516 |
++ s->sh_entsize = get_offset(&mod->init_size_rx, s); |
32517 |
++ s->sh_entsize |= INIT_OFFSET_MASK; |
32518 |
+ DEBUGP("\t%s\n", secstrings + s->sh_name); |
32519 |
+ } |
32520 |
+ if (m == 0) |
32521 |
+- mod->init_text_size = mod->init_size; |
32522 |
++ mod->init_size_rx = mod->init_size_rx; |
32523 |
+ } |
32524 |
+ } |
32525 |
+ |
32526 |
+@@ -1626,14 +1674,31 @@ static void add_kallsyms(struct module * |
32527 |
+ { |
32528 |
+ unsigned int i; |
32529 |
+ |
32530 |
++#ifdef CONFIG_PAX_KERNEXEC |
32531 |
++ unsigned long cr0; |
32532 |
++#endif |
32533 |
++ |
32534 |
+ mod->symtab = (void *)sechdrs[symindex].sh_addr; |
32535 |
+ mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym); |
32536 |
+ mod->strtab = (void *)sechdrs[strindex].sh_addr; |
32537 |
+ |
32538 |
+ /* Set types up while we still have access to sections. */ |
32539 |
+- for (i = 0; i < mod->num_symtab; i++) |
32540 |
+- mod->symtab[i].st_info |
32541 |
+- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod); |
32542 |
++ |
32543 |
++ for (i = 0; i < mod->num_symtab; i++) { |
32544 |
++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod); |
32545 |
++ |
32546 |
++#ifdef CONFIG_PAX_KERNEXEC |
32547 |
++ pax_open_kernel(cr0); |
32548 |
++#endif |
32549 |
++ |
32550 |
++ mod->symtab[i].st_info = type; |
32551 |
++ |
32552 |
++#ifdef CONFIG_PAX_KERNEXEC |
32553 |
++ pax_close_kernel(cr0); |
32554 |
++#endif |
32555 |
++ |
32556 |
++ } |
32557 |
++ |
32558 |
+ } |
32559 |
+ #else |
32560 |
+ static inline void add_kallsyms(struct module *mod, |
32561 |
+@@ -1683,6 +1748,10 @@ static struct module *load_module(void _ |
32562 |
+ struct exception_table_entry *extable; |
32563 |
+ mm_segment_t old_fs; |
32564 |
+ |
32565 |
++#ifdef CONFIG_PAX_KERNEXEC |
32566 |
++ unsigned long cr0; |
32567 |
++#endif |
32568 |
++ |
32569 |
+ DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", |
32570 |
+ umod, len, uargs); |
32571 |
+ if (len < sizeof(*hdr)) |
32572 |
+@@ -1841,21 +1910,57 @@ static struct module *load_module(void _ |
32573 |
+ layout_sections(mod, hdr, sechdrs, secstrings); |
32574 |
+ |
32575 |
+ /* Do the allocs. */ |
32576 |
+- ptr = module_alloc(mod->core_size); |
32577 |
++ ptr = module_alloc(mod->core_size_rw); |
32578 |
+ if (!ptr) { |
32579 |
+ err = -ENOMEM; |
32580 |
+ goto free_percpu; |
32581 |
+ } |
32582 |
+- memset(ptr, 0, mod->core_size); |
32583 |
+- mod->module_core = ptr; |
32584 |
++ memset(ptr, 0, mod->core_size_rw); |
32585 |
++ mod->module_core_rw = ptr; |
32586 |
+ |
32587 |
+- ptr = module_alloc(mod->init_size); |
32588 |
+- if (!ptr && mod->init_size) { |
32589 |
++ ptr = module_alloc(mod->init_size_rw); |
32590 |
++ if (!ptr && mod->init_size_rw) { |
32591 |
++ err = -ENOMEM; |
32592 |
++ goto free_core_rw; |
32593 |
++ } |
32594 |
++ memset(ptr, 0, mod->init_size_rw); |
32595 |
++ mod->module_init_rw = ptr; |
32596 |
++ |
32597 |
++ ptr = module_alloc_exec(mod->core_size_rx); |
32598 |
++ if (!ptr) { |
32599 |
+ err = -ENOMEM; |
32600 |
+- goto free_core; |
32601 |
++ goto free_init_rw; |
32602 |
+ } |
32603 |
+- memset(ptr, 0, mod->init_size); |
32604 |
+- mod->module_init = ptr; |
32605 |
++ |
32606 |
++#ifdef CONFIG_PAX_KERNEXEC |
32607 |
++ pax_open_kernel(cr0); |
32608 |
++#endif |
32609 |
++ |
32610 |
++ memset(ptr, 0, mod->core_size_rx); |
32611 |
++ |
32612 |
++#ifdef CONFIG_PAX_KERNEXEC |
32613 |
++ pax_close_kernel(cr0); |
32614 |
++#endif |
32615 |
++ |
32616 |
++ mod->module_core_rx = ptr; |
32617 |
++ |
32618 |
++ ptr = module_alloc_exec(mod->init_size_rx); |
32619 |
++ if (!ptr && mod->init_size_rx) { |
32620 |
++ err = -ENOMEM; |
32621 |
++ goto free_core_rx; |
32622 |
++ } |
32623 |
++ |
32624 |
++#ifdef CONFIG_PAX_KERNEXEC |
32625 |
++ pax_open_kernel(cr0); |
32626 |
++#endif |
32627 |
++ |
32628 |
++ memset(ptr, 0, mod->init_size_rx); |
32629 |
++ |
32630 |
++#ifdef CONFIG_PAX_KERNEXEC |
32631 |
++ pax_close_kernel(cr0); |
32632 |
++#endif |
32633 |
++ |
32634 |
++ mod->module_init_rx = ptr; |
32635 |
+ |
32636 |
+ /* Transfer each section which specifies SHF_ALLOC */ |
32637 |
+ DEBUGP("final section addresses:\n"); |
32638 |
+@@ -1865,17 +1970,41 @@ static struct module *load_module(void _ |
32639 |
+ if (!(sechdrs[i].sh_flags & SHF_ALLOC)) |
32640 |
+ continue; |
32641 |
+ |
32642 |
+- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) |
32643 |
+- dest = mod->module_init |
32644 |
+- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK); |
32645 |
+- else |
32646 |
+- dest = mod->module_core + sechdrs[i].sh_entsize; |
32647 |
++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) { |
32648 |
++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC)) |
32649 |
++ dest = mod->module_init_rw |
32650 |
++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK); |
32651 |
++ else |
32652 |
++ dest = mod->module_init_rx |
32653 |
++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK); |
32654 |
++ } else { |
32655 |
++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC)) |
32656 |
++ dest = mod->module_core_rw + sechdrs[i].sh_entsize; |
32657 |
++ else |
32658 |
++ dest = mod->module_core_rx + sechdrs[i].sh_entsize; |
32659 |
++ } |
32660 |
+ |
32661 |
+- if (sechdrs[i].sh_type != SHT_NOBITS) |
32662 |
+- memcpy(dest, (void *)sechdrs[i].sh_addr, |
32663 |
+- sechdrs[i].sh_size); |
32664 |
++ if (sechdrs[i].sh_type != SHT_NOBITS) { |
32665 |
++ |
32666 |
++#ifdef CONFIG_PAX_KERNEXEC |
32667 |
++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) { |
32668 |
++ pax_open_kernel(cr0); |
32669 |
++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size); |
32670 |
++ pax_close_kernel(cr0); |
32671 |
++ } else |
32672 |
++#endif |
32673 |
++ |
32674 |
++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size); |
32675 |
++ } |
32676 |
+ /* Update sh_addr to point to copy in image. */ |
32677 |
+- sechdrs[i].sh_addr = (unsigned long)dest; |
32678 |
++ |
32679 |
++#ifdef CONFIG_PAX_KERNEXEC |
32680 |
++ if (sechdrs[i].sh_flags & SHF_EXECINSTR) |
32681 |
++ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest); |
32682 |
++ else |
32683 |
++#endif |
32684 |
++ |
32685 |
++ sechdrs[i].sh_addr = (unsigned long)dest; |
32686 |
+ DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name); |
32687 |
+ } |
32688 |
+ /* Module has been moved. */ |
32689 |
+@@ -2009,12 +2138,12 @@ static struct module *load_module(void _ |
32690 |
+ * Do it before processing of module parameters, so the module |
32691 |
+ * can provide parameter accessor functions of its own. |
32692 |
+ */ |
32693 |
+- if (mod->module_init) |
32694 |
+- flush_icache_range((unsigned long)mod->module_init, |
32695 |
+- (unsigned long)mod->module_init |
32696 |
+- + mod->init_size); |
32697 |
+- flush_icache_range((unsigned long)mod->module_core, |
32698 |
+- (unsigned long)mod->module_core + mod->core_size); |
32699 |
++ if (mod->module_init_rx) |
32700 |
++ flush_icache_range((unsigned long)mod->module_init_rx, |
32701 |
++ (unsigned long)mod->module_init_rx |
32702 |
++ + mod->init_size_rx); |
32703 |
++ flush_icache_range((unsigned long)mod->module_core_rx, |
32704 |
++ (unsigned long)mod->module_core_rx + mod->core_size_rx); |
32705 |
+ |
32706 |
+ set_fs(old_fs); |
32707 |
+ |
32708 |
+@@ -2058,9 +2187,13 @@ static struct module *load_module(void _ |
32709 |
+ module_arch_cleanup(mod); |
32710 |
+ cleanup: |
32711 |
+ module_unload_free(mod); |
32712 |
+- module_free(mod, mod->module_init); |
32713 |
+- free_core: |
32714 |
+- module_free(mod, mod->module_core); |
32715 |
++ module_free_exec(mod, mod->module_init_rx); |
32716 |
++ free_core_rx: |
32717 |
++ module_free_exec(mod, mod->module_core_rx); |
32718 |
++ free_init_rw: |
32719 |
++ module_free(mod, mod->module_init_rw); |
32720 |
++ free_core_rw: |
32721 |
++ module_free(mod, mod->module_core_rw); |
32722 |
+ free_percpu: |
32723 |
+ if (percpu) |
32724 |
+ percpu_modfree(percpu); |
32725 |
+@@ -2096,6 +2229,9 @@ sys_init_module(void __user *umod, |
32726 |
+ struct module *mod; |
32727 |
+ int ret = 0; |
32728 |
+ |
32729 |
++ if (gr_check_modstop()) |
32730 |
++ return -EPERM; |
32731 |
++ |
32732 |
+ /* Must have permission */ |
32733 |
+ if (!capable(CAP_SYS_MODULE)) |
32734 |
+ return -EPERM; |
32735 |
+@@ -2142,10 +2278,12 @@ sys_init_module(void __user *umod, |
32736 |
+ /* Drop initial reference. */ |
32737 |
+ module_put(mod); |
32738 |
+ unwind_remove_table(mod->unwind_info, 1); |
32739 |
+- module_free(mod, mod->module_init); |
32740 |
+- mod->module_init = NULL; |
32741 |
+- mod->init_size = 0; |
32742 |
+- mod->init_text_size = 0; |
32743 |
++ module_free(mod, mod->module_init_rw); |
32744 |
++ module_free_exec(mod, mod->module_init_rx); |
32745 |
++ mod->module_init_rw = NULL; |
32746 |
++ mod->module_init_rx = NULL; |
32747 |
++ mod->init_size_rw = 0; |
32748 |
++ mod->init_size_rx = 0; |
32749 |
+ mutex_unlock(&module_mutex); |
32750 |
+ |
32751 |
+ return 0; |
32752 |
+@@ -2153,6 +2291,13 @@ sys_init_module(void __user *umod, |
32753 |
+ |
32754 |
+ static inline int within(unsigned long addr, void *start, unsigned long size) |
32755 |
+ { |
32756 |
++ |
32757 |
++#ifdef CONFIG_PAX_KERNEXEC |
32758 |
++ if (ktla_ktva(addr) >= (unsigned long)start && |
32759 |
++ ktla_ktva(addr) < (unsigned long)start + size) |
32760 |
++ return 1; |
32761 |
++#endif |
32762 |
++ |
32763 |
+ return ((void *)addr >= start && (void *)addr < start + size); |
32764 |
+ } |
32765 |
+ |
32766 |
+@@ -2176,10 +2321,14 @@ static const char *get_ksymbol(struct mo |
32767 |
+ unsigned long nextval; |
32768 |
+ |
32769 |
+ /* At worse, next value is at end of module */ |
32770 |
+- if (within(addr, mod->module_init, mod->init_size)) |
32771 |
+- nextval = (unsigned long)mod->module_init+mod->init_text_size; |
32772 |
++ if (within(addr, mod->module_init_rx, mod->init_size_rx)) |
32773 |
++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx; |
32774 |
++ else if (within(addr, mod->module_init_rw, mod->init_size_rw)) |
32775 |
++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw; |
32776 |
++ else if (within(addr, mod->module_core_rx, mod->core_size_rx)) |
32777 |
++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx; |
32778 |
+ else |
32779 |
+- nextval = (unsigned long)mod->module_core+mod->core_text_size; |
32780 |
++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw; |
32781 |
+ |
32782 |
+ /* Scan for closest preceeding symbol, and next symbol. (ELF |
32783 |
+ starts real symbols at 1). */ |
32784 |
+@@ -2225,8 +2374,10 @@ const char *module_address_lookup(unsign |
32785 |
+ |
32786 |
+ preempt_disable(); |
32787 |
+ list_for_each_entry(mod, &modules, list) { |
32788 |
+- if (within(addr, mod->module_init, mod->init_size) |
32789 |
+- || within(addr, mod->module_core, mod->core_size)) { |
32790 |
++ if (within(addr, mod->module_init_rx, mod->init_size_rx) || |
32791 |
++ within(addr, mod->module_init_rw, mod->init_size_rw) || |
32792 |
++ within(addr, mod->module_core_rx, mod->core_size_rx) || |
32793 |
++ within(addr, mod->module_core_rw, mod->core_size_rw)) { |
32794 |
+ if (modname) |
32795 |
+ *modname = mod->name; |
32796 |
+ ret = get_ksymbol(mod, addr, size, offset); |
32797 |
+@@ -2243,8 +2394,10 @@ int lookup_module_symbol_name(unsigned l |
32798 |
+ |
32799 |
+ preempt_disable(); |
32800 |
+ list_for_each_entry(mod, &modules, list) { |
32801 |
+- if (within(addr, mod->module_init, mod->init_size) || |
32802 |
+- within(addr, mod->module_core, mod->core_size)) { |
32803 |
++ if (within(addr, mod->module_init_rx, mod->init_size_rx) || |
32804 |
++ within(addr, mod->module_init_rw, mod->init_size_rw) || |
32805 |
++ within(addr, mod->module_core_rx, mod->core_size_rx) || |
32806 |
++ within(addr, mod->module_core_rw, mod->core_size_rw)) { |
32807 |
+ const char *sym; |
32808 |
+ |
32809 |
+ sym = get_ksymbol(mod, addr, NULL, NULL); |
32810 |
+@@ -2267,8 +2420,10 @@ int lookup_module_symbol_attrs(unsigned |
32811 |
+ |
32812 |
+ preempt_disable(); |
32813 |
+ list_for_each_entry(mod, &modules, list) { |
32814 |
+- if (within(addr, mod->module_init, mod->init_size) || |
32815 |
+- within(addr, mod->module_core, mod->core_size)) { |
32816 |
++ if (within(addr, mod->module_init_rx, mod->init_size_rx) || |
32817 |
++ within(addr, mod->module_init_rw, mod->init_size_rw) || |
32818 |
++ within(addr, mod->module_core_rx, mod->core_size_rx) || |
32819 |
++ within(addr, mod->module_core_rw, mod->core_size_rw)) { |
32820 |
+ const char *sym; |
32821 |
+ |
32822 |
+ sym = get_ksymbol(mod, addr, size, offset); |
32823 |
+@@ -2390,7 +2545,7 @@ static int m_show(struct seq_file *m, vo |
32824 |
+ char buf[8]; |
32825 |
+ |
32826 |
+ seq_printf(m, "%s %lu", |
32827 |
+- mod->name, mod->init_size + mod->core_size); |
32828 |
++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw); |
32829 |
+ print_unload_info(m, mod); |
32830 |
+ |
32831 |
+ /* Informative for users. */ |
32832 |
+@@ -2399,7 +2554,7 @@ static int m_show(struct seq_file *m, vo |
32833 |
+ mod->state == MODULE_STATE_COMING ? "Loading": |
32834 |
+ "Live"); |
32835 |
+ /* Used by oprofile and other similar tools. */ |
32836 |
+- seq_printf(m, " 0x%p", mod->module_core); |
32837 |
++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw); |
32838 |
+ |
32839 |
+ /* Taints info */ |
32840 |
+ if (mod->taints) |
32841 |
+@@ -2455,7 +2610,8 @@ int is_module_address(unsigned long addr |
32842 |
+ preempt_disable(); |
32843 |
+ |
32844 |
+ list_for_each_entry(mod, &modules, list) { |
32845 |
+- if (within(addr, mod->module_core, mod->core_size)) { |
32846 |
++ if (within(addr, mod->module_core_rx, mod->core_size_rx) || |
32847 |
++ within(addr, mod->module_core_rw, mod->core_size_rw)) { |
32848 |
+ preempt_enable(); |
32849 |
+ return 1; |
32850 |
+ } |
32851 |
+@@ -2473,8 +2629,8 @@ struct module *__module_text_address(uns |
32852 |
+ struct module *mod; |
32853 |
+ |
32854 |
+ list_for_each_entry(mod, &modules, list) |
32855 |
+- if (within(addr, mod->module_init, mod->init_text_size) |
32856 |
+- || within(addr, mod->module_core, mod->core_text_size)) |
32857 |
++ if (within(addr, mod->module_init_rx, mod->init_size_rx) |
32858 |
++ || within(addr, mod->module_core_rx, mod->core_size_rx)) |
32859 |
+ return mod; |
32860 |
+ return NULL; |
32861 |
+ } |
32862 |
+diff -urNp linux-2.6.24.4/kernel/mutex.c linux-2.6.24.4/kernel/mutex.c |
32863 |
+--- linux-2.6.24.4/kernel/mutex.c 2008-03-24 14:49:18.000000000 -0400 |
32864 |
++++ linux-2.6.24.4/kernel/mutex.c 2008-03-26 17:56:56.000000000 -0400 |
32865 |
+@@ -82,7 +82,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou |
32866 |
+ * |
32867 |
+ * This function is similar to (but not equivalent to) down(). |
32868 |
+ */ |
32869 |
+-void inline fastcall __sched mutex_lock(struct mutex *lock) |
32870 |
++inline void fastcall __sched mutex_lock(struct mutex *lock) |
32871 |
+ { |
32872 |
+ might_sleep(); |
32873 |
+ /* |
32874 |
+diff -urNp linux-2.6.24.4/kernel/panic.c linux-2.6.24.4/kernel/panic.c |
32875 |
+--- linux-2.6.24.4/kernel/panic.c 2008-03-24 14:49:18.000000000 -0400 |
32876 |
++++ linux-2.6.24.4/kernel/panic.c 2008-03-26 17:56:56.000000000 -0400 |
32877 |
+@@ -20,6 +20,7 @@ |
32878 |
+ #include <linux/kexec.h> |
32879 |
+ #include <linux/debug_locks.h> |
32880 |
+ #include <linux/random.h> |
32881 |
++#include <linux/kallsyms.h> |
32882 |
+ |
32883 |
+ int panic_on_oops; |
32884 |
+ int tainted; |
32885 |
+@@ -299,6 +300,8 @@ void oops_exit(void) |
32886 |
+ */ |
32887 |
+ void __stack_chk_fail(void) |
32888 |
+ { |
32889 |
++ print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0)); |
32890 |
++ dump_stack(); |
32891 |
+ panic("stack-protector: Kernel stack is corrupted"); |
32892 |
+ } |
32893 |
+ EXPORT_SYMBOL(__stack_chk_fail); |
32894 |
+diff -urNp linux-2.6.24.4/kernel/params.c linux-2.6.24.4/kernel/params.c |
32895 |
+--- linux-2.6.24.4/kernel/params.c 2008-03-24 14:49:18.000000000 -0400 |
32896 |
++++ linux-2.6.24.4/kernel/params.c 2008-03-26 17:56:56.000000000 -0400 |
32897 |
+@@ -272,7 +272,7 @@ static int param_array(const char *name, |
32898 |
+ unsigned int min, unsigned int max, |
32899 |
+ void *elem, int elemsize, |
32900 |
+ int (*set)(const char *, struct kernel_param *kp), |
32901 |
+- int *num) |
32902 |
++ unsigned int *num) |
32903 |
+ { |
32904 |
+ int ret; |
32905 |
+ struct kernel_param kp; |
32906 |
+diff -urNp linux-2.6.24.4/kernel/pid.c linux-2.6.24.4/kernel/pid.c |
32907 |
+--- linux-2.6.24.4/kernel/pid.c 2008-03-24 14:49:18.000000000 -0400 |
32908 |
++++ linux-2.6.24.4/kernel/pid.c 2008-03-26 17:56:56.000000000 -0400 |
32909 |
+@@ -35,6 +35,7 @@ |
32910 |
+ #include <linux/pid_namespace.h> |
32911 |
+ #include <linux/init_task.h> |
32912 |
+ #include <linux/syscalls.h> |
32913 |
++#include <linux/grsecurity.h> |
32914 |
+ |
32915 |
+ #define pid_hashfn(nr, ns) \ |
32916 |
+ hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift) |
32917 |
+@@ -45,7 +46,7 @@ static struct kmem_cache *pid_ns_cachep; |
32918 |
+ |
32919 |
+ int pid_max = PID_MAX_DEFAULT; |
32920 |
+ |
32921 |
+-#define RESERVED_PIDS 300 |
32922 |
++#define RESERVED_PIDS 500 |
32923 |
+ |
32924 |
+ int pid_max_min = RESERVED_PIDS + 1; |
32925 |
+ int pid_max_max = PID_MAX_LIMIT; |
32926 |
+@@ -375,7 +376,14 @@ struct task_struct * fastcall pid_task(s |
32927 |
+ struct task_struct *find_task_by_pid_type_ns(int type, int nr, |
32928 |
+ struct pid_namespace *ns) |
32929 |
+ { |
32930 |
+- return pid_task(find_pid_ns(nr, ns), type); |
32931 |
++ struct task_struct *task; |
32932 |
++ |
32933 |
++ task = pid_task(find_pid_ns(nr, ns), type); |
32934 |
++ |
32935 |
++ if (gr_pid_is_chrooted(task)) |
32936 |
++ return NULL; |
32937 |
++ |
32938 |
++ return task; |
32939 |
+ } |
32940 |
+ |
32941 |
+ EXPORT_SYMBOL(find_task_by_pid_type_ns); |
32942 |
+diff -urNp linux-2.6.24.4/kernel/posix-cpu-timers.c linux-2.6.24.4/kernel/posix-cpu-timers.c |
32943 |
+--- linux-2.6.24.4/kernel/posix-cpu-timers.c 2008-03-24 14:49:18.000000000 -0400 |
32944 |
++++ linux-2.6.24.4/kernel/posix-cpu-timers.c 2008-03-26 17:56:56.000000000 -0400 |
32945 |
+@@ -6,6 +6,7 @@ |
32946 |
+ #include <linux/posix-timers.h> |
32947 |
+ #include <asm/uaccess.h> |
32948 |
+ #include <linux/errno.h> |
32949 |
++#include <linux/grsecurity.h> |
32950 |
+ |
32951 |
+ static int check_clock(const clockid_t which_clock) |
32952 |
+ { |
32953 |
+@@ -1144,6 +1145,7 @@ static void check_process_timers(struct |
32954 |
+ __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); |
32955 |
+ return; |
32956 |
+ } |
32957 |
++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1); |
32958 |
+ if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) { |
32959 |
+ /* |
32960 |
+ * At the soft limit, send a SIGXCPU every second. |
32961 |
+diff -urNp linux-2.6.24.4/kernel/power/poweroff.c linux-2.6.24.4/kernel/power/poweroff.c |
32962 |
+--- linux-2.6.24.4/kernel/power/poweroff.c 2008-03-24 14:49:18.000000000 -0400 |
32963 |
++++ linux-2.6.24.4/kernel/power/poweroff.c 2008-03-26 17:56:56.000000000 -0400 |
32964 |
+@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof |
32965 |
+ .enable_mask = SYSRQ_ENABLE_BOOT, |
32966 |
+ }; |
32967 |
+ |
32968 |
+-static int pm_sysrq_init(void) |
32969 |
++static int __init pm_sysrq_init(void) |
32970 |
+ { |
32971 |
+ register_sysrq_key('o', &sysrq_poweroff_op); |
32972 |
+ return 0; |
32973 |
+diff -urNp linux-2.6.24.4/kernel/printk.c linux-2.6.24.4/kernel/printk.c |
32974 |
+--- linux-2.6.24.4/kernel/printk.c 2008-03-24 14:49:18.000000000 -0400 |
32975 |
++++ linux-2.6.24.4/kernel/printk.c 2008-03-26 17:56:56.000000000 -0400 |
32976 |
+@@ -33,6 +33,7 @@ |
32977 |
+ #include <linux/bootmem.h> |
32978 |
+ #include <linux/syscalls.h> |
32979 |
+ #include <linux/jiffies.h> |
32980 |
++#include <linux/grsecurity.h> |
32981 |
+ |
32982 |
+ #include <asm/uaccess.h> |
32983 |
+ |
32984 |
+@@ -293,6 +294,11 @@ int do_syslog(int type, char __user *buf |
32985 |
+ char c; |
32986 |
+ int error = 0; |
32987 |
+ |
32988 |
++#ifdef CONFIG_GRKERNSEC_DMESG |
32989 |
++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN)) |
32990 |
++ return -EPERM; |
32991 |
++#endif |
32992 |
++ |
32993 |
+ error = security_syslog(type); |
32994 |
+ if (error) |
32995 |
+ return error; |
32996 |
+diff -urNp linux-2.6.24.4/kernel/ptrace.c linux-2.6.24.4/kernel/ptrace.c |
32997 |
+--- linux-2.6.24.4/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400 |
32998 |
++++ linux-2.6.24.4/kernel/ptrace.c 2008-03-26 17:56:56.000000000 -0400 |
32999 |
+@@ -20,6 +20,7 @@ |
33000 |
+ #include <linux/signal.h> |
33001 |
+ #include <linux/audit.h> |
33002 |
+ #include <linux/pid_namespace.h> |
33003 |
++#include <linux/grsecurity.h> |
33004 |
+ |
33005 |
+ #include <asm/pgtable.h> |
33006 |
+ #include <asm/uaccess.h> |
33007 |
+@@ -139,12 +140,12 @@ int __ptrace_may_attach(struct task_stru |
33008 |
+ (current->uid != task->uid) || |
33009 |
+ (current->gid != task->egid) || |
33010 |
+ (current->gid != task->sgid) || |
33011 |
+- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE)) |
33012 |
++ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE)) |
33013 |
+ return -EPERM; |
33014 |
+ smp_rmb(); |
33015 |
+ if (task->mm) |
33016 |
+ dumpable = get_dumpable(task->mm); |
33017 |
+- if (!dumpable && !capable(CAP_SYS_PTRACE)) |
33018 |
++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE)) |
33019 |
+ return -EPERM; |
33020 |
+ |
33021 |
+ return security_ptrace(current, task); |
33022 |
+@@ -203,7 +204,7 @@ repeat: |
33023 |
+ /* Go */ |
33024 |
+ task->ptrace |= PT_PTRACED | ((task->real_parent != current) |
33025 |
+ ? PT_ATTACHED : 0); |
33026 |
+- if (capable(CAP_SYS_PTRACE)) |
33027 |
++ if (capable_nolog(CAP_SYS_PTRACE)) |
33028 |
+ task->ptrace |= PT_PTRACE_CAP; |
33029 |
+ |
33030 |
+ __ptrace_link(task, current); |
33031 |
+@@ -494,6 +495,11 @@ asmlinkage long sys_ptrace(long request, |
33032 |
+ if (ret < 0) |
33033 |
+ goto out_put_task_struct; |
33034 |
+ |
33035 |
++ if (gr_handle_ptrace(child, request)) { |
33036 |
++ ret = -EPERM; |
33037 |
++ goto out_put_task_struct; |
33038 |
++ } |
33039 |
++ |
33040 |
+ ret = arch_ptrace(child, request, addr, data); |
33041 |
+ if (ret < 0) |
33042 |
+ goto out_put_task_struct; |
33043 |
+diff -urNp linux-2.6.24.4/kernel/rcupdate.c linux-2.6.24.4/kernel/rcupdate.c |
33044 |
+--- linux-2.6.24.4/kernel/rcupdate.c 2008-03-24 14:49:18.000000000 -0400 |
33045 |
++++ linux-2.6.24.4/kernel/rcupdate.c 2008-03-26 17:56:56.000000000 -0400 |
33046 |
+@@ -70,11 +70,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk |
33047 |
+ .cpumask = CPU_MASK_NONE, |
33048 |
+ }; |
33049 |
+ |
33050 |
+-DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; |
33051 |
+-DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L }; |
33052 |
++DEFINE_PER_CPU(struct rcu_data, rcu_data); |
33053 |
++DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); |
33054 |
+ |
33055 |
+ /* Fake initialization required by compiler */ |
33056 |
+-static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; |
33057 |
++static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet); |
33058 |
+ static int blimit = 10; |
33059 |
+ static int qhimark = 10000; |
33060 |
+ static int qlowmark = 100; |
33061 |
+diff -urNp linux-2.6.24.4/kernel/relay.c linux-2.6.24.4/kernel/relay.c |
33062 |
+--- linux-2.6.24.4/kernel/relay.c 2008-03-24 14:49:18.000000000 -0400 |
33063 |
++++ linux-2.6.24.4/kernel/relay.c 2008-03-26 17:56:56.000000000 -0400 |
33064 |
+@@ -1141,7 +1141,7 @@ static int subbuf_splice_actor(struct fi |
33065 |
+ return 0; |
33066 |
+ |
33067 |
+ ret = *nonpad_ret = splice_to_pipe(pipe, &spd); |
33068 |
+- if (ret < 0 || ret < total_len) |
33069 |
++ if ((int)ret < 0 || ret < total_len) |
33070 |
+ return ret; |
33071 |
+ |
33072 |
+ if (read_start + ret == nonpad_end) |
33073 |
+diff -urNp linux-2.6.24.4/kernel/resource.c linux-2.6.24.4/kernel/resource.c |
33074 |
+--- linux-2.6.24.4/kernel/resource.c 2008-03-24 14:49:18.000000000 -0400 |
33075 |
++++ linux-2.6.24.4/kernel/resource.c 2008-03-26 17:56:56.000000000 -0400 |
33076 |
+@@ -133,10 +133,27 @@ static int __init ioresources_init(void) |
33077 |
+ { |
33078 |
+ struct proc_dir_entry *entry; |
33079 |
+ |
33080 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
33081 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
33082 |
++ entry = create_proc_entry("ioports", S_IRUSR, NULL); |
33083 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
33084 |
++ entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL); |
33085 |
++#endif |
33086 |
++#else |
33087 |
+ entry = create_proc_entry("ioports", 0, NULL); |
33088 |
++#endif |
33089 |
+ if (entry) |
33090 |
+ entry->proc_fops = &proc_ioports_operations; |
33091 |
++ |
33092 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
33093 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
33094 |
++ entry = create_proc_entry("iomem", S_IRUSR, NULL); |
33095 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
33096 |
++ entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL); |
33097 |
++#endif |
33098 |
++#else |
33099 |
+ entry = create_proc_entry("iomem", 0, NULL); |
33100 |
++#endif |
33101 |
+ if (entry) |
33102 |
+ entry->proc_fops = &proc_iomem_operations; |
33103 |
+ return 0; |
33104 |
+diff -urNp linux-2.6.24.4/kernel/sched.c linux-2.6.24.4/kernel/sched.c |
33105 |
+--- linux-2.6.24.4/kernel/sched.c 2008-03-24 14:49:18.000000000 -0400 |
33106 |
++++ linux-2.6.24.4/kernel/sched.c 2008-03-26 17:56:56.000000000 -0400 |
33107 |
+@@ -63,6 +63,7 @@ |
33108 |
+ #include <linux/reciprocal_div.h> |
33109 |
+ #include <linux/unistd.h> |
33110 |
+ #include <linux/pagemap.h> |
33111 |
++#include <linux/grsecurity.h> |
33112 |
+ |
33113 |
+ #include <asm/tlb.h> |
33114 |
+ #include <asm/irq_regs.h> |
33115 |
+@@ -3619,7 +3620,7 @@ pick_next_task(struct rq *rq, struct tas |
33116 |
+ asmlinkage void __sched schedule(void) |
33117 |
+ { |
33118 |
+ struct task_struct *prev, *next; |
33119 |
+- long *switch_count; |
33120 |
++ unsigned long *switch_count; |
33121 |
+ struct rq *rq; |
33122 |
+ int cpu; |
33123 |
+ |
33124 |
+@@ -4155,7 +4156,8 @@ asmlinkage long sys_nice(int increment) |
33125 |
+ if (nice > 19) |
33126 |
+ nice = 19; |
33127 |
+ |
33128 |
+- if (increment < 0 && !can_nice(current, nice)) |
33129 |
++ if (increment < 0 && (!can_nice(current, nice) || |
33130 |
++ gr_handle_chroot_nice())) |
33131 |
+ return -EPERM; |
33132 |
+ |
33133 |
+ retval = security_task_setnice(current, nice); |
33134 |
+@@ -5396,7 +5398,7 @@ static struct ctl_table sd_ctl_dir[] = { |
33135 |
+ .procname = "sched_domain", |
33136 |
+ .mode = 0555, |
33137 |
+ }, |
33138 |
+- {0, }, |
33139 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }, |
33140 |
+ }; |
33141 |
+ |
33142 |
+ static struct ctl_table sd_ctl_root[] = { |
33143 |
+@@ -5406,7 +5408,7 @@ static struct ctl_table sd_ctl_root[] = |
33144 |
+ .mode = 0555, |
33145 |
+ .child = sd_ctl_dir, |
33146 |
+ }, |
33147 |
+- {0, }, |
33148 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }, |
33149 |
+ }; |
33150 |
+ |
33151 |
+ static struct ctl_table *sd_alloc_ctl_entry(int n) |
33152 |
+diff -urNp linux-2.6.24.4/kernel/signal.c linux-2.6.24.4/kernel/signal.c |
33153 |
+--- linux-2.6.24.4/kernel/signal.c 2008-03-24 14:49:18.000000000 -0400 |
33154 |
++++ linux-2.6.24.4/kernel/signal.c 2008-03-26 17:56:56.000000000 -0400 |
33155 |
+@@ -25,6 +25,7 @@ |
33156 |
+ #include <linux/capability.h> |
33157 |
+ #include <linux/freezer.h> |
33158 |
+ #include <linux/pid_namespace.h> |
33159 |
++#include <linux/grsecurity.h> |
33160 |
+ #include <linux/nsproxy.h> |
33161 |
+ |
33162 |
+ #include <asm/param.h> |
33163 |
+@@ -540,7 +541,9 @@ static int check_kill_permission(int sig |
33164 |
+ && (current->euid ^ t->suid) && (current->euid ^ t->uid) |
33165 |
+ && (current->uid ^ t->suid) && (current->uid ^ t->uid) |
33166 |
+ && !capable(CAP_KILL)) |
33167 |
+- return error; |
33168 |
++ return error; |
33169 |
++ if (gr_handle_signal(t, sig)) |
33170 |
++ return error; |
33171 |
+ } |
33172 |
+ |
33173 |
+ return security_task_kill(t, info, sig, 0); |
33174 |
+@@ -757,7 +760,7 @@ static int __init setup_print_fatal_sign |
33175 |
+ |
33176 |
+ __setup("print-fatal-signals=", setup_print_fatal_signals); |
33177 |
+ |
33178 |
+-static int |
33179 |
++int |
33180 |
+ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) |
33181 |
+ { |
33182 |
+ int ret = 0; |
33183 |
+@@ -811,8 +814,12 @@ force_sig_info(int sig, struct siginfo * |
33184 |
+ } |
33185 |
+ } |
33186 |
+ ret = specific_send_sig_info(sig, info, t); |
33187 |
++ |
33188 |
+ spin_unlock_irqrestore(&t->sighand->siglock, flags); |
33189 |
+ |
33190 |
++ gr_log_signal(sig, t); |
33191 |
++ gr_handle_crash(t, sig); |
33192 |
++ |
33193 |
+ return ret; |
33194 |
+ } |
33195 |
+ |
33196 |
+diff -urNp linux-2.6.24.4/kernel/softirq.c linux-2.6.24.4/kernel/softirq.c |
33197 |
+--- linux-2.6.24.4/kernel/softirq.c 2008-03-24 14:49:18.000000000 -0400 |
33198 |
++++ linux-2.6.24.4/kernel/softirq.c 2008-03-26 17:56:56.000000000 -0400 |
33199 |
+@@ -467,9 +467,9 @@ void tasklet_kill(struct tasklet_struct |
33200 |
+ printk("Attempt to kill tasklet from interrupt\n"); |
33201 |
+ |
33202 |
+ while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { |
33203 |
+- do |
33204 |
++ do { |
33205 |
+ yield(); |
33206 |
+- while (test_bit(TASKLET_STATE_SCHED, &t->state)); |
33207 |
++ } while (test_bit(TASKLET_STATE_SCHED, &t->state)); |
33208 |
+ } |
33209 |
+ tasklet_unlock_wait(t); |
33210 |
+ clear_bit(TASKLET_STATE_SCHED, &t->state); |
33211 |
+diff -urNp linux-2.6.24.4/kernel/sys.c linux-2.6.24.4/kernel/sys.c |
33212 |
+--- linux-2.6.24.4/kernel/sys.c 2008-03-24 14:49:18.000000000 -0400 |
33213 |
++++ linux-2.6.24.4/kernel/sys.c 2008-03-26 17:56:56.000000000 -0400 |
33214 |
+@@ -33,6 +33,7 @@ |
33215 |
+ #include <linux/task_io_accounting_ops.h> |
33216 |
+ #include <linux/seccomp.h> |
33217 |
+ #include <linux/cpu.h> |
33218 |
++#include <linux/grsecurity.h> |
33219 |
+ |
33220 |
+ #include <linux/compat.h> |
33221 |
+ #include <linux/syscalls.h> |
33222 |
+@@ -119,6 +120,12 @@ static int set_one_prio(struct task_stru |
33223 |
+ error = -EACCES; |
33224 |
+ goto out; |
33225 |
+ } |
33226 |
++ |
33227 |
++ if (gr_handle_chroot_setpriority(p, niceval)) { |
33228 |
++ error = -EACCES; |
33229 |
++ goto out; |
33230 |
++ } |
33231 |
++ |
33232 |
+ no_nice = security_task_setnice(p, niceval); |
33233 |
+ if (no_nice) { |
33234 |
+ error = no_nice; |
33235 |
+@@ -175,10 +182,10 @@ asmlinkage long sys_setpriority(int whic |
33236 |
+ if ((who != current->uid) && !(user = find_user(who))) |
33237 |
+ goto out_unlock; /* No processes for this user */ |
33238 |
+ |
33239 |
+- do_each_thread(g, p) |
33240 |
++ do_each_thread(g, p) { |
33241 |
+ if (p->uid == who) |
33242 |
+ error = set_one_prio(p, niceval, error); |
33243 |
+- while_each_thread(g, p); |
33244 |
++ } while_each_thread(g, p); |
33245 |
+ if (who != current->uid) |
33246 |
+ free_uid(user); /* For find_user() */ |
33247 |
+ break; |
33248 |
+@@ -237,13 +244,13 @@ asmlinkage long sys_getpriority(int whic |
33249 |
+ if ((who != current->uid) && !(user = find_user(who))) |
33250 |
+ goto out_unlock; /* No processes for this user */ |
33251 |
+ |
33252 |
+- do_each_thread(g, p) |
33253 |
++ do_each_thread(g, p) { |
33254 |
+ if (p->uid == who) { |
33255 |
+ niceval = 20 - task_nice(p); |
33256 |
+ if (niceval > retval) |
33257 |
+ retval = niceval; |
33258 |
+ } |
33259 |
+- while_each_thread(g, p); |
33260 |
++ } while_each_thread(g, p); |
33261 |
+ if (who != current->uid) |
33262 |
+ free_uid(user); /* for find_user() */ |
33263 |
+ break; |
33264 |
+@@ -515,6 +522,9 @@ asmlinkage long sys_setregid(gid_t rgid, |
33265 |
+ if (rgid != (gid_t) -1 || |
33266 |
+ (egid != (gid_t) -1 && egid != old_rgid)) |
33267 |
+ current->sgid = new_egid; |
33268 |
++ |
33269 |
++ gr_set_role_label(current, current->uid, new_rgid); |
33270 |
++ |
33271 |
+ current->fsgid = new_egid; |
33272 |
+ current->egid = new_egid; |
33273 |
+ current->gid = new_rgid; |
33274 |
+@@ -542,6 +552,9 @@ asmlinkage long sys_setgid(gid_t gid) |
33275 |
+ set_dumpable(current->mm, suid_dumpable); |
33276 |
+ smp_wmb(); |
33277 |
+ } |
33278 |
++ |
33279 |
++ gr_set_role_label(current, current->uid, gid); |
33280 |
++ |
33281 |
+ current->gid = current->egid = current->sgid = current->fsgid = gid; |
33282 |
+ } else if ((gid == current->gid) || (gid == current->sgid)) { |
33283 |
+ if (old_egid != gid) { |
33284 |
+@@ -579,6 +592,9 @@ static int set_user(uid_t new_ruid, int |
33285 |
+ set_dumpable(current->mm, suid_dumpable); |
33286 |
+ smp_wmb(); |
33287 |
+ } |
33288 |
++ |
33289 |
++ gr_set_role_label(current, new_ruid, current->gid); |
33290 |
++ |
33291 |
+ current->uid = new_ruid; |
33292 |
+ return 0; |
33293 |
+ } |
33294 |
+@@ -681,6 +697,9 @@ asmlinkage long sys_setuid(uid_t uid) |
33295 |
+ } else if ((uid != current->uid) && (uid != new_suid)) |
33296 |
+ return -EPERM; |
33297 |
+ |
33298 |
++ if (gr_check_crash_uid(uid)) |
33299 |
++ return -EPERM; |
33300 |
++ |
33301 |
+ if (old_euid != uid) { |
33302 |
+ set_dumpable(current->mm, suid_dumpable); |
33303 |
+ smp_wmb(); |
33304 |
+@@ -783,8 +802,10 @@ asmlinkage long sys_setresgid(gid_t rgid |
33305 |
+ current->egid = egid; |
33306 |
+ } |
33307 |
+ current->fsgid = current->egid; |
33308 |
+- if (rgid != (gid_t) -1) |
33309 |
++ if (rgid != (gid_t) -1) { |
33310 |
++ gr_set_role_label(current, current->uid, rgid); |
33311 |
+ current->gid = rgid; |
33312 |
++ } |
33313 |
+ if (sgid != (gid_t) -1) |
33314 |
+ current->sgid = sgid; |
33315 |
+ |
33316 |
+@@ -934,7 +955,10 @@ asmlinkage long sys_setpgid(pid_t pid, p |
33317 |
+ write_lock_irq(&tasklist_lock); |
33318 |
+ |
33319 |
+ err = -ESRCH; |
33320 |
+- p = find_task_by_pid_ns(pid, ns); |
33321 |
++ /* grsec: replaced find_task_by_pid_ns with equivalent call which |
33322 |
++ lacks the chroot restriction |
33323 |
++ */ |
33324 |
++ p = pid_task(find_pid_ns(pid, ns), PIDTYPE_PID); |
33325 |
+ if (!p) |
33326 |
+ goto out; |
33327 |
+ |
33328 |
+@@ -1662,7 +1686,7 @@ asmlinkage long sys_prctl(int option, un |
33329 |
+ error = get_dumpable(current->mm); |
33330 |
+ break; |
33331 |
+ case PR_SET_DUMPABLE: |
33332 |
+- if (arg2 < 0 || arg2 > 1) { |
33333 |
++ if (arg2 > 1) { |
33334 |
+ error = -EINVAL; |
33335 |
+ break; |
33336 |
+ } |
33337 |
+diff -urNp linux-2.6.24.4/kernel/sysctl.c linux-2.6.24.4/kernel/sysctl.c |
33338 |
+--- linux-2.6.24.4/kernel/sysctl.c 2008-03-24 14:49:18.000000000 -0400 |
33339 |
++++ linux-2.6.24.4/kernel/sysctl.c 2008-03-26 17:56:56.000000000 -0400 |
33340 |
+@@ -58,6 +58,13 @@ |
33341 |
+ static int deprecated_sysctl_warning(struct __sysctl_args *args); |
33342 |
+ |
33343 |
+ #if defined(CONFIG_SYSCTL) |
33344 |
++#include <linux/grsecurity.h> |
33345 |
++#include <linux/grinternal.h> |
33346 |
++ |
33347 |
++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op); |
33348 |
++extern int gr_handle_sysctl_mod(const char *dirname, const char *name, |
33349 |
++ const int op); |
33350 |
++extern int gr_handle_chroot_sysctl(const int op); |
33351 |
+ |
33352 |
+ /* External variables not in a header file. */ |
33353 |
+ extern int C_A_D; |
33354 |
+@@ -154,10 +161,11 @@ static int proc_do_cad_pid(struct ctl_ta |
33355 |
+ static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, |
33356 |
+ void __user *buffer, size_t *lenp, loff_t *ppos); |
33357 |
+ #endif |
33358 |
++extern ctl_table grsecurity_table[]; |
33359 |
+ |
33360 |
+ static struct ctl_table root_table[]; |
33361 |
+ static struct ctl_table_header root_table_header = |
33362 |
+- { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; |
33363 |
++ { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry), 0, NULL }; |
33364 |
+ |
33365 |
+ static struct ctl_table kern_table[]; |
33366 |
+ static struct ctl_table vm_table[]; |
33367 |
+@@ -173,6 +181,21 @@ extern struct ctl_table inotify_table[]; |
33368 |
+ int sysctl_legacy_va_layout; |
33369 |
+ #endif |
33370 |
+ |
33371 |
++#ifdef CONFIG_PAX_SOFTMODE |
33372 |
++static ctl_table pax_table[] = { |
33373 |
++ { |
33374 |
++ .ctl_name = CTL_UNNUMBERED, |
33375 |
++ .procname = "softmode", |
33376 |
++ .data = &pax_softmode, |
33377 |
++ .maxlen = sizeof(unsigned int), |
33378 |
++ .mode = 0600, |
33379 |
++ .proc_handler = &proc_dointvec, |
33380 |
++ }, |
33381 |
++ |
33382 |
++ { .ctl_name = 0 } |
33383 |
++}; |
33384 |
++#endif |
33385 |
++ |
33386 |
+ extern int prove_locking; |
33387 |
+ extern int lock_stat; |
33388 |
+ |
33389 |
+@@ -217,6 +240,16 @@ static struct ctl_table root_table[] = { |
33390 |
+ .mode = 0555, |
33391 |
+ .child = dev_table, |
33392 |
+ }, |
33393 |
++ |
33394 |
++#ifdef CONFIG_PAX_SOFTMODE |
33395 |
++ { |
33396 |
++ .ctl_name = CTL_UNNUMBERED, |
33397 |
++ .procname = "pax", |
33398 |
++ .mode = 0500, |
33399 |
++ .child = pax_table, |
33400 |
++ }, |
33401 |
++#endif |
33402 |
++ |
33403 |
+ /* |
33404 |
+ * NOTE: do not add new entries to this table unless you have read |
33405 |
+ * Documentation/sysctl/ctl_unnumbered.txt |
33406 |
+@@ -775,6 +808,14 @@ static struct ctl_table kern_table[] = { |
33407 |
+ .proc_handler = &proc_dostring, |
33408 |
+ .strategy = &sysctl_string, |
33409 |
+ }, |
33410 |
++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP) |
33411 |
++ { |
33412 |
++ .ctl_name = CTL_UNNUMBERED, |
33413 |
++ .procname = "grsecurity", |
33414 |
++ .mode = 0500, |
33415 |
++ .child = grsecurity_table, |
33416 |
++ }, |
33417 |
++#endif |
33418 |
+ /* |
33419 |
+ * NOTE: do not add new entries to this table unless you have read |
33420 |
+ * Documentation/sysctl/ctl_unnumbered.txt |
33421 |
+@@ -1394,6 +1435,25 @@ static int test_perm(int mode, int op) |
33422 |
+ int sysctl_perm(struct ctl_table *table, int op) |
33423 |
+ { |
33424 |
+ int error; |
33425 |
++ if (table->parent != NULL && table->parent->procname != NULL && |
33426 |
++ table->procname != NULL && |
33427 |
++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op)) |
33428 |
++ return -EACCES; |
33429 |
++ if (gr_handle_chroot_sysctl(op)) |
33430 |
++ return -EACCES; |
33431 |
++ error = gr_handle_sysctl(table, op); |
33432 |
++ if (error) |
33433 |
++ return error; |
33434 |
++ error = security_sysctl(table, op); |
33435 |
++ if (error) |
33436 |
++ return error; |
33437 |
++ return test_perm(table->mode, op); |
33438 |
++} |
33439 |
++ |
33440 |
++int sysctl_perm_nochk(ctl_table *table, int op) |
33441 |
++{ |
33442 |
++ int error; |
33443 |
++ |
33444 |
+ error = security_sysctl(table, op); |
33445 |
+ if (error) |
33446 |
+ return error; |
33447 |
+@@ -1418,13 +1478,14 @@ repeat: |
33448 |
+ if (n == table->ctl_name) { |
33449 |
+ int error; |
33450 |
+ if (table->child) { |
33451 |
+- if (sysctl_perm(table, 001)) |
33452 |
++ if (sysctl_perm_nochk(table, 001)) |
33453 |
+ return -EPERM; |
33454 |
+ name++; |
33455 |
+ nlen--; |
33456 |
+ table = table->child; |
33457 |
+ goto repeat; |
33458 |
+ } |
33459 |
++ |
33460 |
+ error = do_sysctl_strategy(table, name, nlen, |
33461 |
+ oldval, oldlenp, |
33462 |
+ newval, newlen); |
33463 |
+diff -urNp linux-2.6.24.4/kernel/time.c linux-2.6.24.4/kernel/time.c |
33464 |
+--- linux-2.6.24.4/kernel/time.c 2008-03-24 14:49:18.000000000 -0400 |
33465 |
++++ linux-2.6.24.4/kernel/time.c 2008-03-26 17:56:56.000000000 -0400 |
33466 |
+@@ -35,6 +35,7 @@ |
33467 |
+ #include <linux/syscalls.h> |
33468 |
+ #include <linux/security.h> |
33469 |
+ #include <linux/fs.h> |
33470 |
++#include <linux/grsecurity.h> |
33471 |
+ |
33472 |
+ #include <asm/uaccess.h> |
33473 |
+ #include <asm/unistd.h> |
33474 |
+@@ -88,6 +89,9 @@ asmlinkage long sys_stime(time_t __user |
33475 |
+ return err; |
33476 |
+ |
33477 |
+ do_settimeofday(&tv); |
33478 |
++ |
33479 |
++ gr_log_timechange(); |
33480 |
++ |
33481 |
+ return 0; |
33482 |
+ } |
33483 |
+ |
33484 |
+@@ -194,6 +198,8 @@ asmlinkage long sys_settimeofday(struct |
33485 |
+ return -EFAULT; |
33486 |
+ } |
33487 |
+ |
33488 |
++ gr_log_timechange(); |
33489 |
++ |
33490 |
+ return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL); |
33491 |
+ } |
33492 |
+ |
33493 |
+@@ -232,7 +238,7 @@ EXPORT_SYMBOL(current_fs_time); |
33494 |
+ * Avoid unnecessary multiplications/divisions in the |
33495 |
+ * two most common HZ cases: |
33496 |
+ */ |
33497 |
+-unsigned int inline jiffies_to_msecs(const unsigned long j) |
33498 |
++inline unsigned int jiffies_to_msecs(const unsigned long j) |
33499 |
+ { |
33500 |
+ #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) |
33501 |
+ return (MSEC_PER_SEC / HZ) * j; |
33502 |
+@@ -244,7 +250,7 @@ unsigned int inline jiffies_to_msecs(con |
33503 |
+ } |
33504 |
+ EXPORT_SYMBOL(jiffies_to_msecs); |
33505 |
+ |
33506 |
+-unsigned int inline jiffies_to_usecs(const unsigned long j) |
33507 |
++inline unsigned int jiffies_to_usecs(const unsigned long j) |
33508 |
+ { |
33509 |
+ #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) |
33510 |
+ return (USEC_PER_SEC / HZ) * j; |
33511 |
+diff -urNp linux-2.6.24.4/kernel/utsname_sysctl.c linux-2.6.24.4/kernel/utsname_sysctl.c |
33512 |
+--- linux-2.6.24.4/kernel/utsname_sysctl.c 2008-03-24 14:49:18.000000000 -0400 |
33513 |
++++ linux-2.6.24.4/kernel/utsname_sysctl.c 2008-03-26 17:56:56.000000000 -0400 |
33514 |
+@@ -125,7 +125,7 @@ static struct ctl_table uts_kern_table[] |
33515 |
+ .proc_handler = proc_do_uts_string, |
33516 |
+ .strategy = sysctl_uts_string, |
33517 |
+ }, |
33518 |
+- {} |
33519 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
33520 |
+ }; |
33521 |
+ |
33522 |
+ static struct ctl_table uts_root_table[] = { |
33523 |
+@@ -135,7 +135,7 @@ static struct ctl_table uts_root_table[] |
33524 |
+ .mode = 0555, |
33525 |
+ .child = uts_kern_table, |
33526 |
+ }, |
33527 |
+- {} |
33528 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
33529 |
+ }; |
33530 |
+ |
33531 |
+ static int __init utsname_sysctl_init(void) |
33532 |
+diff -urNp linux-2.6.24.4/lib/radix-tree.c linux-2.6.24.4/lib/radix-tree.c |
33533 |
+--- linux-2.6.24.4/lib/radix-tree.c 2008-03-24 14:49:18.000000000 -0400 |
33534 |
++++ linux-2.6.24.4/lib/radix-tree.c 2008-03-26 17:56:56.000000000 -0400 |
33535 |
+@@ -81,7 +81,7 @@ struct radix_tree_preload { |
33536 |
+ int nr; |
33537 |
+ struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH]; |
33538 |
+ }; |
33539 |
+-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; |
33540 |
++DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} }; |
33541 |
+ |
33542 |
+ static inline gfp_t root_gfp_mask(struct radix_tree_root *root) |
33543 |
+ { |
33544 |
+diff -urNp linux-2.6.24.4/localversion-grsec linux-2.6.24.4/localversion-grsec |
33545 |
+--- linux-2.6.24.4/localversion-grsec 1969-12-31 19:00:00.000000000 -0500 |
33546 |
++++ linux-2.6.24.4/localversion-grsec 2008-03-26 17:56:56.000000000 -0400 |
33547 |
+@@ -0,0 +1 @@ |
33548 |
++-grsec |
33549 |
+diff -urNp linux-2.6.24.4/Makefile linux-2.6.24.4/Makefile |
33550 |
+--- linux-2.6.24.4/Makefile 2008-03-24 14:49:18.000000000 -0400 |
33551 |
++++ linux-2.6.24.4/Makefile 2008-03-26 17:56:55.000000000 -0400 |
33552 |
+@@ -214,7 +214,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" |
33553 |
+ |
33554 |
+ HOSTCC = gcc |
33555 |
+ HOSTCXX = g++ |
33556 |
+-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer |
33557 |
++HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer |
33558 |
+ HOSTCXXFLAGS = -O2 |
33559 |
+ |
33560 |
+ # Decide whether to build built-in, modular, or both. |
33561 |
+@@ -507,6 +507,9 @@ else |
33562 |
+ KBUILD_CFLAGS += -O2 |
33563 |
+ endif |
33564 |
+ |
33565 |
++# Force gcc to behave correct even for buggy distributions |
33566 |
++KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) |
33567 |
++ |
33568 |
+ include $(srctree)/arch/$(SRCARCH)/Makefile |
33569 |
+ |
33570 |
+ ifdef CONFIG_FRAME_POINTER |
33571 |
+@@ -520,9 +523,6 @@ KBUILD_CFLAGS += -g |
33572 |
+ KBUILD_AFLAGS += -gdwarf-2 |
33573 |
+ endif |
33574 |
+ |
33575 |
+-# Force gcc to behave correct even for buggy distributions |
33576 |
+-KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) |
33577 |
+- |
33578 |
+ # arch Makefile may override CC so keep this after arch Makefile is included |
33579 |
+ NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) |
33580 |
+ CHECKFLAGS += $(NOSTDINC_FLAGS) |
33581 |
+@@ -597,7 +597,7 @@ export mod_strip_cmd |
33582 |
+ |
33583 |
+ |
33584 |
+ ifeq ($(KBUILD_EXTMOD),) |
33585 |
+-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ |
33586 |
++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/ |
33587 |
+ |
33588 |
+ vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \ |
33589 |
+ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ |
33590 |
+diff -urNp linux-2.6.24.4/mm/filemap.c linux-2.6.24.4/mm/filemap.c |
33591 |
+--- linux-2.6.24.4/mm/filemap.c 2008-03-24 14:49:18.000000000 -0400 |
33592 |
++++ linux-2.6.24.4/mm/filemap.c 2008-03-26 17:56:56.000000000 -0400 |
33593 |
+@@ -33,6 +33,7 @@ |
33594 |
+ #include <linux/syscalls.h> |
33595 |
+ #include <linux/cpuset.h> |
33596 |
+ #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */ |
33597 |
++#include <linux/grsecurity.h> |
33598 |
+ #include "internal.h" |
33599 |
+ |
33600 |
+ /* |
33601 |
+@@ -1461,7 +1462,7 @@ int generic_file_mmap(struct file * file |
33602 |
+ struct address_space *mapping = file->f_mapping; |
33603 |
+ |
33604 |
+ if (!mapping->a_ops->readpage) |
33605 |
+- return -ENOEXEC; |
33606 |
++ return -ENODEV; |
33607 |
+ file_accessed(file); |
33608 |
+ vma->vm_ops = &generic_file_vm_ops; |
33609 |
+ vma->vm_flags |= VM_CAN_NONLINEAR; |
33610 |
+@@ -1810,6 +1811,7 @@ inline int generic_write_checks(struct f |
33611 |
+ *pos = i_size_read(inode); |
33612 |
+ |
33613 |
+ if (limit != RLIM_INFINITY) { |
33614 |
++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0); |
33615 |
+ if (*pos >= limit) { |
33616 |
+ send_sig(SIGXFSZ, current, 0); |
33617 |
+ return -EFBIG; |
33618 |
+diff -urNp linux-2.6.24.4/mm/fremap.c linux-2.6.24.4/mm/fremap.c |
33619 |
+--- linux-2.6.24.4/mm/fremap.c 2008-03-24 14:49:18.000000000 -0400 |
33620 |
++++ linux-2.6.24.4/mm/fremap.c 2008-03-26 17:56:56.000000000 -0400 |
33621 |
+@@ -150,6 +150,13 @@ asmlinkage long sys_remap_file_pages(uns |
33622 |
+ retry: |
33623 |
+ vma = find_vma(mm, start); |
33624 |
+ |
33625 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33626 |
++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) { |
33627 |
++ up_read(&mm->mmap_sem); |
33628 |
++ return err; |
33629 |
++ } |
33630 |
++#endif |
33631 |
++ |
33632 |
+ /* |
33633 |
+ * Make sure the vma is shared, that it supports prefaulting, |
33634 |
+ * and that the remapped range is valid and fully within |
33635 |
+diff -urNp linux-2.6.24.4/mm/hugetlb.c linux-2.6.24.4/mm/hugetlb.c |
33636 |
+--- linux-2.6.24.4/mm/hugetlb.c 2008-03-24 14:49:18.000000000 -0400 |
33637 |
++++ linux-2.6.24.4/mm/hugetlb.c 2008-03-26 17:56:56.000000000 -0400 |
33638 |
+@@ -797,6 +797,26 @@ void unmap_hugepage_range(struct vm_area |
33639 |
+ } |
33640 |
+ } |
33641 |
+ |
33642 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33643 |
++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m) |
33644 |
++{ |
33645 |
++ struct mm_struct *mm = vma->vm_mm; |
33646 |
++ struct vm_area_struct *vma_m; |
33647 |
++ unsigned long address_m; |
33648 |
++ pte_t *ptep_m; |
33649 |
++ |
33650 |
++ vma_m = pax_find_mirror_vma(vma); |
33651 |
++ if (!vma_m) |
33652 |
++ return; |
33653 |
++ |
33654 |
++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); |
33655 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
33656 |
++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK); |
33657 |
++ get_page(page_m); |
33658 |
++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0)); |
33659 |
++} |
33660 |
++#endif |
33661 |
++ |
33662 |
+ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, |
33663 |
+ unsigned long address, pte_t *ptep, pte_t pte) |
33664 |
+ { |
33665 |
+@@ -830,6 +850,11 @@ static int hugetlb_cow(struct mm_struct |
33666 |
+ /* Break COW */ |
33667 |
+ set_huge_pte_at(mm, address, ptep, |
33668 |
+ make_huge_pte(vma, new_page, 1)); |
33669 |
++ |
33670 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33671 |
++ pax_mirror_huge_pte(vma, address, new_page); |
33672 |
++#endif |
33673 |
++ |
33674 |
+ /* Make the old page be freed below */ |
33675 |
+ new_page = old_page; |
33676 |
+ } |
33677 |
+@@ -901,6 +926,10 @@ retry: |
33678 |
+ && (vma->vm_flags & VM_SHARED))); |
33679 |
+ set_huge_pte_at(mm, address, ptep, new_pte); |
33680 |
+ |
33681 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33682 |
++ pax_mirror_huge_pte(vma, address, page); |
33683 |
++#endif |
33684 |
++ |
33685 |
+ if (write_access && !(vma->vm_flags & VM_SHARED)) { |
33686 |
+ /* Optimization, do the COW without a second fault */ |
33687 |
+ ret = hugetlb_cow(mm, vma, address, ptep, new_pte); |
33688 |
+@@ -926,6 +955,27 @@ int hugetlb_fault(struct mm_struct *mm, |
33689 |
+ int ret; |
33690 |
+ static DEFINE_MUTEX(hugetlb_instantiation_mutex); |
33691 |
+ |
33692 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33693 |
++ struct vm_area_struct *vma_m; |
33694 |
++ |
33695 |
++ vma_m = pax_find_mirror_vma(vma); |
33696 |
++ if (vma_m) { |
33697 |
++ unsigned long address_m; |
33698 |
++ |
33699 |
++ if (vma->vm_start > vma_m->vm_start) { |
33700 |
++ address_m = address; |
33701 |
++ address -= SEGMEXEC_TASK_SIZE; |
33702 |
++ vma = vma_m; |
33703 |
++ } else |
33704 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
33705 |
++ |
33706 |
++ if (!huge_pte_alloc(mm, address_m)) |
33707 |
++ return VM_FAULT_OOM; |
33708 |
++ address_m &= HPAGE_MASK; |
33709 |
++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE); |
33710 |
++ } |
33711 |
++#endif |
33712 |
++ |
33713 |
+ ptep = huge_pte_alloc(mm, address); |
33714 |
+ if (!ptep) |
33715 |
+ return VM_FAULT_OOM; |
33716 |
+diff -urNp linux-2.6.24.4/mm/madvise.c linux-2.6.24.4/mm/madvise.c |
33717 |
+--- linux-2.6.24.4/mm/madvise.c 2008-03-24 14:49:18.000000000 -0400 |
33718 |
++++ linux-2.6.24.4/mm/madvise.c 2008-03-26 17:56:56.000000000 -0400 |
33719 |
+@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a |
33720 |
+ pgoff_t pgoff; |
33721 |
+ int new_flags = vma->vm_flags; |
33722 |
+ |
33723 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33724 |
++ struct vm_area_struct *vma_m; |
33725 |
++#endif |
33726 |
++ |
33727 |
+ switch (behavior) { |
33728 |
+ case MADV_NORMAL: |
33729 |
+ new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ; |
33730 |
+@@ -92,6 +96,13 @@ success: |
33731 |
+ /* |
33732 |
+ * vm_flags is protected by the mmap_sem held in write mode. |
33733 |
+ */ |
33734 |
++ |
33735 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33736 |
++ vma_m = pax_find_mirror_vma(vma); |
33737 |
++ if (vma_m) |
33738 |
++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT); |
33739 |
++#endif |
33740 |
++ |
33741 |
+ vma->vm_flags = new_flags; |
33742 |
+ |
33743 |
+ out: |
33744 |
+@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma, |
33745 |
+ |
33746 |
+ case MADV_DONTNEED: |
33747 |
+ error = madvise_dontneed(vma, prev, start, end); |
33748 |
++ |
33749 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33750 |
++ if (!error) { |
33751 |
++ struct vm_area_struct *vma_m, *prev_m; |
33752 |
++ |
33753 |
++ vma_m = pax_find_mirror_vma(vma); |
33754 |
++ if (vma_m) |
33755 |
++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE); |
33756 |
++ } |
33757 |
++#endif |
33758 |
++ |
33759 |
+ break; |
33760 |
+ |
33761 |
+ default: |
33762 |
+@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon |
33763 |
+ if (end < start) |
33764 |
+ goto out; |
33765 |
+ |
33766 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33767 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { |
33768 |
++ if (end > SEGMEXEC_TASK_SIZE) |
33769 |
++ goto out; |
33770 |
++ } else |
33771 |
++#endif |
33772 |
++ |
33773 |
++ if (end > TASK_SIZE) |
33774 |
++ goto out; |
33775 |
++ |
33776 |
+ error = 0; |
33777 |
+ if (end == start) |
33778 |
+ goto out; |
33779 |
+diff -urNp linux-2.6.24.4/mm/memory.c linux-2.6.24.4/mm/memory.c |
33780 |
+--- linux-2.6.24.4/mm/memory.c 2008-03-24 14:49:18.000000000 -0400 |
33781 |
++++ linux-2.6.24.4/mm/memory.c 2008-03-26 17:56:56.000000000 -0400 |
33782 |
+@@ -50,6 +50,7 @@ |
33783 |
+ #include <linux/delayacct.h> |
33784 |
+ #include <linux/init.h> |
33785 |
+ #include <linux/writeback.h> |
33786 |
++#include <linux/grsecurity.h> |
33787 |
+ |
33788 |
+ #include <asm/pgalloc.h> |
33789 |
+ #include <asm/uaccess.h> |
33790 |
+@@ -990,11 +991,11 @@ int get_user_pages(struct task_struct *t |
33791 |
+ vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE); |
33792 |
+ i = 0; |
33793 |
+ |
33794 |
+- do { |
33795 |
++ while (len) { |
33796 |
+ struct vm_area_struct *vma; |
33797 |
+ unsigned int foll_flags; |
33798 |
+ |
33799 |
+- vma = find_extend_vma(mm, start); |
33800 |
++ vma = find_vma(mm, start); |
33801 |
+ if (!vma && in_gate_area(tsk, start)) { |
33802 |
+ unsigned long pg = start & PAGE_MASK; |
33803 |
+ struct vm_area_struct *gate_vma = get_gate_vma(tsk); |
33804 |
+@@ -1034,7 +1035,7 @@ int get_user_pages(struct task_struct *t |
33805 |
+ continue; |
33806 |
+ } |
33807 |
+ |
33808 |
+- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP)) |
33809 |
++ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP)) |
33810 |
+ || !(vm_flags & vma->vm_flags)) |
33811 |
+ return i ? : -EFAULT; |
33812 |
+ |
33813 |
+@@ -1107,7 +1108,7 @@ int get_user_pages(struct task_struct *t |
33814 |
+ start += PAGE_SIZE; |
33815 |
+ len--; |
33816 |
+ } while (len && start < vma->vm_end); |
33817 |
+- } while (len); |
33818 |
++ } |
33819 |
+ return i; |
33820 |
+ } |
33821 |
+ EXPORT_SYMBOL(get_user_pages); |
33822 |
+@@ -1526,6 +1527,196 @@ static inline void cow_user_page(struct |
33823 |
+ copy_user_highpage(dst, src, va, vma); |
33824 |
+ } |
33825 |
+ |
33826 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33827 |
++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd) |
33828 |
++{ |
33829 |
++ struct mm_struct *mm = vma->vm_mm; |
33830 |
++ spinlock_t *ptl; |
33831 |
++ pte_t *pte, entry; |
33832 |
++ |
33833 |
++ pte = pte_offset_map_lock(mm, pmd, address, &ptl); |
33834 |
++ entry = *pte; |
33835 |
++ if (!pte_present(entry)) { |
33836 |
++ if (!pte_none(entry)) { |
33837 |
++ BUG_ON(pte_file(entry)); |
33838 |
++ free_swap_and_cache(pte_to_swp_entry(entry)); |
33839 |
++ pte_clear_not_present_full(mm, address, pte, 0); |
33840 |
++ } |
33841 |
++ } else { |
33842 |
++ struct page *page; |
33843 |
++ |
33844 |
++ page = vm_normal_page(vma, address, entry); |
33845 |
++ if (page) { |
33846 |
++ flush_cache_page(vma, address, pte_pfn(entry)); |
33847 |
++ flush_icache_page(vma, page); |
33848 |
++ } |
33849 |
++ ptep_clear_flush(vma, address, pte); |
33850 |
++ BUG_ON(pte_dirty(entry)); |
33851 |
++ if (page) { |
33852 |
++ update_hiwater_rss(mm); |
33853 |
++ if (PageAnon(page)) |
33854 |
++ dec_mm_counter(mm, anon_rss); |
33855 |
++ else |
33856 |
++ dec_mm_counter(mm, file_rss); |
33857 |
++ page_remove_rmap(page, vma); |
33858 |
++ page_cache_release(page); |
33859 |
++ } |
33860 |
++ } |
33861 |
++ pte_unmap_unlock(pte, ptl); |
33862 |
++} |
33863 |
++ |
33864 |
++/* PaX: if vma is mirrored, synchronize the mirror's PTE |
33865 |
++ * |
33866 |
++ * the ptl of the lower mapped page is held on entry and is not released on exit |
33867 |
++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc) |
33868 |
++ */ |
33869 |
++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl) |
33870 |
++{ |
33871 |
++ struct mm_struct *mm = vma->vm_mm; |
33872 |
++ unsigned long address_m; |
33873 |
++ spinlock_t *ptl_m; |
33874 |
++ struct vm_area_struct *vma_m; |
33875 |
++ pmd_t *pmd_m; |
33876 |
++ pte_t *pte_m, entry_m; |
33877 |
++ |
33878 |
++ BUG_ON(!page_m || !PageAnon(page_m)); |
33879 |
++ |
33880 |
++ vma_m = pax_find_mirror_vma(vma); |
33881 |
++ if (!vma_m) |
33882 |
++ return; |
33883 |
++ |
33884 |
++ BUG_ON(!PageLocked(page_m)); |
33885 |
++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); |
33886 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
33887 |
++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m); |
33888 |
++ pte_m = pte_offset_map_nested(pmd_m, address_m); |
33889 |
++ ptl_m = pte_lockptr(mm, pmd_m); |
33890 |
++ if (ptl != ptl_m) { |
33891 |
++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING); |
33892 |
++ if (!pte_none(*pte_m)) { |
33893 |
++ spin_unlock(ptl_m); |
33894 |
++ pte_unmap_nested(pte_m); |
33895 |
++ unlock_page(page_m); |
33896 |
++ return; |
33897 |
++ } |
33898 |
++ } |
33899 |
++ |
33900 |
++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot); |
33901 |
++ page_cache_get(page_m); |
33902 |
++ page_add_anon_rmap(page_m, vma_m, address_m); |
33903 |
++ inc_mm_counter(mm, anon_rss); |
33904 |
++ set_pte_at(mm, address_m, pte_m, entry_m); |
33905 |
++ update_mmu_cache(vma_m, address_m, entry_m); |
33906 |
++ if (ptl != ptl_m) |
33907 |
++ spin_unlock(ptl_m); |
33908 |
++ pte_unmap_nested(pte_m); |
33909 |
++ unlock_page(page_m); |
33910 |
++} |
33911 |
++ |
33912 |
++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl) |
33913 |
++{ |
33914 |
++ struct mm_struct *mm = vma->vm_mm; |
33915 |
++ unsigned long address_m; |
33916 |
++ spinlock_t *ptl_m; |
33917 |
++ struct vm_area_struct *vma_m; |
33918 |
++ pmd_t *pmd_m; |
33919 |
++ pte_t *pte_m, entry_m; |
33920 |
++ |
33921 |
++ BUG_ON(!page_m || PageAnon(page_m)); |
33922 |
++ |
33923 |
++ vma_m = pax_find_mirror_vma(vma); |
33924 |
++ if (!vma_m) |
33925 |
++ return; |
33926 |
++ |
33927 |
++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); |
33928 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
33929 |
++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m); |
33930 |
++ pte_m = pte_offset_map_nested(pmd_m, address_m); |
33931 |
++ ptl_m = pte_lockptr(mm, pmd_m); |
33932 |
++ if (ptl != ptl_m) { |
33933 |
++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING); |
33934 |
++ if (!pte_none(*pte_m)) { |
33935 |
++ spin_unlock(ptl_m); |
33936 |
++ pte_unmap_nested(pte_m); |
33937 |
++ return; |
33938 |
++ } |
33939 |
++ } |
33940 |
++ |
33941 |
++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot); |
33942 |
++ page_cache_get(page_m); |
33943 |
++ page_add_file_rmap(page_m); |
33944 |
++ inc_mm_counter(mm, file_rss); |
33945 |
++ set_pte_at(mm, address_m, pte_m, entry_m); |
33946 |
++ update_mmu_cache(vma_m, address_m, entry_m); |
33947 |
++ if (ptl != ptl_m) |
33948 |
++ spin_unlock(ptl_m); |
33949 |
++ pte_unmap_nested(pte_m); |
33950 |
++} |
33951 |
++ |
33952 |
++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl) |
33953 |
++{ |
33954 |
++ struct mm_struct *mm = vma->vm_mm; |
33955 |
++ unsigned long address_m; |
33956 |
++ spinlock_t *ptl_m; |
33957 |
++ struct vm_area_struct *vma_m; |
33958 |
++ pmd_t *pmd_m; |
33959 |
++ pte_t *pte_m, entry_m; |
33960 |
++ |
33961 |
++ vma_m = pax_find_mirror_vma(vma); |
33962 |
++ if (!vma_m) |
33963 |
++ return; |
33964 |
++ |
33965 |
++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); |
33966 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
33967 |
++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m); |
33968 |
++ pte_m = pte_offset_map_nested(pmd_m, address_m); |
33969 |
++ ptl_m = pte_lockptr(mm, pmd_m); |
33970 |
++ if (ptl != ptl_m) { |
33971 |
++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING); |
33972 |
++ if (!pte_none(*pte_m)) { |
33973 |
++ spin_unlock(ptl_m); |
33974 |
++ pte_unmap_nested(pte_m); |
33975 |
++ return; |
33976 |
++ } |
33977 |
++ } |
33978 |
++ |
33979 |
++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot); |
33980 |
++ set_pte_at(mm, address_m, pte_m, entry_m); |
33981 |
++ if (ptl != ptl_m) |
33982 |
++ spin_unlock(ptl_m); |
33983 |
++ pte_unmap_nested(pte_m); |
33984 |
++} |
33985 |
++ |
33986 |
++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl) |
33987 |
++{ |
33988 |
++ struct page *page_m; |
33989 |
++ pte_t entry; |
33990 |
++ |
33991 |
++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC)) |
33992 |
++ goto out; |
33993 |
++ |
33994 |
++ entry = *pte; |
33995 |
++ page_m = vm_normal_page(vma, address, entry); |
33996 |
++ if (!page_m) |
33997 |
++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl); |
33998 |
++ else if (PageAnon(page_m)) { |
33999 |
++ if (pax_find_mirror_vma(vma)) { |
34000 |
++ pte_unmap_unlock(pte, ptl); |
34001 |
++ lock_page(page_m); |
34002 |
++ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl); |
34003 |
++ if (pte_same(entry, *pte)) |
34004 |
++ pax_mirror_anon_pte(vma, address, page_m, ptl); |
34005 |
++ else |
34006 |
++ unlock_page(page_m); |
34007 |
++ } |
34008 |
++ } else |
34009 |
++ pax_mirror_file_pte(vma, address, page_m, ptl); |
34010 |
++ |
34011 |
++out: |
34012 |
++ pte_unmap_unlock(pte, ptl); |
34013 |
++} |
34014 |
++#endif |
34015 |
++ |
34016 |
+ /* |
34017 |
+ * This routine handles present pages, when users try to write |
34018 |
+ * to a shared page. It is done by copying the page to a new address |
34019 |
+@@ -1638,6 +1829,12 @@ gotten: |
34020 |
+ */ |
34021 |
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl); |
34022 |
+ if (likely(pte_same(*page_table, orig_pte))) { |
34023 |
++ |
34024 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34025 |
++ if (pax_find_mirror_vma(vma)) |
34026 |
++ BUG_ON(TestSetPageLocked(new_page)); |
34027 |
++#endif |
34028 |
++ |
34029 |
+ if (old_page) { |
34030 |
+ page_remove_rmap(old_page, vma); |
34031 |
+ if (!PageAnon(old_page)) { |
34032 |
+@@ -1661,6 +1858,10 @@ gotten: |
34033 |
+ lru_cache_add_active(new_page); |
34034 |
+ page_add_new_anon_rmap(new_page, vma, address); |
34035 |
+ |
34036 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34037 |
++ pax_mirror_anon_pte(vma, address, new_page, ptl); |
34038 |
++#endif |
34039 |
++ |
34040 |
+ /* Free the old page.. */ |
34041 |
+ new_page = old_page; |
34042 |
+ ret |= VM_FAULT_WRITE; |
34043 |
+@@ -1941,6 +2142,7 @@ int vmtruncate(struct inode * inode, lof |
34044 |
+ |
34045 |
+ do_expand: |
34046 |
+ limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; |
34047 |
++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1); |
34048 |
+ if (limit != RLIM_INFINITY && offset > limit) |
34049 |
+ goto out_sig; |
34050 |
+ if (offset > inode->i_sb->s_maxbytes) |
34051 |
+@@ -2123,6 +2325,11 @@ static int do_swap_page(struct mm_struct |
34052 |
+ swap_free(entry); |
34053 |
+ if (vm_swap_full()) |
34054 |
+ remove_exclusive_swap_page(page); |
34055 |
++ |
34056 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34057 |
++ if (write_access || !pax_find_mirror_vma(vma)) |
34058 |
++#endif |
34059 |
++ |
34060 |
+ unlock_page(page); |
34061 |
+ |
34062 |
+ if (write_access) { |
34063 |
+@@ -2135,6 +2342,11 @@ static int do_swap_page(struct mm_struct |
34064 |
+ |
34065 |
+ /* No need to invalidate - it was non-present before */ |
34066 |
+ update_mmu_cache(vma, address, pte); |
34067 |
++ |
34068 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34069 |
++ pax_mirror_anon_pte(vma, address, page, ptl); |
34070 |
++#endif |
34071 |
++ |
34072 |
+ unlock: |
34073 |
+ pte_unmap_unlock(page_table, ptl); |
34074 |
+ out: |
34075 |
+@@ -2174,6 +2386,12 @@ static int do_anonymous_page(struct mm_s |
34076 |
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl); |
34077 |
+ if (!pte_none(*page_table)) |
34078 |
+ goto release; |
34079 |
++ |
34080 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34081 |
++ if (pax_find_mirror_vma(vma)) |
34082 |
++ BUG_ON(TestSetPageLocked(page)); |
34083 |
++#endif |
34084 |
++ |
34085 |
+ inc_mm_counter(mm, anon_rss); |
34086 |
+ lru_cache_add_active(page); |
34087 |
+ page_add_new_anon_rmap(page, vma, address); |
34088 |
+@@ -2181,6 +2399,11 @@ static int do_anonymous_page(struct mm_s |
34089 |
+ |
34090 |
+ /* No need to invalidate - it was non-present before */ |
34091 |
+ update_mmu_cache(vma, address, entry); |
34092 |
++ |
34093 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34094 |
++ pax_mirror_anon_pte(vma, address, page, ptl); |
34095 |
++#endif |
34096 |
++ |
34097 |
+ unlock: |
34098 |
+ pte_unmap_unlock(page_table, ptl); |
34099 |
+ return 0; |
34100 |
+@@ -2313,6 +2536,12 @@ static int __do_fault(struct mm_struct * |
34101 |
+ */ |
34102 |
+ /* Only go through if we didn't race with anybody else... */ |
34103 |
+ if (likely(pte_same(*page_table, orig_pte))) { |
34104 |
++ |
34105 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34106 |
++ if (anon && pax_find_mirror_vma(vma)) |
34107 |
++ BUG_ON(TestSetPageLocked(page)); |
34108 |
++#endif |
34109 |
++ |
34110 |
+ flush_icache_page(vma, page); |
34111 |
+ entry = mk_pte(page, vma->vm_page_prot); |
34112 |
+ if (flags & FAULT_FLAG_WRITE) |
34113 |
+@@ -2333,6 +2562,14 @@ static int __do_fault(struct mm_struct * |
34114 |
+ |
34115 |
+ /* no need to invalidate: a not-present page won't be cached */ |
34116 |
+ update_mmu_cache(vma, address, entry); |
34117 |
++ |
34118 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34119 |
++ if (anon) |
34120 |
++ pax_mirror_anon_pte(vma, address, page, ptl); |
34121 |
++ else |
34122 |
++ pax_mirror_file_pte(vma, address, page, ptl); |
34123 |
++#endif |
34124 |
++ |
34125 |
+ } else { |
34126 |
+ if (anon) |
34127 |
+ page_cache_release(page); |
34128 |
+@@ -2415,6 +2652,11 @@ static noinline int do_no_pfn(struct mm_ |
34129 |
+ if (write_access) |
34130 |
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma); |
34131 |
+ set_pte_at(mm, address, page_table, entry); |
34132 |
++ |
34133 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34134 |
++ pax_mirror_pfn_pte(vma, address, pfn, ptl); |
34135 |
++#endif |
34136 |
++ |
34137 |
+ } |
34138 |
+ pte_unmap_unlock(page_table, ptl); |
34139 |
+ return 0; |
34140 |
+@@ -2517,6 +2759,12 @@ static inline int handle_pte_fault(struc |
34141 |
+ if (write_access) |
34142 |
+ flush_tlb_page(vma, address); |
34143 |
+ } |
34144 |
++ |
34145 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34146 |
++ pax_mirror_pte(vma, address, pte, pmd, ptl); |
34147 |
++ return 0; |
34148 |
++#endif |
34149 |
++ |
34150 |
+ unlock: |
34151 |
+ pte_unmap_unlock(pte, ptl); |
34152 |
+ return 0; |
34153 |
+@@ -2533,6 +2781,10 @@ int handle_mm_fault(struct mm_struct *mm |
34154 |
+ pmd_t *pmd; |
34155 |
+ pte_t *pte; |
34156 |
+ |
34157 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34158 |
++ struct vm_area_struct *vma_m; |
34159 |
++#endif |
34160 |
++ |
34161 |
+ __set_current_state(TASK_RUNNING); |
34162 |
+ |
34163 |
+ count_vm_event(PGFAULT); |
34164 |
+@@ -2540,6 +2792,34 @@ int handle_mm_fault(struct mm_struct *mm |
34165 |
+ if (unlikely(is_vm_hugetlb_page(vma))) |
34166 |
+ return hugetlb_fault(mm, vma, address, write_access); |
34167 |
+ |
34168 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34169 |
++ vma_m = pax_find_mirror_vma(vma); |
34170 |
++ if (vma_m) { |
34171 |
++ unsigned long address_m; |
34172 |
++ pgd_t *pgd_m; |
34173 |
++ pud_t *pud_m; |
34174 |
++ pmd_t *pmd_m; |
34175 |
++ |
34176 |
++ if (vma->vm_start > vma_m->vm_start) { |
34177 |
++ address_m = address; |
34178 |
++ address -= SEGMEXEC_TASK_SIZE; |
34179 |
++ vma = vma_m; |
34180 |
++ } else |
34181 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
34182 |
++ |
34183 |
++ pgd_m = pgd_offset(mm, address_m); |
34184 |
++ pud_m = pud_alloc(mm, pgd_m, address_m); |
34185 |
++ if (!pud_m) |
34186 |
++ return VM_FAULT_OOM; |
34187 |
++ pmd_m = pmd_alloc(mm, pud_m, address_m); |
34188 |
++ if (!pmd_m) |
34189 |
++ return VM_FAULT_OOM; |
34190 |
++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m)) |
34191 |
++ return VM_FAULT_OOM; |
34192 |
++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m); |
34193 |
++ } |
34194 |
++#endif |
34195 |
++ |
34196 |
+ pgd = pgd_offset(mm, address); |
34197 |
+ pud = pud_alloc(mm, pgd, address); |
34198 |
+ if (!pud) |
34199 |
+@@ -2673,7 +2953,7 @@ static int __init gate_vma_init(void) |
34200 |
+ gate_vma.vm_start = FIXADDR_USER_START; |
34201 |
+ gate_vma.vm_end = FIXADDR_USER_END; |
34202 |
+ gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; |
34203 |
+- gate_vma.vm_page_prot = __P101; |
34204 |
++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags); |
34205 |
+ /* |
34206 |
+ * Make sure the vDSO gets into every core dump. |
34207 |
+ * Dumping its contents makes post-mortem fully interpretable later |
34208 |
+diff -urNp linux-2.6.24.4/mm/mempolicy.c linux-2.6.24.4/mm/mempolicy.c |
34209 |
+--- linux-2.6.24.4/mm/mempolicy.c 2008-03-24 14:49:18.000000000 -0400 |
34210 |
++++ linux-2.6.24.4/mm/mempolicy.c 2008-03-26 17:56:56.000000000 -0400 |
34211 |
+@@ -406,6 +406,10 @@ static int mbind_range(struct vm_area_st |
34212 |
+ struct vm_area_struct *next; |
34213 |
+ int err; |
34214 |
+ |
34215 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34216 |
++ struct vm_area_struct *vma_m; |
34217 |
++#endif |
34218 |
++ |
34219 |
+ err = 0; |
34220 |
+ for (; vma && vma->vm_start < end; vma = next) { |
34221 |
+ next = vma->vm_next; |
34222 |
+@@ -417,6 +421,16 @@ static int mbind_range(struct vm_area_st |
34223 |
+ err = policy_vma(vma, new); |
34224 |
+ if (err) |
34225 |
+ break; |
34226 |
++ |
34227 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34228 |
++ vma_m = pax_find_mirror_vma(vma); |
34229 |
++ if (vma_m) { |
34230 |
++ err = policy_vma(vma_m, new); |
34231 |
++ if (err) |
34232 |
++ break; |
34233 |
++ } |
34234 |
++#endif |
34235 |
++ |
34236 |
+ } |
34237 |
+ return err; |
34238 |
+ } |
34239 |
+@@ -794,6 +808,17 @@ static long do_mbind(unsigned long start |
34240 |
+ |
34241 |
+ if (end < start) |
34242 |
+ return -EINVAL; |
34243 |
++ |
34244 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34245 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) { |
34246 |
++ if (end > SEGMEXEC_TASK_SIZE) |
34247 |
++ return -EINVAL; |
34248 |
++ } else |
34249 |
++#endif |
34250 |
++ |
34251 |
++ if (end > TASK_SIZE) |
34252 |
++ return -EINVAL; |
34253 |
++ |
34254 |
+ if (end == start) |
34255 |
+ return 0; |
34256 |
+ |
34257 |
+diff -urNp linux-2.6.24.4/mm/mlock.c linux-2.6.24.4/mm/mlock.c |
34258 |
+--- linux-2.6.24.4/mm/mlock.c 2008-03-24 14:49:18.000000000 -0400 |
34259 |
++++ linux-2.6.24.4/mm/mlock.c 2008-03-26 17:56:56.000000000 -0400 |
34260 |
+@@ -12,6 +12,7 @@ |
34261 |
+ #include <linux/syscalls.h> |
34262 |
+ #include <linux/sched.h> |
34263 |
+ #include <linux/module.h> |
34264 |
++#include <linux/grsecurity.h> |
34265 |
+ |
34266 |
+ int can_do_mlock(void) |
34267 |
+ { |
34268 |
+@@ -95,6 +96,17 @@ static int do_mlock(unsigned long start, |
34269 |
+ return -EINVAL; |
34270 |
+ if (end == start) |
34271 |
+ return 0; |
34272 |
++ |
34273 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34274 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { |
34275 |
++ if (end > SEGMEXEC_TASK_SIZE) |
34276 |
++ return -EINVAL; |
34277 |
++ } else |
34278 |
++#endif |
34279 |
++ |
34280 |
++ if (end > TASK_SIZE) |
34281 |
++ return -EINVAL; |
34282 |
++ |
34283 |
+ vma = find_vma_prev(current->mm, start, &prev); |
34284 |
+ if (!vma || vma->vm_start > start) |
34285 |
+ return -ENOMEM; |
34286 |
+@@ -152,6 +164,7 @@ asmlinkage long sys_mlock(unsigned long |
34287 |
+ lock_limit >>= PAGE_SHIFT; |
34288 |
+ |
34289 |
+ /* check against resource limits */ |
34290 |
++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1); |
34291 |
+ if ((locked <= lock_limit) || capable(CAP_IPC_LOCK)) |
34292 |
+ error = do_mlock(start, len, 1); |
34293 |
+ up_write(¤t->mm->mmap_sem); |
34294 |
+@@ -173,10 +186,10 @@ asmlinkage long sys_munlock(unsigned lon |
34295 |
+ static int do_mlockall(int flags) |
34296 |
+ { |
34297 |
+ struct vm_area_struct * vma, * prev = NULL; |
34298 |
+- unsigned int def_flags = 0; |
34299 |
++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED; |
34300 |
+ |
34301 |
+ if (flags & MCL_FUTURE) |
34302 |
+- def_flags = VM_LOCKED; |
34303 |
++ def_flags |= VM_LOCKED; |
34304 |
+ current->mm->def_flags = def_flags; |
34305 |
+ if (flags == MCL_FUTURE) |
34306 |
+ goto out; |
34307 |
+@@ -184,6 +197,12 @@ static int do_mlockall(int flags) |
34308 |
+ for (vma = current->mm->mmap; vma ; vma = prev->vm_next) { |
34309 |
+ unsigned int newflags; |
34310 |
+ |
34311 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34312 |
++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) |
34313 |
++ break; |
34314 |
++#endif |
34315 |
++ |
34316 |
++ BUG_ON(vma->vm_end > TASK_SIZE); |
34317 |
+ newflags = vma->vm_flags | VM_LOCKED; |
34318 |
+ if (!(flags & MCL_CURRENT)) |
34319 |
+ newflags &= ~VM_LOCKED; |
34320 |
+@@ -213,6 +232,7 @@ asmlinkage long sys_mlockall(int flags) |
34321 |
+ lock_limit >>= PAGE_SHIFT; |
34322 |
+ |
34323 |
+ ret = -ENOMEM; |
34324 |
++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1); |
34325 |
+ if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) || |
34326 |
+ capable(CAP_IPC_LOCK)) |
34327 |
+ ret = do_mlockall(flags); |
34328 |
+diff -urNp linux-2.6.24.4/mm/mmap.c linux-2.6.24.4/mm/mmap.c |
34329 |
+--- linux-2.6.24.4/mm/mmap.c 2008-03-24 14:49:18.000000000 -0400 |
34330 |
++++ linux-2.6.24.4/mm/mmap.c 2008-03-26 17:56:56.000000000 -0400 |
34331 |
+@@ -26,6 +26,7 @@ |
34332 |
+ #include <linux/mount.h> |
34333 |
+ #include <linux/mempolicy.h> |
34334 |
+ #include <linux/rmap.h> |
34335 |
++#include <linux/grsecurity.h> |
34336 |
+ |
34337 |
+ #include <asm/uaccess.h> |
34338 |
+ #include <asm/cacheflush.h> |
34339 |
+@@ -36,6 +37,16 @@ |
34340 |
+ #define arch_mmap_check(addr, len, flags) (0) |
34341 |
+ #endif |
34342 |
+ |
34343 |
++static inline void verify_mm_writelocked(struct mm_struct *mm) |
34344 |
++{ |
34345 |
++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX) |
34346 |
++ if (unlikely(down_read_trylock(&mm->mmap_sem))) { |
34347 |
++ up_read(&mm->mmap_sem); |
34348 |
++ BUG(); |
34349 |
++ } |
34350 |
++#endif |
34351 |
++} |
34352 |
++ |
34353 |
+ static void unmap_region(struct mm_struct *mm, |
34354 |
+ struct vm_area_struct *vma, struct vm_area_struct *prev, |
34355 |
+ unsigned long start, unsigned long end); |
34356 |
+@@ -61,15 +72,23 @@ static void unmap_region(struct mm_struc |
34357 |
+ * x: (no) no x: (no) yes x: (no) yes x: (yes) yes |
34358 |
+ * |
34359 |
+ */ |
34360 |
+-pgprot_t protection_map[16] = { |
34361 |
++pgprot_t protection_map[16] __read_only = { |
34362 |
+ __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111, |
34363 |
+ __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111 |
34364 |
+ }; |
34365 |
+ |
34366 |
+ pgprot_t vm_get_page_prot(unsigned long vm_flags) |
34367 |
+ { |
34368 |
+- return protection_map[vm_flags & |
34369 |
+- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; |
34370 |
++ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; |
34371 |
++ |
34372 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32) |
34373 |
++ if (!nx_enabled && |
34374 |
++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC && |
34375 |
++ (vm_flags & (VM_READ | VM_WRITE))) |
34376 |
++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot))))); |
34377 |
++#endif |
34378 |
++ |
34379 |
++ return prot; |
34380 |
+ } |
34381 |
+ EXPORT_SYMBOL(vm_get_page_prot); |
34382 |
+ |
34383 |
+@@ -224,6 +243,7 @@ static struct vm_area_struct *remove_vma |
34384 |
+ struct vm_area_struct *next = vma->vm_next; |
34385 |
+ |
34386 |
+ might_sleep(); |
34387 |
++ BUG_ON(vma->vm_mirror); |
34388 |
+ if (vma->vm_ops && vma->vm_ops->close) |
34389 |
+ vma->vm_ops->close(vma); |
34390 |
+ if (vma->vm_file) |
34391 |
+@@ -251,6 +271,7 @@ asmlinkage unsigned long sys_brk(unsigne |
34392 |
+ * not page aligned -Ram Gupta |
34393 |
+ */ |
34394 |
+ rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; |
34395 |
++ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1); |
34396 |
+ if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) |
34397 |
+ goto out; |
34398 |
+ |
34399 |
+@@ -351,8 +372,12 @@ find_vma_prepare(struct mm_struct *mm, u |
34400 |
+ |
34401 |
+ if (vma_tmp->vm_end > addr) { |
34402 |
+ vma = vma_tmp; |
34403 |
+- if (vma_tmp->vm_start <= addr) |
34404 |
+- return vma; |
34405 |
++ if (vma_tmp->vm_start <= addr) { |
34406 |
++//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ", |
34407 |
++//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent); |
34408 |
++//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0))); |
34409 |
++ break; |
34410 |
++ } |
34411 |
+ __rb_link = &__rb_parent->rb_left; |
34412 |
+ } else { |
34413 |
+ rb_prev = __rb_parent; |
34414 |
+@@ -676,6 +701,12 @@ static int |
34415 |
+ can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags, |
34416 |
+ struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff) |
34417 |
+ { |
34418 |
++ |
34419 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34420 |
++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE) |
34421 |
++ return 0; |
34422 |
++#endif |
34423 |
++ |
34424 |
+ if (is_mergeable_vma(vma, file, vm_flags) && |
34425 |
+ is_mergeable_anon_vma(anon_vma, vma->anon_vma)) { |
34426 |
+ if (vma->vm_pgoff == vm_pgoff) |
34427 |
+@@ -695,6 +726,12 @@ static int |
34428 |
+ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, |
34429 |
+ struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff) |
34430 |
+ { |
34431 |
++ |
34432 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34433 |
++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE) |
34434 |
++ return 0; |
34435 |
++#endif |
34436 |
++ |
34437 |
+ if (is_mergeable_vma(vma, file, vm_flags) && |
34438 |
+ is_mergeable_anon_vma(anon_vma, vma->anon_vma)) { |
34439 |
+ pgoff_t vm_pglen; |
34440 |
+@@ -737,12 +774,19 @@ can_vma_merge_after(struct vm_area_struc |
34441 |
+ struct vm_area_struct *vma_merge(struct mm_struct *mm, |
34442 |
+ struct vm_area_struct *prev, unsigned long addr, |
34443 |
+ unsigned long end, unsigned long vm_flags, |
34444 |
+- struct anon_vma *anon_vma, struct file *file, |
34445 |
++ struct anon_vma *anon_vma, struct file *file, |
34446 |
+ pgoff_t pgoff, struct mempolicy *policy) |
34447 |
+ { |
34448 |
+ pgoff_t pglen = (end - addr) >> PAGE_SHIFT; |
34449 |
+ struct vm_area_struct *area, *next; |
34450 |
+ |
34451 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34452 |
++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE; |
34453 |
++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL; |
34454 |
++ |
34455 |
++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end); |
34456 |
++#endif |
34457 |
++ |
34458 |
+ /* |
34459 |
+ * We later require that vma->vm_flags == vm_flags, |
34460 |
+ * so this tests vma->vm_flags & VM_SPECIAL, too. |
34461 |
+@@ -758,6 +802,15 @@ struct vm_area_struct *vma_merge(struct |
34462 |
+ if (next && next->vm_end == end) /* cases 6, 7, 8 */ |
34463 |
+ next = next->vm_next; |
34464 |
+ |
34465 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34466 |
++ if (prev) |
34467 |
++ prev_m = pax_find_mirror_vma(prev); |
34468 |
++ if (area) |
34469 |
++ area_m = pax_find_mirror_vma(area); |
34470 |
++ if (next) |
34471 |
++ next_m = pax_find_mirror_vma(next); |
34472 |
++#endif |
34473 |
++ |
34474 |
+ /* |
34475 |
+ * Can it merge with the predecessor? |
34476 |
+ */ |
34477 |
+@@ -777,9 +830,24 @@ struct vm_area_struct *vma_merge(struct |
34478 |
+ /* cases 1, 6 */ |
34479 |
+ vma_adjust(prev, prev->vm_start, |
34480 |
+ next->vm_end, prev->vm_pgoff, NULL); |
34481 |
+- } else /* cases 2, 5, 7 */ |
34482 |
++ |
34483 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34484 |
++ if (prev_m) |
34485 |
++ vma_adjust(prev_m, prev_m->vm_start, |
34486 |
++ next_m->vm_end, prev_m->vm_pgoff, NULL); |
34487 |
++#endif |
34488 |
++ |
34489 |
++ } else { /* cases 2, 5, 7 */ |
34490 |
+ vma_adjust(prev, prev->vm_start, |
34491 |
+ end, prev->vm_pgoff, NULL); |
34492 |
++ |
34493 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34494 |
++ if (prev_m) |
34495 |
++ vma_adjust(prev_m, prev_m->vm_start, |
34496 |
++ end_m, prev_m->vm_pgoff, NULL); |
34497 |
++#endif |
34498 |
++ |
34499 |
++ } |
34500 |
+ return prev; |
34501 |
+ } |
34502 |
+ |
34503 |
+@@ -790,12 +858,43 @@ struct vm_area_struct *vma_merge(struct |
34504 |
+ mpol_equal(policy, vma_policy(next)) && |
34505 |
+ can_vma_merge_before(next, vm_flags, |
34506 |
+ anon_vma, file, pgoff+pglen)) { |
34507 |
+- if (prev && addr < prev->vm_end) /* case 4 */ |
34508 |
++ if (prev && addr < prev->vm_end) { /* case 4 */ |
34509 |
+ vma_adjust(prev, prev->vm_start, |
34510 |
+ addr, prev->vm_pgoff, NULL); |
34511 |
+- else /* cases 3, 8 */ |
34512 |
++ |
34513 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34514 |
++ if (prev_m) |
34515 |
++ vma_adjust(prev_m, prev_m->vm_start, |
34516 |
++ addr_m, prev_m->vm_pgoff, NULL); |
34517 |
++#endif |
34518 |
++ |
34519 |
++ } else { /* cases 3, 8 */ |
34520 |
+ vma_adjust(area, addr, next->vm_end, |
34521 |
+ next->vm_pgoff - pglen, NULL); |
34522 |
++ |
34523 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34524 |
++ if (area_m) |
34525 |
++ vma_adjust(area_m, addr_m, next_m->vm_end, |
34526 |
++ next_m->vm_pgoff - pglen, NULL); |
34527 |
++ else if (next_m) { |
34528 |
++ vma_adjust(next_m, addr_m, next_m->vm_end, |
34529 |
++ next_m->vm_pgoff - pglen, NULL); |
34530 |
++ BUG_ON(area == next); |
34531 |
++ BUG_ON(area->vm_mirror); |
34532 |
++ BUG_ON(next_m->anon_vma && next_m->anon_vma != area->anon_vma); |
34533 |
++ BUG_ON(area->vm_file != next_m->vm_file); |
34534 |
++ BUG_ON(area->vm_end - area->vm_start != next_m->vm_end - next_m->vm_start); |
34535 |
++ BUG_ON(area->vm_pgoff != next_m->vm_pgoff); |
34536 |
++ area->vm_mirror = next_m; |
34537 |
++ next_m->vm_mirror = area; |
34538 |
++ if (area->anon_vma && !next_m->anon_vma) { |
34539 |
++ next_m->anon_vma = area->anon_vma; |
34540 |
++ anon_vma_link(next_m); |
34541 |
++ } |
34542 |
++ } |
34543 |
++#endif |
34544 |
++ |
34545 |
++ } |
34546 |
+ return area; |
34547 |
+ } |
34548 |
+ |
34549 |
+@@ -870,14 +969,11 @@ none: |
34550 |
+ void vm_stat_account(struct mm_struct *mm, unsigned long flags, |
34551 |
+ struct file *file, long pages) |
34552 |
+ { |
34553 |
+- const unsigned long stack_flags |
34554 |
+- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN); |
34555 |
+- |
34556 |
+ if (file) { |
34557 |
+ mm->shared_vm += pages; |
34558 |
+ if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC) |
34559 |
+ mm->exec_vm += pages; |
34560 |
+- } else if (flags & stack_flags) |
34561 |
++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN)) |
34562 |
+ mm->stack_vm += pages; |
34563 |
+ if (flags & (VM_RESERVED|VM_IO)) |
34564 |
+ mm->reserved_vm += pages; |
34565 |
+@@ -905,7 +1001,7 @@ unsigned long do_mmap_pgoff(struct file |
34566 |
+ * (the exception is when the underlying filesystem is noexec |
34567 |
+ * mounted, in which case we dont add PROT_EXEC.) |
34568 |
+ */ |
34569 |
+- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) |
34570 |
++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC)) |
34571 |
+ if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC))) |
34572 |
+ prot |= PROT_EXEC; |
34573 |
+ |
34574 |
+@@ -915,15 +1011,15 @@ unsigned long do_mmap_pgoff(struct file |
34575 |
+ if (!(flags & MAP_FIXED)) |
34576 |
+ addr = round_hint_to_min(addr); |
34577 |
+ |
34578 |
+- error = arch_mmap_check(addr, len, flags); |
34579 |
+- if (error) |
34580 |
+- return error; |
34581 |
+- |
34582 |
+ /* Careful about overflows.. */ |
34583 |
+ len = PAGE_ALIGN(len); |
34584 |
+ if (!len || len > TASK_SIZE) |
34585 |
+ return -ENOMEM; |
34586 |
+ |
34587 |
++ error = arch_mmap_check(addr, len, flags); |
34588 |
++ if (error) |
34589 |
++ return error; |
34590 |
++ |
34591 |
+ /* offset overflow? */ |
34592 |
+ if ((pgoff + (len >> PAGE_SHIFT)) < pgoff) |
34593 |
+ return -EOVERFLOW; |
34594 |
+@@ -935,7 +1031,7 @@ unsigned long do_mmap_pgoff(struct file |
34595 |
+ /* Obtain the address to map to. we verify (or select) it and ensure |
34596 |
+ * that it represents a valid section of the address space. |
34597 |
+ */ |
34598 |
+- addr = get_unmapped_area(file, addr, len, pgoff, flags); |
34599 |
++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0)); |
34600 |
+ if (addr & ~PAGE_MASK) |
34601 |
+ return addr; |
34602 |
+ |
34603 |
+@@ -946,6 +1042,26 @@ unsigned long do_mmap_pgoff(struct file |
34604 |
+ vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) | |
34605 |
+ mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; |
34606 |
+ |
34607 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
34608 |
++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
34609 |
++ |
34610 |
++#ifdef CONFIG_PAX_MPROTECT |
34611 |
++ if (mm->pax_flags & MF_PAX_MPROTECT) { |
34612 |
++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC) |
34613 |
++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC); |
34614 |
++ else |
34615 |
++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE); |
34616 |
++ } |
34617 |
++#endif |
34618 |
++ |
34619 |
++ } |
34620 |
++#endif |
34621 |
++ |
34622 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32) |
34623 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file) |
34624 |
++ vm_flags &= ~VM_PAGEEXEC; |
34625 |
++#endif |
34626 |
++ |
34627 |
+ if (flags & MAP_LOCKED) { |
34628 |
+ if (!can_do_mlock()) |
34629 |
+ return -EPERM; |
34630 |
+@@ -958,6 +1074,7 @@ unsigned long do_mmap_pgoff(struct file |
34631 |
+ locked += mm->locked_vm; |
34632 |
+ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; |
34633 |
+ lock_limit >>= PAGE_SHIFT; |
34634 |
++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1); |
34635 |
+ if (locked > lock_limit && !capable(CAP_IPC_LOCK)) |
34636 |
+ return -EAGAIN; |
34637 |
+ } |
34638 |
+@@ -1026,6 +1143,9 @@ unsigned long do_mmap_pgoff(struct file |
34639 |
+ if (error) |
34640 |
+ return error; |
34641 |
+ |
34642 |
++ if (!gr_acl_handle_mmap(file, prot)) |
34643 |
++ return -EACCES; |
34644 |
++ |
34645 |
+ return mmap_region(file, addr, len, flags, vm_flags, pgoff, |
34646 |
+ accountable); |
34647 |
+ } |
34648 |
+@@ -1039,10 +1159,10 @@ EXPORT_SYMBOL(do_mmap_pgoff); |
34649 |
+ */ |
34650 |
+ int vma_wants_writenotify(struct vm_area_struct *vma) |
34651 |
+ { |
34652 |
+- unsigned int vm_flags = vma->vm_flags; |
34653 |
++ unsigned long vm_flags = vma->vm_flags; |
34654 |
+ |
34655 |
+ /* If it was private or non-writable, the write bit is already clear */ |
34656 |
+- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED))) |
34657 |
++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED)) |
34658 |
+ return 0; |
34659 |
+ |
34660 |
+ /* The backer wishes to know when pages are first written to? */ |
34661 |
+@@ -1077,14 +1197,24 @@ unsigned long mmap_region(struct file *f |
34662 |
+ unsigned long charged = 0; |
34663 |
+ struct inode *inode = file ? file->f_path.dentry->d_inode : NULL; |
34664 |
+ |
34665 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34666 |
++ struct vm_area_struct *vma_m = NULL; |
34667 |
++#endif |
34668 |
++ |
34669 |
++ /* |
34670 |
++ * mm->mmap_sem is required to protect against another thread |
34671 |
++ * changing the mappings in case we sleep. |
34672 |
++ */ |
34673 |
++ verify_mm_writelocked(mm); |
34674 |
++ |
34675 |
+ /* Clear old maps */ |
34676 |
+ error = -ENOMEM; |
34677 |
+-munmap_back: |
34678 |
+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); |
34679 |
+ if (vma && vma->vm_start < addr + len) { |
34680 |
+ if (do_munmap(mm, addr, len)) |
34681 |
+ return -ENOMEM; |
34682 |
+- goto munmap_back; |
34683 |
++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); |
34684 |
++ BUG_ON(vma && vma->vm_start < addr + len); |
34685 |
+ } |
34686 |
+ |
34687 |
+ /* Check against address space limit. */ |
34688 |
+@@ -1128,6 +1258,16 @@ munmap_back: |
34689 |
+ goto unacct_error; |
34690 |
+ } |
34691 |
+ |
34692 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34693 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) { |
34694 |
++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
34695 |
++ if (!vma_m) { |
34696 |
++ error = -ENOMEM; |
34697 |
++ goto free_vma; |
34698 |
++ } |
34699 |
++ } |
34700 |
++#endif |
34701 |
++ |
34702 |
+ vma->vm_mm = mm; |
34703 |
+ vma->vm_start = addr; |
34704 |
+ vma->vm_end = addr + len; |
34705 |
+@@ -1150,6 +1290,27 @@ munmap_back: |
34706 |
+ error = file->f_op->mmap(file, vma); |
34707 |
+ if (error) |
34708 |
+ goto unmap_and_free_vma; |
34709 |
++ |
34710 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34711 |
++ if (vma_m) { |
34712 |
++ struct mempolicy *pol; |
34713 |
++ |
34714 |
++ pol = mpol_copy(vma_policy(vma)); |
34715 |
++ if (IS_ERR(pol)) { |
34716 |
++ mpol_free(vma_policy(vma)); |
34717 |
++ goto unmap_and_free_vma; |
34718 |
++ } |
34719 |
++ vma_set_policy(vma_m, pol); |
34720 |
++ } |
34721 |
++#endif |
34722 |
++ |
34723 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32) |
34724 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) { |
34725 |
++ vma->vm_flags |= VM_PAGEEXEC; |
34726 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
34727 |
++ } |
34728 |
++#endif |
34729 |
++ |
34730 |
+ } else if (vm_flags & VM_SHARED) { |
34731 |
+ error = shmem_zero_setup(vma); |
34732 |
+ if (error) |
34733 |
+@@ -1180,6 +1341,12 @@ munmap_back: |
34734 |
+ vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) { |
34735 |
+ file = vma->vm_file; |
34736 |
+ vma_link(mm, vma, prev, rb_link, rb_parent); |
34737 |
++ |
34738 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34739 |
++ if (vma_m) |
34740 |
++ pax_mirror_vma(vma_m, vma); |
34741 |
++#endif |
34742 |
++ |
34743 |
+ if (correct_wcount) |
34744 |
+ atomic_inc(&inode->i_writecount); |
34745 |
+ } else { |
34746 |
+@@ -1190,10 +1357,20 @@ munmap_back: |
34747 |
+ } |
34748 |
+ mpol_free(vma_policy(vma)); |
34749 |
+ kmem_cache_free(vm_area_cachep, vma); |
34750 |
++ vma = NULL; |
34751 |
++ |
34752 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34753 |
++ if (vma_m) { |
34754 |
++ mpol_free(vma_policy(vma_m)); |
34755 |
++ kmem_cache_free(vm_area_cachep, vma_m); |
34756 |
++ } |
34757 |
++#endif |
34758 |
++ |
34759 |
+ } |
34760 |
+ out: |
34761 |
+ mm->total_vm += len >> PAGE_SHIFT; |
34762 |
+ vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); |
34763 |
++ track_exec_limit(mm, addr, addr + len, vm_flags); |
34764 |
+ if (vm_flags & VM_LOCKED) { |
34765 |
+ mm->locked_vm += len >> PAGE_SHIFT; |
34766 |
+ make_pages_present(addr, addr + len); |
34767 |
+@@ -1212,6 +1389,12 @@ unmap_and_free_vma: |
34768 |
+ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); |
34769 |
+ charged = 0; |
34770 |
+ free_vma: |
34771 |
++ |
34772 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34773 |
++ if (vma_m) |
34774 |
++ kmem_cache_free(vm_area_cachep, vma_m); |
34775 |
++#endif |
34776 |
++ |
34777 |
+ kmem_cache_free(vm_area_cachep, vma); |
34778 |
+ unacct_error: |
34779 |
+ if (charged) |
34780 |
+@@ -1245,6 +1428,10 @@ arch_get_unmapped_area(struct file *filp |
34781 |
+ if (flags & MAP_FIXED) |
34782 |
+ return addr; |
34783 |
+ |
34784 |
++#ifdef CONFIG_PAX_RANDMMAP |
34785 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) |
34786 |
++#endif |
34787 |
++ |
34788 |
+ if (addr) { |
34789 |
+ addr = PAGE_ALIGN(addr); |
34790 |
+ vma = find_vma(mm, addr); |
34791 |
+@@ -1253,10 +1440,10 @@ arch_get_unmapped_area(struct file *filp |
34792 |
+ return addr; |
34793 |
+ } |
34794 |
+ if (len > mm->cached_hole_size) { |
34795 |
+- start_addr = addr = mm->free_area_cache; |
34796 |
++ start_addr = addr = mm->free_area_cache; |
34797 |
+ } else { |
34798 |
+- start_addr = addr = TASK_UNMAPPED_BASE; |
34799 |
+- mm->cached_hole_size = 0; |
34800 |
++ start_addr = addr = mm->mmap_base; |
34801 |
++ mm->cached_hole_size = 0; |
34802 |
+ } |
34803 |
+ |
34804 |
+ full_search: |
34805 |
+@@ -1267,9 +1454,8 @@ full_search: |
34806 |
+ * Start a new search - just in case we missed |
34807 |
+ * some holes. |
34808 |
+ */ |
34809 |
+- if (start_addr != TASK_UNMAPPED_BASE) { |
34810 |
+- addr = TASK_UNMAPPED_BASE; |
34811 |
+- start_addr = addr; |
34812 |
++ if (start_addr != mm->mmap_base) { |
34813 |
++ start_addr = addr = mm->mmap_base; |
34814 |
+ mm->cached_hole_size = 0; |
34815 |
+ goto full_search; |
34816 |
+ } |
34817 |
+@@ -1291,10 +1477,16 @@ full_search: |
34818 |
+ |
34819 |
+ void arch_unmap_area(struct mm_struct *mm, unsigned long addr) |
34820 |
+ { |
34821 |
++ |
34822 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34823 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr) |
34824 |
++ return; |
34825 |
++#endif |
34826 |
++ |
34827 |
+ /* |
34828 |
+ * Is this a new hole at the lowest possible address? |
34829 |
+ */ |
34830 |
+- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) { |
34831 |
++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) { |
34832 |
+ mm->free_area_cache = addr; |
34833 |
+ mm->cached_hole_size = ~0UL; |
34834 |
+ } |
34835 |
+@@ -1312,7 +1504,7 @@ arch_get_unmapped_area_topdown(struct fi |
34836 |
+ { |
34837 |
+ struct vm_area_struct *vma; |
34838 |
+ struct mm_struct *mm = current->mm; |
34839 |
+- unsigned long addr = addr0; |
34840 |
++ unsigned long base = mm->mmap_base, addr = addr0; |
34841 |
+ |
34842 |
+ /* requested length too big for entire address space */ |
34843 |
+ if (len > TASK_SIZE) |
34844 |
+@@ -1321,6 +1513,10 @@ arch_get_unmapped_area_topdown(struct fi |
34845 |
+ if (flags & MAP_FIXED) |
34846 |
+ return addr; |
34847 |
+ |
34848 |
++#ifdef CONFIG_PAX_RANDMMAP |
34849 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) |
34850 |
++#endif |
34851 |
++ |
34852 |
+ /* requesting a specific address */ |
34853 |
+ if (addr) { |
34854 |
+ addr = PAGE_ALIGN(addr); |
34855 |
+@@ -1378,13 +1574,21 @@ bottomup: |
34856 |
+ * can happen with large stack limits and large mmap() |
34857 |
+ * allocations. |
34858 |
+ */ |
34859 |
++ mm->mmap_base = TASK_UNMAPPED_BASE; |
34860 |
++ |
34861 |
++#ifdef CONFIG_PAX_RANDMMAP |
34862 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
34863 |
++ mm->mmap_base += mm->delta_mmap; |
34864 |
++#endif |
34865 |
++ |
34866 |
++ mm->free_area_cache = mm->mmap_base; |
34867 |
+ mm->cached_hole_size = ~0UL; |
34868 |
+- mm->free_area_cache = TASK_UNMAPPED_BASE; |
34869 |
+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); |
34870 |
+ /* |
34871 |
+ * Restore the topdown base: |
34872 |
+ */ |
34873 |
+- mm->free_area_cache = mm->mmap_base; |
34874 |
++ mm->mmap_base = base; |
34875 |
++ mm->free_area_cache = base; |
34876 |
+ mm->cached_hole_size = ~0UL; |
34877 |
+ |
34878 |
+ return addr; |
34879 |
+@@ -1393,6 +1597,12 @@ bottomup: |
34880 |
+ |
34881 |
+ void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr) |
34882 |
+ { |
34883 |
++ |
34884 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34885 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr) |
34886 |
++ return; |
34887 |
++#endif |
34888 |
++ |
34889 |
+ /* |
34890 |
+ * Is this a new hole at the highest possible address? |
34891 |
+ */ |
34892 |
+@@ -1400,8 +1610,10 @@ void arch_unmap_area_topdown(struct mm_s |
34893 |
+ mm->free_area_cache = addr; |
34894 |
+ |
34895 |
+ /* dont allow allocations above current base */ |
34896 |
+- if (mm->free_area_cache > mm->mmap_base) |
34897 |
++ if (mm->free_area_cache > mm->mmap_base) { |
34898 |
+ mm->free_area_cache = mm->mmap_base; |
34899 |
++ mm->cached_hole_size = ~0UL; |
34900 |
++ } |
34901 |
+ } |
34902 |
+ |
34903 |
+ unsigned long |
34904 |
+@@ -1501,6 +1713,33 @@ out: |
34905 |
+ return prev ? prev->vm_next : vma; |
34906 |
+ } |
34907 |
+ |
34908 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34909 |
++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma) |
34910 |
++{ |
34911 |
++ struct vm_area_struct *vma_m; |
34912 |
++ |
34913 |
++ BUG_ON(!vma || vma->vm_start >= vma->vm_end); |
34914 |
++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) { |
34915 |
++ BUG_ON(vma->vm_mirror); |
34916 |
++ return NULL; |
34917 |
++ } |
34918 |
++ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1); |
34919 |
++ vma_m = vma->vm_mirror; |
34920 |
++ BUG_ON(!vma_m || vma_m->vm_mirror != vma); |
34921 |
++ BUG_ON(vma->vm_file != vma_m->vm_file); |
34922 |
++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start); |
34923 |
++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma); |
34924 |
++ |
34925 |
++#ifdef CONFIG_PAX_MPROTECT |
34926 |
++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE)); |
34927 |
++#else |
34928 |
++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED)); |
34929 |
++#endif |
34930 |
++ |
34931 |
++ return vma_m; |
34932 |
++} |
34933 |
++#endif |
34934 |
++ |
34935 |
+ /* |
34936 |
+ * Verify that the stack growth is acceptable and |
34937 |
+ * update accounting. This is shared with both the |
34938 |
+@@ -1517,6 +1756,7 @@ static int acct_stack_growth(struct vm_a |
34939 |
+ return -ENOMEM; |
34940 |
+ |
34941 |
+ /* Stack limit test */ |
34942 |
++ gr_learn_resource(current, RLIMIT_STACK, size, 1); |
34943 |
+ if (size > rlim[RLIMIT_STACK].rlim_cur) |
34944 |
+ return -ENOMEM; |
34945 |
+ |
34946 |
+@@ -1526,6 +1766,7 @@ static int acct_stack_growth(struct vm_a |
34947 |
+ unsigned long limit; |
34948 |
+ locked = mm->locked_vm + grow; |
34949 |
+ limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; |
34950 |
++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1); |
34951 |
+ if (locked > limit && !capable(CAP_IPC_LOCK)) |
34952 |
+ return -ENOMEM; |
34953 |
+ } |
34954 |
+@@ -1540,7 +1781,7 @@ static int acct_stack_growth(struct vm_a |
34955 |
+ * Overcommit.. This must be the final test, as it will |
34956 |
+ * update security statistics. |
34957 |
+ */ |
34958 |
+- if (security_vm_enough_memory(grow)) |
34959 |
++ if (security_vm_enough_memory_mm(mm, grow)) |
34960 |
+ return -ENOMEM; |
34961 |
+ |
34962 |
+ /* Ok, everything looks good - let it rip */ |
34963 |
+@@ -1561,35 +1802,40 @@ static inline |
34964 |
+ #endif |
34965 |
+ int expand_upwards(struct vm_area_struct *vma, unsigned long address) |
34966 |
+ { |
34967 |
+- int error; |
34968 |
++ int error, locknext; |
34969 |
+ |
34970 |
+ if (!(vma->vm_flags & VM_GROWSUP)) |
34971 |
+ return -EFAULT; |
34972 |
+ |
34973 |
++ /* Also guard against wrapping around to address 0. */ |
34974 |
++ if (address < PAGE_ALIGN(address+1)) |
34975 |
++ address = PAGE_ALIGN(address+1); |
34976 |
++ else |
34977 |
++ return -ENOMEM; |
34978 |
++ |
34979 |
+ /* |
34980 |
+ * We must make sure the anon_vma is allocated |
34981 |
+ * so that the anon_vma locking is not a noop. |
34982 |
+ */ |
34983 |
+ if (unlikely(anon_vma_prepare(vma))) |
34984 |
+ return -ENOMEM; |
34985 |
++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN); |
34986 |
++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next))) |
34987 |
++ return -ENOMEM; |
34988 |
+ anon_vma_lock(vma); |
34989 |
++ if (locknext) |
34990 |
++ anon_vma_lock(vma->vm_next); |
34991 |
+ |
34992 |
+ /* |
34993 |
+ * vma->vm_start/vm_end cannot change under us because the caller |
34994 |
+ * is required to hold the mmap_sem in read mode. We need the |
34995 |
+- * anon_vma lock to serialize against concurrent expand_stacks. |
34996 |
+- * Also guard against wrapping around to address 0. |
34997 |
++ * anon_vma locks to serialize against concurrent expand_stacks |
34998 |
++ * and expand_upwards. |
34999 |
+ */ |
35000 |
+- if (address < PAGE_ALIGN(address+4)) |
35001 |
+- address = PAGE_ALIGN(address+4); |
35002 |
+- else { |
35003 |
+- anon_vma_unlock(vma); |
35004 |
+- return -ENOMEM; |
35005 |
+- } |
35006 |
+ error = 0; |
35007 |
+ |
35008 |
+ /* Somebody else might have raced and expanded it already */ |
35009 |
+- if (address > vma->vm_end) { |
35010 |
++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) { |
35011 |
+ unsigned long size, grow; |
35012 |
+ |
35013 |
+ size = address - vma->vm_start; |
35014 |
+@@ -1599,6 +1845,8 @@ int expand_upwards(struct vm_area_struct |
35015 |
+ if (!error) |
35016 |
+ vma->vm_end = address; |
35017 |
+ } |
35018 |
++ if (locknext) |
35019 |
++ anon_vma_unlock(vma->vm_next); |
35020 |
+ anon_vma_unlock(vma); |
35021 |
+ return error; |
35022 |
+ } |
35023 |
+@@ -1610,7 +1858,8 @@ int expand_upwards(struct vm_area_struct |
35024 |
+ static inline int expand_downwards(struct vm_area_struct *vma, |
35025 |
+ unsigned long address) |
35026 |
+ { |
35027 |
+- int error; |
35028 |
++ int error, lockprev = 0; |
35029 |
++ struct vm_area_struct *prev = NULL; |
35030 |
+ |
35031 |
+ /* |
35032 |
+ * We must make sure the anon_vma is allocated |
35033 |
+@@ -1624,6 +1873,15 @@ static inline int expand_downwards(struc |
35034 |
+ if (error) |
35035 |
+ return error; |
35036 |
+ |
35037 |
++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64) |
35038 |
++ find_vma_prev(address, &prev); |
35039 |
++ lockprev = prev && (prev->vm_flags & VM_GROWSUP); |
35040 |
++#endif |
35041 |
++ if (lockprev && unlikely(anon_vma_prepare(prev))) |
35042 |
++ return -ENOMEM; |
35043 |
++ if (lockprev) |
35044 |
++ anon_vma_lock(prev); |
35045 |
++ |
35046 |
+ anon_vma_lock(vma); |
35047 |
+ |
35048 |
+ /* |
35049 |
+@@ -1633,9 +1891,15 @@ static inline int expand_downwards(struc |
35050 |
+ */ |
35051 |
+ |
35052 |
+ /* Somebody else might have raced and expanded it already */ |
35053 |
+- if (address < vma->vm_start) { |
35054 |
++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) { |
35055 |
+ unsigned long size, grow; |
35056 |
+ |
35057 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35058 |
++ struct vm_area_struct *vma_m; |
35059 |
++ |
35060 |
++ vma_m = pax_find_mirror_vma(vma); |
35061 |
++#endif |
35062 |
++ |
35063 |
+ size = vma->vm_end - address; |
35064 |
+ grow = (vma->vm_start - address) >> PAGE_SHIFT; |
35065 |
+ |
35066 |
+@@ -1643,9 +1907,20 @@ static inline int expand_downwards(struc |
35067 |
+ if (!error) { |
35068 |
+ vma->vm_start = address; |
35069 |
+ vma->vm_pgoff -= grow; |
35070 |
++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags); |
35071 |
++ |
35072 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35073 |
++ if (vma_m) { |
35074 |
++ vma_m->vm_start -= grow << PAGE_SHIFT; |
35075 |
++ vma_m->vm_pgoff -= grow; |
35076 |
++ } |
35077 |
++#endif |
35078 |
++ |
35079 |
+ } |
35080 |
+ } |
35081 |
+ anon_vma_unlock(vma); |
35082 |
++ if (lockprev) |
35083 |
++ anon_vma_unlock(prev); |
35084 |
+ return error; |
35085 |
+ } |
35086 |
+ |
35087 |
+@@ -1717,6 +1992,13 @@ static void remove_vma_list(struct mm_st |
35088 |
+ do { |
35089 |
+ long nrpages = vma_pages(vma); |
35090 |
+ |
35091 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35092 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) { |
35093 |
++ vma = remove_vma(vma); |
35094 |
++ continue; |
35095 |
++ } |
35096 |
++#endif |
35097 |
++ |
35098 |
+ mm->total_vm -= nrpages; |
35099 |
+ if (vma->vm_flags & VM_LOCKED) |
35100 |
+ mm->locked_vm -= nrpages; |
35101 |
+@@ -1763,6 +2045,16 @@ detach_vmas_to_be_unmapped(struct mm_str |
35102 |
+ |
35103 |
+ insertion_point = (prev ? &prev->vm_next : &mm->mmap); |
35104 |
+ do { |
35105 |
++ |
35106 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35107 |
++ if (vma->vm_mirror) { |
35108 |
++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma); |
35109 |
++ vma->vm_mirror->vm_mirror = NULL; |
35110 |
++ vma->vm_mirror->vm_flags &= ~VM_EXEC; |
35111 |
++ vma->vm_mirror = NULL; |
35112 |
++ } |
35113 |
++#endif |
35114 |
++ |
35115 |
+ rb_erase(&vma->vm_rb, &mm->mm_rb); |
35116 |
+ mm->map_count--; |
35117 |
+ tail_vma = vma; |
35118 |
+@@ -1782,6 +2074,112 @@ detach_vmas_to_be_unmapped(struct mm_str |
35119 |
+ * Split a vma into two pieces at address 'addr', a new vma is allocated |
35120 |
+ * either for the first part or the tail. |
35121 |
+ */ |
35122 |
++ |
35123 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35124 |
++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, |
35125 |
++ unsigned long addr, int new_below) |
35126 |
++{ |
35127 |
++ struct mempolicy *pol, *pol_m; |
35128 |
++ struct vm_area_struct *new, *vma_m, *new_m = NULL; |
35129 |
++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE; |
35130 |
++ |
35131 |
++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK)) |
35132 |
++ return -EINVAL; |
35133 |
++ |
35134 |
++ vma_m = pax_find_mirror_vma(vma); |
35135 |
++ if (vma_m) { |
35136 |
++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE); |
35137 |
++ if (mm->map_count >= sysctl_max_map_count-1) |
35138 |
++ return -ENOMEM; |
35139 |
++ } else if (mm->map_count >= sysctl_max_map_count) |
35140 |
++ return -ENOMEM; |
35141 |
++ |
35142 |
++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
35143 |
++ if (!new) |
35144 |
++ return -ENOMEM; |
35145 |
++ |
35146 |
++ if (vma_m) { |
35147 |
++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
35148 |
++ if (!new_m) { |
35149 |
++ kmem_cache_free(vm_area_cachep, new); |
35150 |
++ return -ENOMEM; |
35151 |
++ } |
35152 |
++ } |
35153 |
++ |
35154 |
++ /* most fields are the same, copy all, and then fixup */ |
35155 |
++ *new = *vma; |
35156 |
++ |
35157 |
++ if (new_below) |
35158 |
++ new->vm_end = addr; |
35159 |
++ else { |
35160 |
++ new->vm_start = addr; |
35161 |
++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT); |
35162 |
++ } |
35163 |
++ |
35164 |
++ if (vma_m) { |
35165 |
++ *new_m = *vma_m; |
35166 |
++ new_m->vm_mirror = new; |
35167 |
++ new->vm_mirror = new_m; |
35168 |
++ |
35169 |
++ if (new_below) |
35170 |
++ new_m->vm_end = addr_m; |
35171 |
++ else { |
35172 |
++ new_m->vm_start = addr_m; |
35173 |
++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT); |
35174 |
++ } |
35175 |
++ } |
35176 |
++ |
35177 |
++ pol = mpol_copy(vma_policy(vma)); |
35178 |
++ if (IS_ERR(pol)) { |
35179 |
++ if (new_m) |
35180 |
++ kmem_cache_free(vm_area_cachep, new_m); |
35181 |
++ kmem_cache_free(vm_area_cachep, new); |
35182 |
++ return PTR_ERR(pol); |
35183 |
++ } |
35184 |
++ |
35185 |
++ if (vma_m) { |
35186 |
++ pol_m = mpol_copy(vma_policy(vma_m)); |
35187 |
++ if (IS_ERR(pol_m)) { |
35188 |
++ mpol_free(pol); |
35189 |
++ kmem_cache_free(vm_area_cachep, new_m); |
35190 |
++ kmem_cache_free(vm_area_cachep, new); |
35191 |
++ return PTR_ERR(pol); |
35192 |
++ } |
35193 |
++ } |
35194 |
++ |
35195 |
++ vma_set_policy(new, pol); |
35196 |
++ |
35197 |
++ if (new->vm_file) |
35198 |
++ get_file(new->vm_file); |
35199 |
++ |
35200 |
++ if (new->vm_ops && new->vm_ops->open) |
35201 |
++ new->vm_ops->open(new); |
35202 |
++ |
35203 |
++ if (new_below) |
35204 |
++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff + |
35205 |
++ ((addr - new->vm_start) >> PAGE_SHIFT), new); |
35206 |
++ else |
35207 |
++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); |
35208 |
++ |
35209 |
++ if (vma_m) { |
35210 |
++ vma_set_policy(new_m, pol_m); |
35211 |
++ |
35212 |
++ if (new_m->vm_file) |
35213 |
++ get_file(new_m->vm_file); |
35214 |
++ |
35215 |
++ if (new_m->vm_ops && new_m->vm_ops->open) |
35216 |
++ new_m->vm_ops->open(new_m); |
35217 |
++ |
35218 |
++ if (new_below) |
35219 |
++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff + |
35220 |
++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m); |
35221 |
++ else |
35222 |
++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m); |
35223 |
++ } |
35224 |
++ |
35225 |
++ return 0; |
35226 |
++} |
35227 |
++#else |
35228 |
+ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, |
35229 |
+ unsigned long addr, int new_below) |
35230 |
+ { |
35231 |
+@@ -1829,17 +2227,37 @@ int split_vma(struct mm_struct * mm, str |
35232 |
+ |
35233 |
+ return 0; |
35234 |
+ } |
35235 |
++#endif |
35236 |
+ |
35237 |
+ /* Munmap is split into 2 main parts -- this part which finds |
35238 |
+ * what needs doing, and the areas themselves, which do the |
35239 |
+ * work. This now handles partial unmappings. |
35240 |
+ * Jeremy Fitzhardinge <jeremy@××××.org> |
35241 |
+ */ |
35242 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35243 |
++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) |
35244 |
++{ |
35245 |
++ int ret = __do_munmap(mm, start, len); |
35246 |
++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC)) |
35247 |
++ return ret; |
35248 |
++ |
35249 |
++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len); |
35250 |
++} |
35251 |
++ |
35252 |
++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len) |
35253 |
++#else |
35254 |
+ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) |
35255 |
++#endif |
35256 |
+ { |
35257 |
+ unsigned long end; |
35258 |
+ struct vm_area_struct *vma, *prev, *last; |
35259 |
+ |
35260 |
++ /* |
35261 |
++ * mm->mmap_sem is required to protect against another thread |
35262 |
++ * changing the mappings in case we sleep. |
35263 |
++ */ |
35264 |
++ verify_mm_writelocked(mm); |
35265 |
++ |
35266 |
+ if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start) |
35267 |
+ return -EINVAL; |
35268 |
+ |
35269 |
+@@ -1889,6 +2307,8 @@ int do_munmap(struct mm_struct *mm, unsi |
35270 |
+ /* Fix up all other VM information */ |
35271 |
+ remove_vma_list(mm, vma); |
35272 |
+ |
35273 |
++ track_exec_limit(mm, start, end, 0UL); |
35274 |
++ |
35275 |
+ return 0; |
35276 |
+ } |
35277 |
+ |
35278 |
+@@ -1901,22 +2321,18 @@ asmlinkage long sys_munmap(unsigned long |
35279 |
+ |
35280 |
+ profile_munmap(addr); |
35281 |
+ |
35282 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35283 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && |
35284 |
++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)) |
35285 |
++ return -EINVAL; |
35286 |
++#endif |
35287 |
++ |
35288 |
+ down_write(&mm->mmap_sem); |
35289 |
+ ret = do_munmap(mm, addr, len); |
35290 |
+ up_write(&mm->mmap_sem); |
35291 |
+ return ret; |
35292 |
+ } |
35293 |
+ |
35294 |
+-static inline void verify_mm_writelocked(struct mm_struct *mm) |
35295 |
+-{ |
35296 |
+-#ifdef CONFIG_DEBUG_VM |
35297 |
+- if (unlikely(down_read_trylock(&mm->mmap_sem))) { |
35298 |
+- WARN_ON(1); |
35299 |
+- up_read(&mm->mmap_sem); |
35300 |
+- } |
35301 |
+-#endif |
35302 |
+-} |
35303 |
+- |
35304 |
+ /* |
35305 |
+ * this is really a simplified "do_mmap". it only handles |
35306 |
+ * anonymous maps. eventually we may be able to do some |
35307 |
+@@ -1930,6 +2346,11 @@ unsigned long do_brk(unsigned long addr, |
35308 |
+ struct rb_node ** rb_link, * rb_parent; |
35309 |
+ pgoff_t pgoff = addr >> PAGE_SHIFT; |
35310 |
+ int error; |
35311 |
++ unsigned long charged; |
35312 |
++ |
35313 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35314 |
++ struct vm_area_struct *vma_m = NULL; |
35315 |
++#endif |
35316 |
+ |
35317 |
+ len = PAGE_ALIGN(len); |
35318 |
+ if (!len) |
35319 |
+@@ -1947,19 +2368,34 @@ unsigned long do_brk(unsigned long addr, |
35320 |
+ |
35321 |
+ flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; |
35322 |
+ |
35323 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
35324 |
++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
35325 |
++ flags &= ~VM_EXEC; |
35326 |
++ |
35327 |
++#ifdef CONFIG_PAX_MPROTECT |
35328 |
++ if (mm->pax_flags & MF_PAX_MPROTECT) |
35329 |
++ flags &= ~VM_MAYEXEC; |
35330 |
++#endif |
35331 |
++ |
35332 |
++ } |
35333 |
++#endif |
35334 |
++ |
35335 |
+ error = arch_mmap_check(addr, len, flags); |
35336 |
+ if (error) |
35337 |
+ return error; |
35338 |
+ |
35339 |
++ charged = len >> PAGE_SHIFT; |
35340 |
++ |
35341 |
+ /* |
35342 |
+ * mlock MCL_FUTURE? |
35343 |
+ */ |
35344 |
+ if (mm->def_flags & VM_LOCKED) { |
35345 |
+ unsigned long locked, lock_limit; |
35346 |
+- locked = len >> PAGE_SHIFT; |
35347 |
++ locked = charged; |
35348 |
+ locked += mm->locked_vm; |
35349 |
+ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; |
35350 |
+ lock_limit >>= PAGE_SHIFT; |
35351 |
++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1); |
35352 |
+ if (locked > lock_limit && !capable(CAP_IPC_LOCK)) |
35353 |
+ return -EAGAIN; |
35354 |
+ } |
35355 |
+@@ -1973,22 +2409,22 @@ unsigned long do_brk(unsigned long addr, |
35356 |
+ /* |
35357 |
+ * Clear old maps. this also does some error checking for us |
35358 |
+ */ |
35359 |
+- munmap_back: |
35360 |
+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); |
35361 |
+ if (vma && vma->vm_start < addr + len) { |
35362 |
+ if (do_munmap(mm, addr, len)) |
35363 |
+ return -ENOMEM; |
35364 |
+- goto munmap_back; |
35365 |
++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); |
35366 |
++ BUG_ON(vma && vma->vm_start < addr + len); |
35367 |
+ } |
35368 |
+ |
35369 |
+ /* Check against address space limits *after* clearing old maps... */ |
35370 |
+- if (!may_expand_vm(mm, len >> PAGE_SHIFT)) |
35371 |
++ if (!may_expand_vm(mm, charged)) |
35372 |
+ return -ENOMEM; |
35373 |
+ |
35374 |
+ if (mm->map_count > sysctl_max_map_count) |
35375 |
+ return -ENOMEM; |
35376 |
+ |
35377 |
+- if (security_vm_enough_memory(len >> PAGE_SHIFT)) |
35378 |
++ if (security_vm_enough_memory(charged)) |
35379 |
+ return -ENOMEM; |
35380 |
+ |
35381 |
+ /* Can we just expand an old private anonymous mapping? */ |
35382 |
+@@ -2001,10 +2437,21 @@ unsigned long do_brk(unsigned long addr, |
35383 |
+ */ |
35384 |
+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
35385 |
+ if (!vma) { |
35386 |
+- vm_unacct_memory(len >> PAGE_SHIFT); |
35387 |
++ vm_unacct_memory(charged); |
35388 |
+ return -ENOMEM; |
35389 |
+ } |
35390 |
+ |
35391 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35392 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) { |
35393 |
++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
35394 |
++ if (!vma_m) { |
35395 |
++ kmem_cache_free(vm_area_cachep, vma); |
35396 |
++ vm_unacct_memory(charged); |
35397 |
++ return -ENOMEM; |
35398 |
++ } |
35399 |
++ } |
35400 |
++#endif |
35401 |
++ |
35402 |
+ vma->vm_mm = mm; |
35403 |
+ vma->vm_start = addr; |
35404 |
+ vma->vm_end = addr + len; |
35405 |
+@@ -2012,12 +2459,19 @@ unsigned long do_brk(unsigned long addr, |
35406 |
+ vma->vm_flags = flags; |
35407 |
+ vma->vm_page_prot = vm_get_page_prot(flags); |
35408 |
+ vma_link(mm, vma, prev, rb_link, rb_parent); |
35409 |
++ |
35410 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35411 |
++ if (vma_m) |
35412 |
++ pax_mirror_vma(vma_m, vma); |
35413 |
++#endif |
35414 |
++ |
35415 |
+ out: |
35416 |
+- mm->total_vm += len >> PAGE_SHIFT; |
35417 |
++ mm->total_vm += charged; |
35418 |
+ if (flags & VM_LOCKED) { |
35419 |
+- mm->locked_vm += len >> PAGE_SHIFT; |
35420 |
++ mm->locked_vm += charged; |
35421 |
+ make_pages_present(addr, addr + len); |
35422 |
+ } |
35423 |
++ track_exec_limit(mm, addr, addr + len, flags); |
35424 |
+ return addr; |
35425 |
+ } |
35426 |
+ |
35427 |
+@@ -2048,8 +2502,10 @@ void exit_mmap(struct mm_struct *mm) |
35428 |
+ * Walk the list again, actually closing and freeing it, |
35429 |
+ * with preemption enabled, without holding any MM locks. |
35430 |
+ */ |
35431 |
+- while (vma) |
35432 |
++ while (vma) { |
35433 |
++ vma->vm_mirror = NULL; |
35434 |
+ vma = remove_vma(vma); |
35435 |
++ } |
35436 |
+ |
35437 |
+ BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT); |
35438 |
+ } |
35439 |
+@@ -2063,6 +2519,10 @@ int insert_vm_struct(struct mm_struct * |
35440 |
+ struct vm_area_struct * __vma, * prev; |
35441 |
+ struct rb_node ** rb_link, * rb_parent; |
35442 |
+ |
35443 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35444 |
++ struct vm_area_struct *vma_m = NULL; |
35445 |
++#endif |
35446 |
++ |
35447 |
+ /* |
35448 |
+ * The vm_pgoff of a purely anonymous vma should be irrelevant |
35449 |
+ * until its first write fault, when page's anon_vma and index |
35450 |
+@@ -2085,7 +2545,22 @@ int insert_vm_struct(struct mm_struct * |
35451 |
+ if ((vma->vm_flags & VM_ACCOUNT) && |
35452 |
+ security_vm_enough_memory_mm(mm, vma_pages(vma))) |
35453 |
+ return -ENOMEM; |
35454 |
++ |
35455 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35456 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) { |
35457 |
++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
35458 |
++ if (!vma_m) |
35459 |
++ return -ENOMEM; |
35460 |
++ } |
35461 |
++#endif |
35462 |
++ |
35463 |
+ vma_link(mm, vma, prev, rb_link, rb_parent); |
35464 |
++ |
35465 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35466 |
++ if (vma_m) |
35467 |
++ pax_mirror_vma(vma_m, vma); |
35468 |
++#endif |
35469 |
++ |
35470 |
+ return 0; |
35471 |
+ } |
35472 |
+ |
35473 |
+@@ -2103,6 +2578,8 @@ struct vm_area_struct *copy_vma(struct v |
35474 |
+ struct rb_node **rb_link, *rb_parent; |
35475 |
+ struct mempolicy *pol; |
35476 |
+ |
35477 |
++ BUG_ON(vma->vm_mirror); |
35478 |
++ |
35479 |
+ /* |
35480 |
+ * If anonymous vma has not yet been faulted, update new pgoff |
35481 |
+ * to match new location, to increase its chance of merging. |
35482 |
+@@ -2143,6 +2620,34 @@ struct vm_area_struct *copy_vma(struct v |
35483 |
+ return new_vma; |
35484 |
+ } |
35485 |
+ |
35486 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35487 |
++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma) |
35488 |
++{ |
35489 |
++ struct vm_area_struct *prev_m; |
35490 |
++ struct rb_node **rb_link_m, *rb_parent_m; |
35491 |
++ struct mempolicy *pol_m; |
35492 |
++ |
35493 |
++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)); |
35494 |
++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror); |
35495 |
++ BUG_ON(!vma_mpol_equal(vma, vma_m)); |
35496 |
++ pol_m = vma_policy(vma_m); |
35497 |
++ *vma_m = *vma; |
35498 |
++ vma_set_policy(vma_m, pol_m); |
35499 |
++ vma_m->vm_start += SEGMEXEC_TASK_SIZE; |
35500 |
++ vma_m->vm_end += SEGMEXEC_TASK_SIZE; |
35501 |
++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED); |
35502 |
++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags); |
35503 |
++ if (vma_m->vm_file) |
35504 |
++ get_file(vma_m->vm_file); |
35505 |
++ if (vma_m->vm_ops && vma_m->vm_ops->open) |
35506 |
++ vma_m->vm_ops->open(vma_m); |
35507 |
++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m); |
35508 |
++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m); |
35509 |
++ vma_m->vm_mirror = vma; |
35510 |
++ vma->vm_mirror = vma_m; |
35511 |
++} |
35512 |
++#endif |
35513 |
++ |
35514 |
+ /* |
35515 |
+ * Return true if the calling process may expand its vm space by the passed |
35516 |
+ * number of pages |
35517 |
+@@ -2153,7 +2658,7 @@ int may_expand_vm(struct mm_struct *mm, |
35518 |
+ unsigned long lim; |
35519 |
+ |
35520 |
+ lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; |
35521 |
+- |
35522 |
++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1); |
35523 |
+ if (cur + npages > lim) |
35524 |
+ return 0; |
35525 |
+ return 1; |
35526 |
+@@ -2165,7 +2670,7 @@ static struct page *special_mapping_nopa |
35527 |
+ { |
35528 |
+ struct page **pages; |
35529 |
+ |
35530 |
+- BUG_ON(address < vma->vm_start || address >= vma->vm_end); |
35531 |
++ BUG_ON(address < vma->vm_start || address >= vma->vm_end || (address & ~PAGE_MASK)); |
35532 |
+ |
35533 |
+ address -= vma->vm_start; |
35534 |
+ for (pages = vma->vm_private_data; address > 0 && *pages; ++pages) |
35535 |
+@@ -2215,6 +2720,15 @@ int install_special_mapping(struct mm_st |
35536 |
+ vma->vm_start = addr; |
35537 |
+ vma->vm_end = addr + len; |
35538 |
+ |
35539 |
++#ifdef CONFIG_PAX_MPROTECT |
35540 |
++ if (mm->pax_flags & MF_PAX_MPROTECT) { |
35541 |
++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC) |
35542 |
++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC); |
35543 |
++ else |
35544 |
++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE); |
35545 |
++ } |
35546 |
++#endif |
35547 |
++ |
35548 |
+ vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND; |
35549 |
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
35550 |
+ |
35551 |
+diff -urNp linux-2.6.24.4/mm/mprotect.c linux-2.6.24.4/mm/mprotect.c |
35552 |
+--- linux-2.6.24.4/mm/mprotect.c 2008-03-24 14:49:18.000000000 -0400 |
35553 |
++++ linux-2.6.24.4/mm/mprotect.c 2008-03-26 17:56:56.000000000 -0400 |
35554 |
+@@ -21,10 +21,17 @@ |
35555 |
+ #include <linux/syscalls.h> |
35556 |
+ #include <linux/swap.h> |
35557 |
+ #include <linux/swapops.h> |
35558 |
++#include <linux/grsecurity.h> |
35559 |
++ |
35560 |
++#ifdef CONFIG_PAX_MPROTECT |
35561 |
++#include <linux/elf.h> |
35562 |
++#endif |
35563 |
++ |
35564 |
+ #include <asm/uaccess.h> |
35565 |
+ #include <asm/pgtable.h> |
35566 |
+ #include <asm/cacheflush.h> |
35567 |
+ #include <asm/tlbflush.h> |
35568 |
++#include <asm/mmu_context.h> |
35569 |
+ |
35570 |
+ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd, |
35571 |
+ unsigned long addr, unsigned long end, pgprot_t newprot, |
35572 |
+@@ -127,6 +134,48 @@ static void change_protection(struct vm_ |
35573 |
+ flush_tlb_range(vma, start, end); |
35574 |
+ } |
35575 |
+ |
35576 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
35577 |
++/* called while holding the mmap semaphor for writing except stack expansion */ |
35578 |
++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) |
35579 |
++{ |
35580 |
++ unsigned long oldlimit, newlimit = 0UL; |
35581 |
++ |
35582 |
++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled) |
35583 |
++ return; |
35584 |
++ |
35585 |
++ spin_lock(&mm->page_table_lock); |
35586 |
++ oldlimit = mm->context.user_cs_limit; |
35587 |
++ if ((prot & VM_EXEC) && oldlimit < end) |
35588 |
++ /* USER_CS limit moved up */ |
35589 |
++ newlimit = end; |
35590 |
++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end) |
35591 |
++ /* USER_CS limit moved down */ |
35592 |
++ newlimit = start; |
35593 |
++ |
35594 |
++ if (newlimit) { |
35595 |
++ mm->context.user_cs_limit = newlimit; |
35596 |
++ |
35597 |
++#ifdef CONFIG_SMP |
35598 |
++ wmb(); |
35599 |
++ cpus_clear(mm->context.cpu_user_cs_mask); |
35600 |
++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask); |
35601 |
++#endif |
35602 |
++ |
35603 |
++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id()); |
35604 |
++ } |
35605 |
++ spin_unlock(&mm->page_table_lock); |
35606 |
++ if (newlimit == end) { |
35607 |
++ struct vm_area_struct *vma = find_vma(mm, oldlimit); |
35608 |
++ |
35609 |
++ for (; vma && vma->vm_start < end; vma = vma->vm_next) |
35610 |
++ if (is_vm_hugetlb_page(vma)) |
35611 |
++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot); |
35612 |
++ else |
35613 |
++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma)); |
35614 |
++ } |
35615 |
++} |
35616 |
++#endif |
35617 |
++ |
35618 |
+ int |
35619 |
+ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, |
35620 |
+ unsigned long start, unsigned long end, unsigned long newflags) |
35621 |
+@@ -139,11 +188,41 @@ mprotect_fixup(struct vm_area_struct *vm |
35622 |
+ int error; |
35623 |
+ int dirty_accountable = 0; |
35624 |
+ |
35625 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35626 |
++ struct vm_area_struct *vma_m = NULL; |
35627 |
++ unsigned long start_m, end_m; |
35628 |
++ |
35629 |
++ start_m = start + SEGMEXEC_TASK_SIZE; |
35630 |
++ end_m = end + SEGMEXEC_TASK_SIZE; |
35631 |
++#endif |
35632 |
++ |
35633 |
+ if (newflags == oldflags) { |
35634 |
+ *pprev = vma; |
35635 |
+ return 0; |
35636 |
+ } |
35637 |
+ |
35638 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35639 |
++ if (pax_find_mirror_vma(vma) && !(newflags & VM_EXEC)) { |
35640 |
++ if (start != vma->vm_start) { |
35641 |
++ error = split_vma(mm, vma, start, 1); |
35642 |
++ if (error) |
35643 |
++ return -ENOMEM; |
35644 |
++ BUG_ON(!*pprev || (*pprev)->vm_next == vma); |
35645 |
++ *pprev = (*pprev)->vm_next; |
35646 |
++ } |
35647 |
++ |
35648 |
++ if (end != vma->vm_end) { |
35649 |
++ error = split_vma(mm, vma, end, 0); |
35650 |
++ if (error) |
35651 |
++ return -ENOMEM; |
35652 |
++ } |
35653 |
++ |
35654 |
++ error = __do_munmap(mm, start_m, end_m - start_m); |
35655 |
++ if (error) |
35656 |
++ return -ENOMEM; |
35657 |
++ } |
35658 |
++#endif |
35659 |
++ |
35660 |
+ /* |
35661 |
+ * If we make a private mapping writable we increase our commit; |
35662 |
+ * but (without finer accounting) cannot reduce our commit if we |
35663 |
+@@ -186,6 +265,25 @@ mprotect_fixup(struct vm_area_struct *vm |
35664 |
+ goto fail; |
35665 |
+ } |
35666 |
+ |
35667 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35668 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) { |
35669 |
++ struct mempolicy *pol; |
35670 |
++ |
35671 |
++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
35672 |
++ if (!vma_m) { |
35673 |
++ error = -ENOMEM; |
35674 |
++ goto fail; |
35675 |
++ } |
35676 |
++ pol = mpol_copy(vma_policy(vma)); |
35677 |
++ if (IS_ERR(pol)) { |
35678 |
++ kmem_cache_free(vm_area_cachep, vma_m); |
35679 |
++ error = -ENOMEM; |
35680 |
++ goto fail; |
35681 |
++ } |
35682 |
++ vma_set_policy(vma_m, pol); |
35683 |
++ } |
35684 |
++#endif |
35685 |
++ |
35686 |
+ success: |
35687 |
+ /* |
35688 |
+ * vm_flags and vm_page_prot are protected by the mmap_sem |
35689 |
+@@ -202,6 +300,12 @@ success: |
35690 |
+ hugetlb_change_protection(vma, start, end, vma->vm_page_prot); |
35691 |
+ else |
35692 |
+ change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable); |
35693 |
++ |
35694 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35695 |
++ if (vma_m) |
35696 |
++ pax_mirror_vma(vma_m, vma); |
35697 |
++#endif |
35698 |
++ |
35699 |
+ vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); |
35700 |
+ vm_stat_account(mm, newflags, vma->vm_file, nrpages); |
35701 |
+ return 0; |
35702 |
+@@ -211,6 +315,70 @@ fail: |
35703 |
+ return error; |
35704 |
+ } |
35705 |
+ |
35706 |
++#ifdef CONFIG_PAX_MPROTECT |
35707 |
++/* PaX: non-PIC ELF libraries need relocations on their executable segments |
35708 |
++ * therefore we'll grant them VM_MAYWRITE once during their life. |
35709 |
++ * |
35710 |
++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment |
35711 |
++ * basis because we want to allow the common case and not the special ones. |
35712 |
++ */ |
35713 |
++static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start) |
35714 |
++{ |
35715 |
++ struct elfhdr elf_h; |
35716 |
++ struct elf_phdr elf_p; |
35717 |
++ elf_addr_t dyn_offset = 0UL; |
35718 |
++ elf_dyn dyn; |
35719 |
++ unsigned long i, j = 65536UL / sizeof(struct elf_phdr); |
35720 |
++ |
35721 |
++#ifndef CONFIG_PAX_NOELFRELOCS |
35722 |
++ if ((vma->vm_start != start) || |
35723 |
++ !vma->vm_file || |
35724 |
++ !(vma->vm_flags & VM_MAYEXEC) || |
35725 |
++ (vma->vm_flags & VM_MAYNOTWRITE)) |
35726 |
++#endif |
35727 |
++ |
35728 |
++ return; |
35729 |
++ |
35730 |
++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) || |
35731 |
++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) || |
35732 |
++ |
35733 |
++#ifdef CONFIG_PAX_ETEXECRELOCS |
35734 |
++ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) || |
35735 |
++#else |
35736 |
++ elf_h.e_type != ET_DYN || |
35737 |
++#endif |
35738 |
++ |
35739 |
++ !elf_check_arch(&elf_h) || |
35740 |
++ elf_h.e_phentsize != sizeof(struct elf_phdr) || |
35741 |
++ elf_h.e_phnum > j) |
35742 |
++ return; |
35743 |
++ |
35744 |
++ for (i = 0UL; i < elf_h.e_phnum; i++) { |
35745 |
++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p))) |
35746 |
++ return; |
35747 |
++ if (elf_p.p_type == PT_DYNAMIC) { |
35748 |
++ dyn_offset = elf_p.p_offset; |
35749 |
++ j = i; |
35750 |
++ } |
35751 |
++ } |
35752 |
++ if (elf_h.e_phnum <= j) |
35753 |
++ return; |
35754 |
++ |
35755 |
++ i = 0UL; |
35756 |
++ do { |
35757 |
++ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn))) |
35758 |
++ return; |
35759 |
++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) { |
35760 |
++ gr_log_textrel(vma); |
35761 |
++ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE; |
35762 |
++ return; |
35763 |
++ } |
35764 |
++ i++; |
35765 |
++ } while (dyn.d_tag != DT_NULL); |
35766 |
++ return; |
35767 |
++} |
35768 |
++#endif |
35769 |
++ |
35770 |
+ asmlinkage long |
35771 |
+ sys_mprotect(unsigned long start, size_t len, unsigned long prot) |
35772 |
+ { |
35773 |
+@@ -230,6 +398,17 @@ sys_mprotect(unsigned long start, size_t |
35774 |
+ end = start + len; |
35775 |
+ if (end <= start) |
35776 |
+ return -ENOMEM; |
35777 |
++ |
35778 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35779 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { |
35780 |
++ if (end > SEGMEXEC_TASK_SIZE) |
35781 |
++ return -EINVAL; |
35782 |
++ } else |
35783 |
++#endif |
35784 |
++ |
35785 |
++ if (end > TASK_SIZE) |
35786 |
++ return -EINVAL; |
35787 |
++ |
35788 |
+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM)) |
35789 |
+ return -EINVAL; |
35790 |
+ |
35791 |
+@@ -237,7 +416,7 @@ sys_mprotect(unsigned long start, size_t |
35792 |
+ /* |
35793 |
+ * Does the application expect PROT_READ to imply PROT_EXEC: |
35794 |
+ */ |
35795 |
+- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) |
35796 |
++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC)) |
35797 |
+ prot |= PROT_EXEC; |
35798 |
+ |
35799 |
+ vm_flags = calc_vm_prot_bits(prot); |
35800 |
+@@ -269,6 +448,16 @@ sys_mprotect(unsigned long start, size_t |
35801 |
+ if (start > vma->vm_start) |
35802 |
+ prev = vma; |
35803 |
+ |
35804 |
++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) { |
35805 |
++ error = -EACCES; |
35806 |
++ goto out; |
35807 |
++ } |
35808 |
++ |
35809 |
++#ifdef CONFIG_PAX_MPROTECT |
35810 |
++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE)) |
35811 |
++ pax_handle_maywrite(vma, start); |
35812 |
++#endif |
35813 |
++ |
35814 |
+ for (nstart = start ; ; ) { |
35815 |
+ unsigned long newflags; |
35816 |
+ |
35817 |
+@@ -282,6 +471,12 @@ sys_mprotect(unsigned long start, size_t |
35818 |
+ goto out; |
35819 |
+ } |
35820 |
+ |
35821 |
++#ifdef CONFIG_PAX_MPROTECT |
35822 |
++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */ |
35823 |
++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE)) |
35824 |
++ newflags &= ~VM_MAYWRITE; |
35825 |
++#endif |
35826 |
++ |
35827 |
+ error = security_file_mprotect(vma, reqprot, prot); |
35828 |
+ if (error) |
35829 |
+ goto out; |
35830 |
+@@ -292,6 +487,9 @@ sys_mprotect(unsigned long start, size_t |
35831 |
+ error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); |
35832 |
+ if (error) |
35833 |
+ goto out; |
35834 |
++ |
35835 |
++ track_exec_limit(current->mm, nstart, tmp, vm_flags); |
35836 |
++ |
35837 |
+ nstart = tmp; |
35838 |
+ |
35839 |
+ if (nstart < prev->vm_end) |
35840 |
+diff -urNp linux-2.6.24.4/mm/mremap.c linux-2.6.24.4/mm/mremap.c |
35841 |
+--- linux-2.6.24.4/mm/mremap.c 2008-03-24 14:49:18.000000000 -0400 |
35842 |
++++ linux-2.6.24.4/mm/mremap.c 2008-03-26 17:56:56.000000000 -0400 |
35843 |
+@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str |
35844 |
+ continue; |
35845 |
+ pte = ptep_clear_flush(vma, old_addr, old_pte); |
35846 |
+ pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr); |
35847 |
++ |
35848 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
35849 |
++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC) |
35850 |
++ pte = pte_exprotect(pte); |
35851 |
++#endif |
35852 |
++ |
35853 |
+ set_pte_at(mm, new_addr, new_pte, pte); |
35854 |
+ } |
35855 |
+ |
35856 |
+@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad |
35857 |
+ struct vm_area_struct *vma; |
35858 |
+ unsigned long ret = -EINVAL; |
35859 |
+ unsigned long charged = 0; |
35860 |
++ unsigned long task_size = TASK_SIZE; |
35861 |
+ |
35862 |
+ if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) |
35863 |
+ goto out; |
35864 |
+@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad |
35865 |
+ if (!new_len) |
35866 |
+ goto out; |
35867 |
+ |
35868 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35869 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) |
35870 |
++ task_size = SEGMEXEC_TASK_SIZE; |
35871 |
++#endif |
35872 |
++ |
35873 |
++ if (new_len > task_size || addr > task_size-new_len || |
35874 |
++ old_len > task_size || addr > task_size-old_len) |
35875 |
++ goto out; |
35876 |
++ |
35877 |
+ /* new_addr is only valid if MREMAP_FIXED is specified */ |
35878 |
+ if (flags & MREMAP_FIXED) { |
35879 |
+ if (new_addr & ~PAGE_MASK) |
35880 |
+@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad |
35881 |
+ if (!(flags & MREMAP_MAYMOVE)) |
35882 |
+ goto out; |
35883 |
+ |
35884 |
+- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len) |
35885 |
++ if (new_addr > task_size - new_len) |
35886 |
+ goto out; |
35887 |
+ |
35888 |
+ /* Check if the location we're moving into overlaps the |
35889 |
+ * old location at all, and fail if it does. |
35890 |
+ */ |
35891 |
+- if ((new_addr <= addr) && (new_addr+new_len) > addr) |
35892 |
+- goto out; |
35893 |
+- |
35894 |
+- if ((addr <= new_addr) && (addr+old_len) > new_addr) |
35895 |
++ if (addr + old_len > new_addr && new_addr + new_len > addr) |
35896 |
+ goto out; |
35897 |
+ |
35898 |
+ ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); |
35899 |
+@@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad |
35900 |
+ ret = -EINVAL; |
35901 |
+ goto out; |
35902 |
+ } |
35903 |
++ |
35904 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35905 |
++ if (pax_find_mirror_vma(vma)) { |
35906 |
++ ret = -EINVAL; |
35907 |
++ goto out; |
35908 |
++ } |
35909 |
++#endif |
35910 |
++ |
35911 |
+ /* We can't remap across vm area boundaries */ |
35912 |
+ if (old_len > vma->vm_end - addr) |
35913 |
+ goto out; |
35914 |
+@@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad |
35915 |
+ if (old_len == vma->vm_end - addr && |
35916 |
+ !((flags & MREMAP_FIXED) && (addr != new_addr)) && |
35917 |
+ (old_len != new_len || !(flags & MREMAP_MAYMOVE))) { |
35918 |
+- unsigned long max_addr = TASK_SIZE; |
35919 |
++ unsigned long max_addr = task_size; |
35920 |
+ if (vma->vm_next) |
35921 |
+ max_addr = vma->vm_next->vm_start; |
35922 |
+ /* can we just expand the current mapping? */ |
35923 |
+@@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad |
35924 |
+ addr + new_len); |
35925 |
+ } |
35926 |
+ ret = addr; |
35927 |
++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags); |
35928 |
+ goto out; |
35929 |
+ } |
35930 |
+ } |
35931 |
+@@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad |
35932 |
+ */ |
35933 |
+ ret = -ENOMEM; |
35934 |
+ if (flags & MREMAP_MAYMOVE) { |
35935 |
++ unsigned long map_flags = 0; |
35936 |
+ if (!(flags & MREMAP_FIXED)) { |
35937 |
+- unsigned long map_flags = 0; |
35938 |
+ if (vma->vm_flags & VM_MAYSHARE) |
35939 |
+ map_flags |= MAP_SHARED; |
35940 |
+ |
35941 |
+@@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad |
35942 |
+ if (ret) |
35943 |
+ goto out; |
35944 |
+ } |
35945 |
++ map_flags = vma->vm_flags; |
35946 |
+ ret = move_vma(vma, addr, old_len, new_len, new_addr); |
35947 |
++ if (!(ret & ~PAGE_MASK)) { |
35948 |
++ track_exec_limit(current->mm, addr, addr + old_len, 0UL); |
35949 |
++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags); |
35950 |
++ } |
35951 |
+ } |
35952 |
+ out: |
35953 |
+ if (ret & ~PAGE_MASK) |
35954 |
+diff -urNp linux-2.6.24.4/mm/nommu.c linux-2.6.24.4/mm/nommu.c |
35955 |
+--- linux-2.6.24.4/mm/nommu.c 2008-03-24 14:49:18.000000000 -0400 |
35956 |
++++ linux-2.6.24.4/mm/nommu.c 2008-03-26 17:56:56.000000000 -0400 |
35957 |
+@@ -377,15 +377,6 @@ struct vm_area_struct *find_vma(struct m |
35958 |
+ } |
35959 |
+ EXPORT_SYMBOL(find_vma); |
35960 |
+ |
35961 |
+-/* |
35962 |
+- * find a VMA |
35963 |
+- * - we don't extend stack VMAs under NOMMU conditions |
35964 |
+- */ |
35965 |
+-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr) |
35966 |
+-{ |
35967 |
+- return find_vma(mm, addr); |
35968 |
+-} |
35969 |
+- |
35970 |
+ int expand_stack(struct vm_area_struct *vma, unsigned long address) |
35971 |
+ { |
35972 |
+ return -ENOMEM; |
35973 |
+diff -urNp linux-2.6.24.4/mm/page_alloc.c linux-2.6.24.4/mm/page_alloc.c |
35974 |
+--- linux-2.6.24.4/mm/page_alloc.c 2008-03-24 14:49:18.000000000 -0400 |
35975 |
++++ linux-2.6.24.4/mm/page_alloc.c 2008-03-26 17:56:56.000000000 -0400 |
35976 |
+@@ -505,9 +505,20 @@ static void free_pages_bulk(struct zone |
35977 |
+ |
35978 |
+ static void free_one_page(struct zone *zone, struct page *page, int order) |
35979 |
+ { |
35980 |
++ |
35981 |
++#ifdef CONFIG_PAX_MEMORY_SANITIZE |
35982 |
++ unsigned long index = 1UL << order; |
35983 |
++#endif |
35984 |
++ |
35985 |
+ spin_lock(&zone->lock); |
35986 |
+ zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE); |
35987 |
+ zone->pages_scanned = 0; |
35988 |
++ |
35989 |
++#ifdef CONFIG_PAX_MEMORY_SANITIZE |
35990 |
++ for (; index; --index) |
35991 |
++ sanitize_highpage(page + index - 1); |
35992 |
++#endif |
35993 |
++ |
35994 |
+ __free_one_page(page, zone, order); |
35995 |
+ spin_unlock(&zone->lock); |
35996 |
+ } |
35997 |
+@@ -631,8 +642,10 @@ static int prep_new_page(struct page *pa |
35998 |
+ arch_alloc_page(page, order); |
35999 |
+ kernel_map_pages(page, 1 << order, 1); |
36000 |
+ |
36001 |
++#ifndef CONFIG_PAX_MEMORY_SANITIZE |
36002 |
+ if (gfp_flags & __GFP_ZERO) |
36003 |
+ prep_zero_page(page, order, gfp_flags); |
36004 |
++#endif |
36005 |
+ |
36006 |
+ if (order && (gfp_flags & __GFP_COMP)) |
36007 |
+ prep_compound_page(page, order); |
36008 |
+@@ -1007,6 +1020,11 @@ static void fastcall free_hot_cold_page( |
36009 |
+ list_add(&page->lru, &pcp->list); |
36010 |
+ set_page_private(page, get_pageblock_migratetype(page)); |
36011 |
+ pcp->count++; |
36012 |
++ |
36013 |
++#ifdef CONFIG_PAX_MEMORY_SANITIZE |
36014 |
++ sanitize_highpage(page); |
36015 |
++#endif |
36016 |
++ |
36017 |
+ if (pcp->count >= pcp->high) { |
36018 |
+ free_pages_bulk(zone, pcp->batch, &pcp->list, 0); |
36019 |
+ pcp->count -= pcp->batch; |
36020 |
+diff -urNp linux-2.6.24.4/mm/rmap.c linux-2.6.24.4/mm/rmap.c |
36021 |
+--- linux-2.6.24.4/mm/rmap.c 2008-03-24 14:49:18.000000000 -0400 |
36022 |
++++ linux-2.6.24.4/mm/rmap.c 2008-03-26 17:56:56.000000000 -0400 |
36023 |
+@@ -64,6 +64,10 @@ int anon_vma_prepare(struct vm_area_stru |
36024 |
+ struct mm_struct *mm = vma->vm_mm; |
36025 |
+ struct anon_vma *allocated, *locked; |
36026 |
+ |
36027 |
++#ifdef CONFIG_PAX_SEGMEXEC |
36028 |
++ struct vm_area_struct *vma_m; |
36029 |
++#endif |
36030 |
++ |
36031 |
+ anon_vma = find_mergeable_anon_vma(vma); |
36032 |
+ if (anon_vma) { |
36033 |
+ allocated = NULL; |
36034 |
+@@ -80,6 +84,15 @@ int anon_vma_prepare(struct vm_area_stru |
36035 |
+ /* page_table_lock to protect against threads */ |
36036 |
+ spin_lock(&mm->page_table_lock); |
36037 |
+ if (likely(!vma->anon_vma)) { |
36038 |
++ |
36039 |
++#ifdef CONFIG_PAX_SEGMEXEC |
36040 |
++ vma_m = pax_find_mirror_vma(vma); |
36041 |
++ if (vma_m) { |
36042 |
++ vma_m->anon_vma = anon_vma; |
36043 |
++ __anon_vma_link(vma_m); |
36044 |
++ } |
36045 |
++#endif |
36046 |
++ |
36047 |
+ vma->anon_vma = anon_vma; |
36048 |
+ list_add_tail(&vma->anon_vma_node, &anon_vma->head); |
36049 |
+ allocated = NULL; |
36050 |
+diff -urNp linux-2.6.24.4/mm/shmem.c linux-2.6.24.4/mm/shmem.c |
36051 |
+--- linux-2.6.24.4/mm/shmem.c 2008-03-24 14:49:18.000000000 -0400 |
36052 |
++++ linux-2.6.24.4/mm/shmem.c 2008-03-26 17:56:56.000000000 -0400 |
36053 |
+@@ -2462,7 +2462,7 @@ static struct file_system_type tmpfs_fs_ |
36054 |
+ .get_sb = shmem_get_sb, |
36055 |
+ .kill_sb = kill_litter_super, |
36056 |
+ }; |
36057 |
+-static struct vfsmount *shm_mnt; |
36058 |
++struct vfsmount *shm_mnt; |
36059 |
+ |
36060 |
+ static int __init init_tmpfs(void) |
36061 |
+ { |
36062 |
+diff -urNp linux-2.6.24.4/mm/slab.c linux-2.6.24.4/mm/slab.c |
36063 |
+--- linux-2.6.24.4/mm/slab.c 2008-03-24 14:49:18.000000000 -0400 |
36064 |
++++ linux-2.6.24.4/mm/slab.c 2008-03-26 17:56:56.000000000 -0400 |
36065 |
+@@ -305,7 +305,7 @@ struct kmem_list3 { |
36066 |
+ * Need this for bootstrapping a per node allocator. |
36067 |
+ */ |
36068 |
+ #define NUM_INIT_LISTS (3 * MAX_NUMNODES) |
36069 |
+-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS]; |
36070 |
++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS]; |
36071 |
+ #define CACHE_CACHE 0 |
36072 |
+ #define SIZE_AC MAX_NUMNODES |
36073 |
+ #define SIZE_L3 (2 * MAX_NUMNODES) |
36074 |
+@@ -654,14 +654,14 @@ struct cache_names { |
36075 |
+ static struct cache_names __initdata cache_names[] = { |
36076 |
+ #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" }, |
36077 |
+ #include <linux/kmalloc_sizes.h> |
36078 |
+- {NULL,} |
36079 |
++ {NULL, NULL} |
36080 |
+ #undef CACHE |
36081 |
+ }; |
36082 |
+ |
36083 |
+ static struct arraycache_init initarray_cache __initdata = |
36084 |
+- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} }; |
36085 |
++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} }; |
36086 |
+ static struct arraycache_init initarray_generic = |
36087 |
+- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} }; |
36088 |
++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} }; |
36089 |
+ |
36090 |
+ /* internal cache of cache description objs */ |
36091 |
+ static struct kmem_cache cache_cache = { |
36092 |
+@@ -3004,7 +3004,7 @@ retry: |
36093 |
+ * there must be at least one object available for |
36094 |
+ * allocation. |
36095 |
+ */ |
36096 |
+- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num); |
36097 |
++ BUG_ON(slabp->inuse >= cachep->num); |
36098 |
+ |
36099 |
+ while (slabp->inuse < cachep->num && batchcount--) { |
36100 |
+ STATS_INC_ALLOCED(cachep); |
36101 |
+diff -urNp linux-2.6.24.4/mm/slub.c linux-2.6.24.4/mm/slub.c |
36102 |
+--- linux-2.6.24.4/mm/slub.c 2008-03-24 14:49:18.000000000 -0400 |
36103 |
++++ linux-2.6.24.4/mm/slub.c 2008-03-26 17:56:56.000000000 -0400 |
36104 |
+@@ -1539,7 +1539,7 @@ debug: |
36105 |
+ * |
36106 |
+ * Otherwise we can simply pick the next object from the lockless free list. |
36107 |
+ */ |
36108 |
+-static void __always_inline *slab_alloc(struct kmem_cache *s, |
36109 |
++static __always_inline void *slab_alloc(struct kmem_cache *s, |
36110 |
+ gfp_t gfpflags, int node, void *addr) |
36111 |
+ { |
36112 |
+ void **object; |
36113 |
+@@ -1647,7 +1647,7 @@ debug: |
36114 |
+ * If fastpath is not possible then fall back to __slab_free where we deal |
36115 |
+ * with all sorts of special processing. |
36116 |
+ */ |
36117 |
+-static void __always_inline slab_free(struct kmem_cache *s, |
36118 |
++static __always_inline void slab_free(struct kmem_cache *s, |
36119 |
+ struct page *page, void *x, void *addr) |
36120 |
+ { |
36121 |
+ void **object = (void *)x; |
36122 |
+diff -urNp linux-2.6.24.4/mm/swap.c linux-2.6.24.4/mm/swap.c |
36123 |
+--- linux-2.6.24.4/mm/swap.c 2008-03-24 14:49:18.000000000 -0400 |
36124 |
++++ linux-2.6.24.4/mm/swap.c 2008-03-26 17:56:56.000000000 -0400 |
36125 |
+@@ -33,9 +33,9 @@ |
36126 |
+ /* How many pages do we try to swap or page in/out together? */ |
36127 |
+ int page_cluster; |
36128 |
+ |
36129 |
+-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, }; |
36130 |
+-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, }; |
36131 |
+-static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, }; |
36132 |
++static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, 0, {NULL} }; |
36133 |
++static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, 0, {NULL} }; |
36134 |
++static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, 0, {NULL} }; |
36135 |
+ |
36136 |
+ /* |
36137 |
+ * This path almost never happens for VM activity - pages are normally |
36138 |
+diff -urNp linux-2.6.24.4/mm/tiny-shmem.c linux-2.6.24.4/mm/tiny-shmem.c |
36139 |
+--- linux-2.6.24.4/mm/tiny-shmem.c 2008-03-24 14:49:18.000000000 -0400 |
36140 |
++++ linux-2.6.24.4/mm/tiny-shmem.c 2008-03-26 17:56:56.000000000 -0400 |
36141 |
+@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_ |
36142 |
+ .kill_sb = kill_litter_super, |
36143 |
+ }; |
36144 |
+ |
36145 |
+-static struct vfsmount *shm_mnt; |
36146 |
++struct vfsmount *shm_mnt; |
36147 |
+ |
36148 |
+ static int __init init_tmpfs(void) |
36149 |
+ { |
36150 |
+diff -urNp linux-2.6.24.4/mm/vmalloc.c linux-2.6.24.4/mm/vmalloc.c |
36151 |
+--- linux-2.6.24.4/mm/vmalloc.c 2008-03-24 14:49:18.000000000 -0400 |
36152 |
++++ linux-2.6.24.4/mm/vmalloc.c 2008-03-26 17:56:56.000000000 -0400 |
36153 |
+@@ -202,6 +202,8 @@ static struct vm_struct *__get_vm_area_n |
36154 |
+ |
36155 |
+ write_lock(&vmlist_lock); |
36156 |
+ for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) { |
36157 |
++ if (addr > end - size) |
36158 |
++ goto out; |
36159 |
+ if ((unsigned long)tmp->addr < addr) { |
36160 |
+ if((unsigned long)tmp->addr + tmp->size >= addr) |
36161 |
+ addr = ALIGN(tmp->size + |
36162 |
+@@ -213,8 +215,6 @@ static struct vm_struct *__get_vm_area_n |
36163 |
+ if (size + addr <= (unsigned long)tmp->addr) |
36164 |
+ goto found; |
36165 |
+ addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align); |
36166 |
+- if (addr > end - size) |
36167 |
+- goto out; |
36168 |
+ } |
36169 |
+ |
36170 |
+ found: |
36171 |
+diff -urNp linux-2.6.24.4/net/bridge/br_stp_if.c linux-2.6.24.4/net/bridge/br_stp_if.c |
36172 |
+--- linux-2.6.24.4/net/bridge/br_stp_if.c 2008-03-24 14:49:18.000000000 -0400 |
36173 |
++++ linux-2.6.24.4/net/bridge/br_stp_if.c 2008-03-26 17:56:56.000000000 -0400 |
36174 |
+@@ -148,7 +148,7 @@ static void br_stp_stop(struct net_bridg |
36175 |
+ char *envp[] = { NULL }; |
36176 |
+ |
36177 |
+ if (br->stp_enabled == BR_USER_STP) { |
36178 |
+- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1); |
36179 |
++ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); |
36180 |
+ printk(KERN_INFO "%s: userspace STP stopped, return code %d\n", |
36181 |
+ br->dev->name, r); |
36182 |
+ |
36183 |
+diff -urNp linux-2.6.24.4/net/core/flow.c linux-2.6.24.4/net/core/flow.c |
36184 |
+--- linux-2.6.24.4/net/core/flow.c 2008-03-24 14:49:18.000000000 -0400 |
36185 |
++++ linux-2.6.24.4/net/core/flow.c 2008-03-26 17:56:56.000000000 -0400 |
36186 |
+@@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT( |
36187 |
+ |
36188 |
+ static u32 flow_hash_shift; |
36189 |
+ #define flow_hash_size (1 << flow_hash_shift) |
36190 |
+-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL }; |
36191 |
++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables); |
36192 |
+ |
36193 |
+ #define flow_table(cpu) (per_cpu(flow_tables, cpu)) |
36194 |
+ |
36195 |
+@@ -53,7 +53,7 @@ struct flow_percpu_info { |
36196 |
+ u32 hash_rnd; |
36197 |
+ int count; |
36198 |
+ } ____cacheline_aligned; |
36199 |
+-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 }; |
36200 |
++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info); |
36201 |
+ |
36202 |
+ #define flow_hash_rnd_recalc(cpu) \ |
36203 |
+ (per_cpu(flow_hash_info, cpu).hash_rnd_recalc) |
36204 |
+@@ -70,7 +70,7 @@ struct flow_flush_info { |
36205 |
+ atomic_t cpuleft; |
36206 |
+ struct completion completion; |
36207 |
+ }; |
36208 |
+-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL }; |
36209 |
++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets); |
36210 |
+ |
36211 |
+ #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu)) |
36212 |
+ |
36213 |
+diff -urNp linux-2.6.24.4/net/dccp/ccids/ccid3.c linux-2.6.24.4/net/dccp/ccids/ccid3.c |
36214 |
+--- linux-2.6.24.4/net/dccp/ccids/ccid3.c 2008-03-24 14:49:18.000000000 -0400 |
36215 |
++++ linux-2.6.24.4/net/dccp/ccids/ccid3.c 2008-03-26 17:56:56.000000000 -0400 |
36216 |
+@@ -46,7 +46,7 @@ |
36217 |
+ static int ccid3_debug; |
36218 |
+ #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a) |
36219 |
+ #else |
36220 |
+-#define ccid3_pr_debug(format, a...) |
36221 |
++#define ccid3_pr_debug(format, a...) do {} while (0) |
36222 |
+ #endif |
36223 |
+ |
36224 |
+ static struct dccp_tx_hist *ccid3_tx_hist; |
36225 |
+diff -urNp linux-2.6.24.4/net/dccp/dccp.h linux-2.6.24.4/net/dccp/dccp.h |
36226 |
+--- linux-2.6.24.4/net/dccp/dccp.h 2008-03-24 14:49:18.000000000 -0400 |
36227 |
++++ linux-2.6.24.4/net/dccp/dccp.h 2008-03-26 17:56:56.000000000 -0400 |
36228 |
+@@ -43,8 +43,8 @@ extern int dccp_debug; |
36229 |
+ #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a) |
36230 |
+ #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a) |
36231 |
+ #else |
36232 |
+-#define dccp_pr_debug(format, a...) |
36233 |
+-#define dccp_pr_debug_cat(format, a...) |
36234 |
++#define dccp_pr_debug(format, a...) do {} while (0) |
36235 |
++#define dccp_pr_debug_cat(format, a...) do {} while (0) |
36236 |
+ #endif |
36237 |
+ |
36238 |
+ extern struct inet_hashinfo dccp_hashinfo; |
36239 |
+diff -urNp linux-2.6.24.4/net/ipv4/inet_connection_sock.c linux-2.6.24.4/net/ipv4/inet_connection_sock.c |
36240 |
+--- linux-2.6.24.4/net/ipv4/inet_connection_sock.c 2008-03-24 14:49:18.000000000 -0400 |
36241 |
++++ linux-2.6.24.4/net/ipv4/inet_connection_sock.c 2008-03-26 17:56:56.000000000 -0400 |
36242 |
+@@ -15,6 +15,7 @@ |
36243 |
+ |
36244 |
+ #include <linux/module.h> |
36245 |
+ #include <linux/jhash.h> |
36246 |
++#include <linux/grsecurity.h> |
36247 |
+ |
36248 |
+ #include <net/inet_connection_sock.h> |
36249 |
+ #include <net/inet_hashtables.h> |
36250 |
+diff -urNp linux-2.6.24.4/net/ipv4/inet_hashtables.c linux-2.6.24.4/net/ipv4/inet_hashtables.c |
36251 |
+--- linux-2.6.24.4/net/ipv4/inet_hashtables.c 2008-03-24 14:49:18.000000000 -0400 |
36252 |
++++ linux-2.6.24.4/net/ipv4/inet_hashtables.c 2008-03-26 17:56:56.000000000 -0400 |
36253 |
+@@ -18,11 +18,14 @@ |
36254 |
+ #include <linux/sched.h> |
36255 |
+ #include <linux/slab.h> |
36256 |
+ #include <linux/wait.h> |
36257 |
++#include <linux/grsecurity.h> |
36258 |
+ |
36259 |
+ #include <net/inet_connection_sock.h> |
36260 |
+ #include <net/inet_hashtables.h> |
36261 |
+ #include <net/ip.h> |
36262 |
+ |
36263 |
++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet); |
36264 |
++ |
36265 |
+ /* |
36266 |
+ * Allocate and initialize a new local port bind bucket. |
36267 |
+ * The bindhash mutex for snum's hash chain must be held here. |
36268 |
+@@ -338,6 +341,8 @@ ok: |
36269 |
+ } |
36270 |
+ spin_unlock(&head->lock); |
36271 |
+ |
36272 |
++ gr_update_task_in_ip_table(current, inet_sk(sk)); |
36273 |
++ |
36274 |
+ if (tw) { |
36275 |
+ inet_twsk_deschedule(tw, death_row); |
36276 |
+ inet_twsk_put(tw); |
36277 |
+diff -urNp linux-2.6.24.4/net/ipv4/netfilter/ipt_stealth.c linux-2.6.24.4/net/ipv4/netfilter/ipt_stealth.c |
36278 |
+--- linux-2.6.24.4/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500 |
36279 |
++++ linux-2.6.24.4/net/ipv4/netfilter/ipt_stealth.c 2008-03-26 17:56:56.000000000 -0400 |
36280 |
+@@ -0,0 +1,114 @@ |
36281 |
++/* Kernel module to add stealth support. |
36282 |
++ * |
36283 |
++ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net> |
36284 |
++ * |
36285 |
++ */ |
36286 |
++ |
36287 |
++#include <linux/kernel.h> |
36288 |
++#include <linux/module.h> |
36289 |
++#include <linux/skbuff.h> |
36290 |
++#include <linux/net.h> |
36291 |
++#include <linux/sched.h> |
36292 |
++#include <linux/inet.h> |
36293 |
++#include <linux/stddef.h> |
36294 |
++ |
36295 |
++#include <net/ip.h> |
36296 |
++#include <net/sock.h> |
36297 |
++#include <net/tcp.h> |
36298 |
++#include <net/udp.h> |
36299 |
++#include <net/route.h> |
36300 |
++#include <net/inet_common.h> |
36301 |
++ |
36302 |
++#include <linux/netfilter_ipv4/ip_tables.h> |
36303 |
++ |
36304 |
++MODULE_LICENSE("GPL"); |
36305 |
++ |
36306 |
++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif); |
36307 |
++ |
36308 |
++static int |
36309 |
++match(const struct sk_buff *skb, |
36310 |
++ const struct net_device *in, |
36311 |
++ const struct net_device *out, |
36312 |
++ const struct xt_match *match, |
36313 |
++ const void *matchinfo, |
36314 |
++ int offset, |
36315 |
++ unsigned int protoff, |
36316 |
++ int *hotdrop) |
36317 |
++{ |
36318 |
++ struct iphdr *ip = ip_hdr(skb); |
36319 |
++ struct tcphdr th; |
36320 |
++ struct udphdr uh; |
36321 |
++ struct sock *sk = NULL; |
36322 |
++ |
36323 |
++ if (!ip || offset) return 0; |
36324 |
++ |
36325 |
++ switch(ip->protocol) { |
36326 |
++ case IPPROTO_TCP: |
36327 |
++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) { |
36328 |
++ *hotdrop = 1; |
36329 |
++ return 0; |
36330 |
++ } |
36331 |
++ if (!(th.syn && !th.ack)) return 0; |
36332 |
++ sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb)); |
36333 |
++ break; |
36334 |
++ case IPPROTO_UDP: |
36335 |
++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) { |
36336 |
++ *hotdrop = 1; |
36337 |
++ return 0; |
36338 |
++ } |
36339 |
++ sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex); |
36340 |
++ break; |
36341 |
++ default: |
36342 |
++ return 0; |
36343 |
++ } |
36344 |
++ |
36345 |
++ if(!sk) // port is being listened on, match this |
36346 |
++ return 1; |
36347 |
++ else { |
36348 |
++ sock_put(sk); |
36349 |
++ return 0; |
36350 |
++ } |
36351 |
++} |
36352 |
++ |
36353 |
++/* Called when user tries to insert an entry of this type. */ |
36354 |
++static int |
36355 |
++checkentry(const char *tablename, |
36356 |
++ const void *nip, |
36357 |
++ const struct xt_match *match, |
36358 |
++ void *matchinfo, |
36359 |
++ unsigned int hook_mask) |
36360 |
++{ |
36361 |
++ const struct ipt_ip *ip = (const struct ipt_ip *)nip; |
36362 |
++ |
36363 |
++ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) || |
36364 |
++ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO))) |
36365 |
++ && (hook_mask & (1 << NF_IP_LOCAL_IN))) |
36366 |
++ return 1; |
36367 |
++ |
36368 |
++ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n"); |
36369 |
++ |
36370 |
++ return 0; |
36371 |
++} |
36372 |
++ |
36373 |
++ |
36374 |
++static struct xt_match stealth_match = { |
36375 |
++ .name = "stealth", |
36376 |
++ .family = AF_INET, |
36377 |
++ .match = match, |
36378 |
++ .checkentry = checkentry, |
36379 |
++ .destroy = NULL, |
36380 |
++ .me = THIS_MODULE |
36381 |
++}; |
36382 |
++ |
36383 |
++static int __init init(void) |
36384 |
++{ |
36385 |
++ return xt_register_match(&stealth_match); |
36386 |
++} |
36387 |
++ |
36388 |
++static void __exit fini(void) |
36389 |
++{ |
36390 |
++ xt_unregister_match(&stealth_match); |
36391 |
++} |
36392 |
++ |
36393 |
++module_init(init); |
36394 |
++module_exit(fini); |
36395 |
+diff -urNp linux-2.6.24.4/net/ipv4/netfilter/Kconfig linux-2.6.24.4/net/ipv4/netfilter/Kconfig |
36396 |
+--- linux-2.6.24.4/net/ipv4/netfilter/Kconfig 2008-03-24 14:49:18.000000000 -0400 |
36397 |
++++ linux-2.6.24.4/net/ipv4/netfilter/Kconfig 2008-03-26 17:56:56.000000000 -0400 |
36398 |
+@@ -130,6 +130,21 @@ config IP_NF_MATCH_ADDRTYPE |
36399 |
+ If you want to compile it as a module, say M here and read |
36400 |
+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. |
36401 |
+ |
36402 |
++config IP_NF_MATCH_STEALTH |
36403 |
++ tristate "stealth match support" |
36404 |
++ depends on IP_NF_IPTABLES |
36405 |
++ help |
36406 |
++ Enabling this option will drop all syn packets coming to unserved tcp |
36407 |
++ ports as well as all packets coming to unserved udp ports. If you |
36408 |
++ are using your system to route any type of packets (ie. via NAT) |
36409 |
++ you should put this module at the end of your ruleset, since it will |
36410 |
++ drop packets that aren't going to ports that are listening on your |
36411 |
++ machine itself, it doesn't take into account that the packet might be |
36412 |
++ destined for someone on your internal network if you're using NAT for |
36413 |
++ instance. |
36414 |
++ |
36415 |
++ To compile it as a module, choose M here. If unsure, say N. |
36416 |
++ |
36417 |
+ # `filter', generic and specific targets |
36418 |
+ config IP_NF_FILTER |
36419 |
+ tristate "Packet filtering" |
36420 |
+@@ -403,4 +418,3 @@ config IP_NF_ARP_MANGLE |
36421 |
+ hardware and network addresses. |
36422 |
+ |
36423 |
+ endmenu |
36424 |
+- |
36425 |
+diff -urNp linux-2.6.24.4/net/ipv4/netfilter/Makefile linux-2.6.24.4/net/ipv4/netfilter/Makefile |
36426 |
+--- linux-2.6.24.4/net/ipv4/netfilter/Makefile 2008-03-24 14:49:18.000000000 -0400 |
36427 |
++++ linux-2.6.24.4/net/ipv4/netfilter/Makefile 2008-03-26 17:56:56.000000000 -0400 |
36428 |
+@@ -47,6 +47,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn |
36429 |
+ obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o |
36430 |
+ obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o |
36431 |
+ obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o |
36432 |
++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o |
36433 |
+ obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o |
36434 |
+ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o |
36435 |
+ |
36436 |
+diff -urNp linux-2.6.24.4/net/ipv4/tcp.c linux-2.6.24.4/net/ipv4/tcp.c |
36437 |
+--- linux-2.6.24.4/net/ipv4/tcp.c 2008-03-24 14:49:18.000000000 -0400 |
36438 |
++++ linux-2.6.24.4/net/ipv4/tcp.c 2008-03-26 17:56:56.000000000 -0400 |
36439 |
+@@ -1054,7 +1054,8 @@ int tcp_read_sock(struct sock *sk, read_ |
36440 |
+ return -ENOTCONN; |
36441 |
+ while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { |
36442 |
+ if (offset < skb->len) { |
36443 |
+- size_t used, len; |
36444 |
++ int used; |
36445 |
++ size_t len; |
36446 |
+ |
36447 |
+ len = skb->len - offset; |
36448 |
+ /* Stop reading if we hit a patch of urgent data */ |
36449 |
+diff -urNp linux-2.6.24.4/net/ipv4/tcp_ipv4.c linux-2.6.24.4/net/ipv4/tcp_ipv4.c |
36450 |
+--- linux-2.6.24.4/net/ipv4/tcp_ipv4.c 2008-03-24 14:49:18.000000000 -0400 |
36451 |
++++ linux-2.6.24.4/net/ipv4/tcp_ipv4.c 2008-03-26 17:56:56.000000000 -0400 |
36452 |
+@@ -61,6 +61,7 @@ |
36453 |
+ #include <linux/jhash.h> |
36454 |
+ #include <linux/init.h> |
36455 |
+ #include <linux/times.h> |
36456 |
++#include <linux/grsecurity.h> |
36457 |
+ |
36458 |
+ #include <net/net_namespace.h> |
36459 |
+ #include <net/icmp.h> |
36460 |
+diff -urNp linux-2.6.24.4/net/ipv4/udp.c linux-2.6.24.4/net/ipv4/udp.c |
36461 |
+--- linux-2.6.24.4/net/ipv4/udp.c 2008-03-24 14:49:18.000000000 -0400 |
36462 |
++++ linux-2.6.24.4/net/ipv4/udp.c 2008-03-26 17:56:56.000000000 -0400 |
36463 |
+@@ -98,6 +98,7 @@ |
36464 |
+ #include <linux/skbuff.h> |
36465 |
+ #include <linux/proc_fs.h> |
36466 |
+ #include <linux/seq_file.h> |
36467 |
++#include <linux/grsecurity.h> |
36468 |
+ #include <net/net_namespace.h> |
36469 |
+ #include <net/icmp.h> |
36470 |
+ #include <net/route.h> |
36471 |
+@@ -105,6 +106,11 @@ |
36472 |
+ #include <net/xfrm.h> |
36473 |
+ #include "udp_impl.h" |
36474 |
+ |
36475 |
++extern int gr_search_udp_recvmsg(const struct sock *sk, |
36476 |
++ const struct sk_buff *skb); |
36477 |
++extern int gr_search_udp_sendmsg(const struct sock *sk, |
36478 |
++ const struct sockaddr_in *addr); |
36479 |
++ |
36480 |
+ /* |
36481 |
+ * Snmp MIB for the UDP layer |
36482 |
+ */ |
36483 |
+@@ -295,6 +301,13 @@ static struct sock *__udp4_lib_lookup(__ |
36484 |
+ return result; |
36485 |
+ } |
36486 |
+ |
36487 |
++struct sock *udp_v4_lookup(__be32 saddr, __be16 sport, |
36488 |
++ __be32 daddr, __be16 dport, int dif) |
36489 |
++{ |
36490 |
++ return __udp4_lib_lookup(saddr, sport, daddr, dport, dif, udp_hash); |
36491 |
++} |
36492 |
++ |
36493 |
++ |
36494 |
+ static inline struct sock *udp_v4_mcast_next(struct sock *sk, |
36495 |
+ __be16 loc_port, __be32 loc_addr, |
36496 |
+ __be16 rmt_port, __be32 rmt_addr, |
36497 |
+@@ -580,9 +593,16 @@ int udp_sendmsg(struct kiocb *iocb, stru |
36498 |
+ dport = usin->sin_port; |
36499 |
+ if (dport == 0) |
36500 |
+ return -EINVAL; |
36501 |
++ |
36502 |
++ if (!gr_search_udp_sendmsg(sk, usin)) |
36503 |
++ return -EPERM; |
36504 |
+ } else { |
36505 |
+ if (sk->sk_state != TCP_ESTABLISHED) |
36506 |
+ return -EDESTADDRREQ; |
36507 |
++ |
36508 |
++ if (!gr_search_udp_sendmsg(sk, NULL)) |
36509 |
++ return -EPERM; |
36510 |
++ |
36511 |
+ daddr = inet->daddr; |
36512 |
+ dport = inet->dport; |
36513 |
+ /* Open fast path for connected socket. |
36514 |
+@@ -842,6 +862,11 @@ try_again: |
36515 |
+ if (!skb) |
36516 |
+ goto out; |
36517 |
+ |
36518 |
++ if (!gr_search_udp_recvmsg(sk, skb)) { |
36519 |
++ err = -EPERM; |
36520 |
++ goto out_free; |
36521 |
++ } |
36522 |
++ |
36523 |
+ ulen = skb->len - sizeof(struct udphdr); |
36524 |
+ copied = len; |
36525 |
+ if (copied > ulen) |
36526 |
+diff -urNp linux-2.6.24.4/net/ipv6/exthdrs.c linux-2.6.24.4/net/ipv6/exthdrs.c |
36527 |
+--- linux-2.6.24.4/net/ipv6/exthdrs.c 2008-03-24 14:49:18.000000000 -0400 |
36528 |
++++ linux-2.6.24.4/net/ipv6/exthdrs.c 2008-03-26 17:56:56.000000000 -0400 |
36529 |
+@@ -621,7 +621,7 @@ static struct tlvtype_proc tlvprochopopt |
36530 |
+ .type = IPV6_TLV_JUMBO, |
36531 |
+ .func = ipv6_hop_jumbo, |
36532 |
+ }, |
36533 |
+- { -1, } |
36534 |
++ { -1, NULL } |
36535 |
+ }; |
36536 |
+ |
36537 |
+ int ipv6_parse_hopopts(struct sk_buff *skb) |
36538 |
+diff -urNp linux-2.6.24.4/net/ipv6/raw.c linux-2.6.24.4/net/ipv6/raw.c |
36539 |
+--- linux-2.6.24.4/net/ipv6/raw.c 2008-03-24 14:49:18.000000000 -0400 |
36540 |
++++ linux-2.6.24.4/net/ipv6/raw.c 2008-03-26 17:56:56.000000000 -0400 |
36541 |
+@@ -578,7 +578,7 @@ out: |
36542 |
+ return err; |
36543 |
+ } |
36544 |
+ |
36545 |
+-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, |
36546 |
++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length, |
36547 |
+ struct flowi *fl, struct rt6_info *rt, |
36548 |
+ unsigned int flags) |
36549 |
+ { |
36550 |
+diff -urNp linux-2.6.24.4/net/irda/ircomm/ircomm_tty.c linux-2.6.24.4/net/irda/ircomm/ircomm_tty.c |
36551 |
+--- linux-2.6.24.4/net/irda/ircomm/ircomm_tty.c 2008-03-24 14:49:18.000000000 -0400 |
36552 |
++++ linux-2.6.24.4/net/irda/ircomm/ircomm_tty.c 2008-03-26 17:56:56.000000000 -0400 |
36553 |
+@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st |
36554 |
+ IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); |
36555 |
+ |
36556 |
+ line = tty->index; |
36557 |
+- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) { |
36558 |
++ if (line >= IRCOMM_TTY_PORTS) { |
36559 |
+ return -ENODEV; |
36560 |
+ } |
36561 |
+ |
36562 |
+diff -urNp linux-2.6.24.4/net/mac80211/regdomain.c linux-2.6.24.4/net/mac80211/regdomain.c |
36563 |
+--- linux-2.6.24.4/net/mac80211/regdomain.c 2008-03-24 14:49:18.000000000 -0400 |
36564 |
++++ linux-2.6.24.4/net/mac80211/regdomain.c 2008-03-26 17:56:56.000000000 -0400 |
36565 |
+@@ -61,14 +61,14 @@ static const struct ieee80211_channel_ra |
36566 |
+ { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */, |
36567 |
+ { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */, |
36568 |
+ { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */, |
36569 |
+- { 0 } |
36570 |
++ { 0, 0, 0, 0 } |
36571 |
+ }; |
36572 |
+ |
36573 |
+ static const struct ieee80211_channel_range ieee80211_mkk_channels[] = { |
36574 |
+ { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */, |
36575 |
+ { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */, |
36576 |
+ { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */, |
36577 |
+- { 0 } |
36578 |
++ { 0, 0, 0, 0 } |
36579 |
+ }; |
36580 |
+ |
36581 |
+ |
36582 |
+diff -urNp linux-2.6.24.4/net/sctp/socket.c linux-2.6.24.4/net/sctp/socket.c |
36583 |
+--- linux-2.6.24.4/net/sctp/socket.c 2008-03-24 14:49:18.000000000 -0400 |
36584 |
++++ linux-2.6.24.4/net/sctp/socket.c 2008-03-26 17:56:56.000000000 -0400 |
36585 |
+@@ -1390,7 +1390,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc |
36586 |
+ struct sctp_sndrcvinfo *sinfo; |
36587 |
+ struct sctp_initmsg *sinit; |
36588 |
+ sctp_assoc_t associd = 0; |
36589 |
+- sctp_cmsgs_t cmsgs = { NULL }; |
36590 |
++ sctp_cmsgs_t cmsgs = { NULL, NULL }; |
36591 |
+ int err; |
36592 |
+ sctp_scope_t scope; |
36593 |
+ long timeo; |
36594 |
+diff -urNp linux-2.6.24.4/net/socket.c linux-2.6.24.4/net/socket.c |
36595 |
+--- linux-2.6.24.4/net/socket.c 2008-03-24 14:49:18.000000000 -0400 |
36596 |
++++ linux-2.6.24.4/net/socket.c 2008-03-26 17:56:56.000000000 -0400 |
36597 |
+@@ -85,6 +85,7 @@ |
36598 |
+ #include <linux/audit.h> |
36599 |
+ #include <linux/wireless.h> |
36600 |
+ #include <linux/nsproxy.h> |
36601 |
++#include <linux/in.h> |
36602 |
+ |
36603 |
+ #include <asm/uaccess.h> |
36604 |
+ #include <asm/unistd.h> |
36605 |
+@@ -94,6 +95,21 @@ |
36606 |
+ #include <net/sock.h> |
36607 |
+ #include <linux/netfilter.h> |
36608 |
+ |
36609 |
++extern void gr_attach_curr_ip(const struct sock *sk); |
36610 |
++extern int gr_handle_sock_all(const int family, const int type, |
36611 |
++ const int protocol); |
36612 |
++extern int gr_handle_sock_server(const struct sockaddr *sck); |
36613 |
++extern int gr_handle_sock_server_other(const struct socket *sck); |
36614 |
++extern int gr_handle_sock_client(const struct sockaddr *sck); |
36615 |
++extern int gr_search_connect(const struct socket * sock, |
36616 |
++ const struct sockaddr_in * addr); |
36617 |
++extern int gr_search_bind(const struct socket * sock, |
36618 |
++ const struct sockaddr_in * addr); |
36619 |
++extern int gr_search_listen(const struct socket * sock); |
36620 |
++extern int gr_search_accept(const struct socket * sock); |
36621 |
++extern int gr_search_socket(const int domain, const int type, |
36622 |
++ const int protocol); |
36623 |
++ |
36624 |
+ static int sock_no_open(struct inode *irrelevant, struct file *dontcare); |
36625 |
+ static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
36626 |
+ unsigned long nr_segs, loff_t pos); |
36627 |
+@@ -293,7 +309,7 @@ static int sockfs_get_sb(struct file_sys |
36628 |
+ mnt); |
36629 |
+ } |
36630 |
+ |
36631 |
+-static struct vfsmount *sock_mnt __read_mostly; |
36632 |
++struct vfsmount *sock_mnt __read_mostly; |
36633 |
+ |
36634 |
+ static struct file_system_type sock_fs_type = { |
36635 |
+ .name = "sockfs", |
36636 |
+@@ -1204,6 +1220,16 @@ asmlinkage long sys_socket(int family, i |
36637 |
+ int retval; |
36638 |
+ struct socket *sock; |
36639 |
+ |
36640 |
++ if(!gr_search_socket(family, type, protocol)) { |
36641 |
++ retval = -EACCES; |
36642 |
++ goto out; |
36643 |
++ } |
36644 |
++ |
36645 |
++ if (gr_handle_sock_all(family, type, protocol)) { |
36646 |
++ retval = -EACCES; |
36647 |
++ goto out; |
36648 |
++ } |
36649 |
++ |
36650 |
+ retval = sock_create(family, type, protocol, &sock); |
36651 |
+ if (retval < 0) |
36652 |
+ goto out; |
36653 |
+@@ -1334,6 +1360,12 @@ asmlinkage long sys_bind(int fd, struct |
36654 |
+ if (sock) { |
36655 |
+ err = move_addr_to_kernel(umyaddr, addrlen, address); |
36656 |
+ if (err >= 0) { |
36657 |
++ if (!gr_search_bind(sock, (struct sockaddr_in *)address) || |
36658 |
++ gr_handle_sock_server((struct sockaddr *)address)) { |
36659 |
++ err = -EACCES; |
36660 |
++ goto error; |
36661 |
++ } |
36662 |
++ |
36663 |
+ err = security_socket_bind(sock, |
36664 |
+ (struct sockaddr *)address, |
36665 |
+ addrlen); |
36666 |
+@@ -1342,6 +1374,7 @@ asmlinkage long sys_bind(int fd, struct |
36667 |
+ (struct sockaddr *) |
36668 |
+ address, addrlen); |
36669 |
+ } |
36670 |
++error: |
36671 |
+ fput_light(sock->file, fput_needed); |
36672 |
+ } |
36673 |
+ return err; |
36674 |
+@@ -1365,10 +1398,17 @@ asmlinkage long sys_listen(int fd, int b |
36675 |
+ if ((unsigned)backlog > sysctl_somaxconn) |
36676 |
+ backlog = sysctl_somaxconn; |
36677 |
+ |
36678 |
++ if (gr_handle_sock_server_other(sock) || |
36679 |
++ !gr_search_listen(sock)) { |
36680 |
++ err = -EPERM; |
36681 |
++ goto error; |
36682 |
++ } |
36683 |
++ |
36684 |
+ err = security_socket_listen(sock, backlog); |
36685 |
+ if (!err) |
36686 |
+ err = sock->ops->listen(sock, backlog); |
36687 |
+ |
36688 |
++error: |
36689 |
+ fput_light(sock->file, fput_needed); |
36690 |
+ } |
36691 |
+ return err; |
36692 |
+@@ -1405,6 +1445,13 @@ asmlinkage long sys_accept(int fd, struc |
36693 |
+ newsock->type = sock->type; |
36694 |
+ newsock->ops = sock->ops; |
36695 |
+ |
36696 |
++ if (gr_handle_sock_server_other(sock) || |
36697 |
++ !gr_search_accept(sock)) { |
36698 |
++ err = -EPERM; |
36699 |
++ sock_release(newsock); |
36700 |
++ goto out_put; |
36701 |
++ } |
36702 |
++ |
36703 |
+ /* |
36704 |
+ * We don't need try_module_get here, as the listening socket (sock) |
36705 |
+ * has the protocol module (sock->ops->owner) held. |
36706 |
+@@ -1448,6 +1495,7 @@ asmlinkage long sys_accept(int fd, struc |
36707 |
+ err = newfd; |
36708 |
+ |
36709 |
+ security_socket_post_accept(sock, newsock); |
36710 |
++ gr_attach_curr_ip(newsock->sk); |
36711 |
+ |
36712 |
+ out_put: |
36713 |
+ fput_light(sock->file, fput_needed); |
36714 |
+@@ -1481,6 +1529,7 @@ asmlinkage long sys_connect(int fd, stru |
36715 |
+ { |
36716 |
+ struct socket *sock; |
36717 |
+ char address[MAX_SOCK_ADDR]; |
36718 |
++ struct sockaddr *sck; |
36719 |
+ int err, fput_needed; |
36720 |
+ |
36721 |
+ sock = sockfd_lookup_light(fd, &err, &fput_needed); |
36722 |
+@@ -1490,6 +1539,13 @@ asmlinkage long sys_connect(int fd, stru |
36723 |
+ if (err < 0) |
36724 |
+ goto out_put; |
36725 |
+ |
36726 |
++ sck = (struct sockaddr *)address; |
36727 |
++ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) || |
36728 |
++ gr_handle_sock_client(sck)) { |
36729 |
++ err = -EACCES; |
36730 |
++ goto out_put; |
36731 |
++ } |
36732 |
++ |
36733 |
+ err = |
36734 |
+ security_socket_connect(sock, (struct sockaddr *)address, addrlen); |
36735 |
+ if (err) |
36736 |
+@@ -1767,6 +1823,7 @@ asmlinkage long sys_shutdown(int fd, int |
36737 |
+ err = sock->ops->shutdown(sock, how); |
36738 |
+ fput_light(sock->file, fput_needed); |
36739 |
+ } |
36740 |
++ |
36741 |
+ return err; |
36742 |
+ } |
36743 |
+ |
36744 |
+diff -urNp linux-2.6.24.4/net/unix/af_unix.c linux-2.6.24.4/net/unix/af_unix.c |
36745 |
+--- linux-2.6.24.4/net/unix/af_unix.c 2008-03-24 14:49:18.000000000 -0400 |
36746 |
++++ linux-2.6.24.4/net/unix/af_unix.c 2008-03-26 17:56:56.000000000 -0400 |
36747 |
+@@ -116,6 +116,7 @@ |
36748 |
+ #include <linux/mount.h> |
36749 |
+ #include <net/checksum.h> |
36750 |
+ #include <linux/security.h> |
36751 |
++#include <linux/grsecurity.h> |
36752 |
+ |
36753 |
+ int sysctl_unix_max_dgram_qlen __read_mostly = 10; |
36754 |
+ |
36755 |
+@@ -738,6 +739,11 @@ static struct sock *unix_find_other(stru |
36756 |
+ if (err) |
36757 |
+ goto put_fail; |
36758 |
+ |
36759 |
++ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) { |
36760 |
++ err = -EACCES; |
36761 |
++ goto put_fail; |
36762 |
++ } |
36763 |
++ |
36764 |
+ err = -ECONNREFUSED; |
36765 |
+ if (!S_ISSOCK(nd.dentry->d_inode->i_mode)) |
36766 |
+ goto put_fail; |
36767 |
+@@ -761,6 +767,13 @@ static struct sock *unix_find_other(stru |
36768 |
+ if (u) { |
36769 |
+ struct dentry *dentry; |
36770 |
+ dentry = unix_sk(u)->dentry; |
36771 |
++ |
36772 |
++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) { |
36773 |
++ err = -EPERM; |
36774 |
++ sock_put(u); |
36775 |
++ goto fail; |
36776 |
++ } |
36777 |
++ |
36778 |
+ if (dentry) |
36779 |
+ touch_atime(unix_sk(u)->mnt, dentry); |
36780 |
+ } else |
36781 |
+@@ -839,9 +852,18 @@ static int unix_bind(struct socket *sock |
36782 |
+ */ |
36783 |
+ mode = S_IFSOCK | |
36784 |
+ (SOCK_INODE(sock)->i_mode & ~current->fs->umask); |
36785 |
++ |
36786 |
++ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) { |
36787 |
++ err = -EACCES; |
36788 |
++ goto out_mknod_dput; |
36789 |
++ } |
36790 |
++ |
36791 |
+ err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); |
36792 |
+ if (err) |
36793 |
+ goto out_mknod_dput; |
36794 |
++ |
36795 |
++ gr_handle_create(dentry, nd.mnt); |
36796 |
++ |
36797 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
36798 |
+ dput(nd.dentry); |
36799 |
+ nd.dentry = dentry; |
36800 |
+@@ -859,6 +881,10 @@ static int unix_bind(struct socket *sock |
36801 |
+ goto out_unlock; |
36802 |
+ } |
36803 |
+ |
36804 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX |
36805 |
++ sk->sk_peercred.pid = current->pid; |
36806 |
++#endif |
36807 |
++ |
36808 |
+ list = &unix_socket_table[addr->hash]; |
36809 |
+ } else { |
36810 |
+ list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; |
36811 |
+diff -urNp linux-2.6.24.4/scripts/pnmtologo.c linux-2.6.24.4/scripts/pnmtologo.c |
36812 |
+--- linux-2.6.24.4/scripts/pnmtologo.c 2008-03-24 14:49:18.000000000 -0400 |
36813 |
++++ linux-2.6.24.4/scripts/pnmtologo.c 2008-03-26 17:56:56.000000000 -0400 |
36814 |
+@@ -237,14 +237,14 @@ static void write_header(void) |
36815 |
+ fprintf(out, " * Linux logo %s\n", logoname); |
36816 |
+ fputs(" */\n\n", out); |
36817 |
+ fputs("#include <linux/linux_logo.h>\n\n", out); |
36818 |
+- fprintf(out, "static unsigned char %s_data[] __initdata = {\n", |
36819 |
++ fprintf(out, "static unsigned char %s_data[] = {\n", |
36820 |
+ logoname); |
36821 |
+ } |
36822 |
+ |
36823 |
+ static void write_footer(void) |
36824 |
+ { |
36825 |
+ fputs("\n};\n\n", out); |
36826 |
+- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname); |
36827 |
++ fprintf(out, "struct linux_logo %s = {\n", logoname); |
36828 |
+ fprintf(out, " .type\t= %s,\n", logo_types[logo_type]); |
36829 |
+ fprintf(out, " .width\t= %d,\n", logo_width); |
36830 |
+ fprintf(out, " .height\t= %d,\n", logo_height); |
36831 |
+@@ -374,7 +374,7 @@ static void write_logo_clut224(void) |
36832 |
+ fputs("\n};\n\n", out); |
36833 |
+ |
36834 |
+ /* write logo clut */ |
36835 |
+- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n", |
36836 |
++ fprintf(out, "static unsigned char %s_clut[] = {\n", |
36837 |
+ logoname); |
36838 |
+ write_hex_cnt = 0; |
36839 |
+ for (i = 0; i < logo_clutsize; i++) { |
36840 |
+diff -urNp linux-2.6.24.4/security/commoncap.c linux-2.6.24.4/security/commoncap.c |
36841 |
+--- linux-2.6.24.4/security/commoncap.c 2008-03-24 14:49:18.000000000 -0400 |
36842 |
++++ linux-2.6.24.4/security/commoncap.c 2008-03-26 17:56:56.000000000 -0400 |
36843 |
+@@ -24,6 +24,7 @@ |
36844 |
+ #include <linux/hugetlb.h> |
36845 |
+ #include <linux/mount.h> |
36846 |
+ #include <linux/sched.h> |
36847 |
++#include <linux/grsecurity.h> |
36848 |
+ |
36849 |
+ #ifdef CONFIG_SECURITY_FILE_CAPABILITIES |
36850 |
+ /* |
36851 |
+@@ -44,9 +45,11 @@ EXPORT_SYMBOL(cap_bset); |
36852 |
+ unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ |
36853 |
+ EXPORT_SYMBOL(securebits); |
36854 |
+ |
36855 |
++extern __u32 gr_cap_rtnetlink(struct sock *sk); |
36856 |
++ |
36857 |
+ int cap_netlink_send(struct sock *sk, struct sk_buff *skb) |
36858 |
+ { |
36859 |
+- NETLINK_CB(skb).eff_cap = current->cap_effective; |
36860 |
++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk); |
36861 |
+ return 0; |
36862 |
+ } |
36863 |
+ |
36864 |
+@@ -68,7 +71,15 @@ EXPORT_SYMBOL(cap_netlink_recv); |
36865 |
+ int cap_capable (struct task_struct *tsk, int cap) |
36866 |
+ { |
36867 |
+ /* Derived from include/linux/sched.h:capable. */ |
36868 |
+- if (cap_raised(tsk->cap_effective, cap)) |
36869 |
++ if (cap_raised (tsk->cap_effective, cap)) |
36870 |
++ return 0; |
36871 |
++ return -EPERM; |
36872 |
++} |
36873 |
++ |
36874 |
++int cap_capable_nolog (struct task_struct *tsk, int cap) |
36875 |
++{ |
36876 |
++ /* tsk = current for all callers */ |
36877 |
++ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap)) |
36878 |
+ return 0; |
36879 |
+ return -EPERM; |
36880 |
+ } |
36881 |
+@@ -343,8 +354,11 @@ void cap_bprm_apply_creds (struct linux_ |
36882 |
+ } |
36883 |
+ } |
36884 |
+ |
36885 |
+- current->suid = current->euid = current->fsuid = bprm->e_uid; |
36886 |
+- current->sgid = current->egid = current->fsgid = bprm->e_gid; |
36887 |
++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid)) |
36888 |
++ current->suid = current->euid = current->fsuid = bprm->e_uid; |
36889 |
++ |
36890 |
++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid)) |
36891 |
++ current->sgid = current->egid = current->fsgid = bprm->e_gid; |
36892 |
+ |
36893 |
+ /* For init, we want to retain the capabilities set |
36894 |
+ * in the init_task struct. Thus we skip the usual |
36895 |
+@@ -355,6 +369,8 @@ void cap_bprm_apply_creds (struct linux_ |
36896 |
+ new_permitted : 0; |
36897 |
+ } |
36898 |
+ |
36899 |
++ gr_handle_chroot_caps(current); |
36900 |
++ |
36901 |
+ /* AUD: Audit candidate if current->cap_effective is set */ |
36902 |
+ |
36903 |
+ current->keep_capabilities = 0; |
36904 |
+@@ -602,7 +618,7 @@ int cap_vm_enough_memory(struct mm_struc |
36905 |
+ { |
36906 |
+ int cap_sys_admin = 0; |
36907 |
+ |
36908 |
+- if (cap_capable(current, CAP_SYS_ADMIN) == 0) |
36909 |
++ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0) |
36910 |
+ cap_sys_admin = 1; |
36911 |
+ return __vm_enough_memory(mm, pages, cap_sys_admin); |
36912 |
+ } |
36913 |
+diff -urNp linux-2.6.24.4/security/dummy.c linux-2.6.24.4/security/dummy.c |
36914 |
+--- linux-2.6.24.4/security/dummy.c 2008-03-24 14:49:18.000000000 -0400 |
36915 |
++++ linux-2.6.24.4/security/dummy.c 2008-03-26 17:56:56.000000000 -0400 |
36916 |
+@@ -27,6 +27,7 @@ |
36917 |
+ #include <linux/hugetlb.h> |
36918 |
+ #include <linux/ptrace.h> |
36919 |
+ #include <linux/file.h> |
36920 |
++#include <linux/grsecurity.h> |
36921 |
+ |
36922 |
+ static int dummy_ptrace (struct task_struct *parent, struct task_struct *child) |
36923 |
+ { |
36924 |
+@@ -135,8 +136,11 @@ static void dummy_bprm_apply_creds (stru |
36925 |
+ } |
36926 |
+ } |
36927 |
+ |
36928 |
+- current->suid = current->euid = current->fsuid = bprm->e_uid; |
36929 |
+- current->sgid = current->egid = current->fsgid = bprm->e_gid; |
36930 |
++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid)) |
36931 |
++ current->suid = current->euid = current->fsuid = bprm->e_uid; |
36932 |
++ |
36933 |
++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid)) |
36934 |
++ current->sgid = current->egid = current->fsgid = bprm->e_gid; |
36935 |
+ |
36936 |
+ dummy_capget(current, ¤t->cap_effective, ¤t->cap_inheritable, ¤t->cap_permitted); |
36937 |
+ } |
36938 |
+diff -urNp linux-2.6.24.4/security/Kconfig linux-2.6.24.4/security/Kconfig |
36939 |
+--- linux-2.6.24.4/security/Kconfig 2008-03-24 14:49:18.000000000 -0400 |
36940 |
++++ linux-2.6.24.4/security/Kconfig 2008-03-26 17:56:56.000000000 -0400 |
36941 |
+@@ -4,6 +4,429 @@ |
36942 |
+ |
36943 |
+ menu "Security options" |
36944 |
+ |
36945 |
++source grsecurity/Kconfig |
36946 |
++ |
36947 |
++menu "PaX" |
36948 |
++ |
36949 |
++config PAX |
36950 |
++ bool "Enable various PaX features" |
36951 |
++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64) |
36952 |
++ help |
36953 |
++ This allows you to enable various PaX features. PaX adds |
36954 |
++ intrusion prevention mechanisms to the kernel that reduce |
36955 |
++ the risks posed by exploitable memory corruption bugs. |
36956 |
++ |
36957 |
++menu "PaX Control" |
36958 |
++ depends on PAX |
36959 |
++ |
36960 |
++config PAX_SOFTMODE |
36961 |
++ bool 'Support soft mode' |
36962 |
++ help |
36963 |
++ Enabling this option will allow you to run PaX in soft mode, that |
36964 |
++ is, PaX features will not be enforced by default, only on executables |
36965 |
++ marked explicitly. You must also enable PT_PAX_FLAGS support as it |
36966 |
++ is the only way to mark executables for soft mode use. |
36967 |
++ |
36968 |
++ Soft mode can be activated by using the "pax_softmode=1" kernel command |
36969 |
++ line option on boot. Furthermore you can control various PaX features |
36970 |
++ at runtime via the entries in /proc/sys/kernel/pax. |
36971 |
++ |
36972 |
++config PAX_EI_PAX |
36973 |
++ bool 'Use legacy ELF header marking' |
36974 |
++ help |
36975 |
++ Enabling this option will allow you to control PaX features on |
36976 |
++ a per executable basis via the 'chpax' utility available at |
36977 |
++ http://pax.grsecurity.net/. The control flags will be read from |
36978 |
++ an otherwise reserved part of the ELF header. This marking has |
36979 |
++ numerous drawbacks (no support for soft-mode, toolchain does not |
36980 |
++ know about the non-standard use of the ELF header) therefore it |
36981 |
++ has been deprecated in favour of PT_PAX_FLAGS support. |
36982 |
++ |
36983 |
++ If you have applications not marked by the PT_PAX_FLAGS ELF |
36984 |
++ program header then you MUST enable this option otherwise they |
36985 |
++ will not get any protection. |
36986 |
++ |
36987 |
++ Note that if you enable PT_PAX_FLAGS marking support as well, |
36988 |
++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks. |
36989 |
++ |
36990 |
++config PAX_PT_PAX_FLAGS |
36991 |
++ bool 'Use ELF program header marking' |
36992 |
++ help |
36993 |
++ Enabling this option will allow you to control PaX features on |
36994 |
++ a per executable basis via the 'paxctl' utility available at |
36995 |
++ http://pax.grsecurity.net/. The control flags will be read from |
36996 |
++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking |
36997 |
++ has the benefits of supporting both soft mode and being fully |
36998 |
++ integrated into the toolchain (the binutils patch is available |
36999 |
++ from http://pax.grsecurity.net). |
37000 |
++ |
37001 |
++ If you have applications not marked by the PT_PAX_FLAGS ELF |
37002 |
++ program header then you MUST enable the EI_PAX marking support |
37003 |
++ otherwise they will not get any protection. |
37004 |
++ |
37005 |
++ Note that if you enable the legacy EI_PAX marking support as well, |
37006 |
++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks. |
37007 |
++ |
37008 |
++choice |
37009 |
++ prompt 'MAC system integration' |
37010 |
++ default PAX_HAVE_ACL_FLAGS |
37011 |
++ help |
37012 |
++ Mandatory Access Control systems have the option of controlling |
37013 |
++ PaX flags on a per executable basis, choose the method supported |
37014 |
++ by your particular system. |
37015 |
++ |
37016 |
++ - "none": if your MAC system does not interact with PaX, |
37017 |
++ - "direct": if your MAC system defines pax_set_initial_flags() itself, |
37018 |
++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback. |
37019 |
++ |
37020 |
++ NOTE: this option is for developers/integrators only. |
37021 |
++ |
37022 |
++ config PAX_NO_ACL_FLAGS |
37023 |
++ bool 'none' |
37024 |
++ |
37025 |
++ config PAX_HAVE_ACL_FLAGS |
37026 |
++ bool 'direct' |
37027 |
++ |
37028 |
++ config PAX_HOOK_ACL_FLAGS |
37029 |
++ bool 'hook' |
37030 |
++endchoice |
37031 |
++ |
37032 |
++endmenu |
37033 |
++ |
37034 |
++menu "Non-executable pages" |
37035 |
++ depends on PAX |
37036 |
++ |
37037 |
++config PAX_NOEXEC |
37038 |
++ bool "Enforce non-executable pages" |
37039 |
++ 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) |
37040 |
++ help |
37041 |
++ By design some architectures do not allow for protecting memory |
37042 |
++ pages against execution or even if they do, Linux does not make |
37043 |
++ use of this feature. In practice this means that if a page is |
37044 |
++ readable (such as the stack or heap) it is also executable. |
37045 |
++ |
37046 |
++ There is a well known exploit technique that makes use of this |
37047 |
++ fact and a common programming mistake where an attacker can |
37048 |
++ introduce code of his choice somewhere in the attacked program's |
37049 |
++ memory (typically the stack or the heap) and then execute it. |
37050 |
++ |
37051 |
++ If the attacked program was running with different (typically |
37052 |
++ higher) privileges than that of the attacker, then he can elevate |
37053 |
++ his own privilege level (e.g. get a root shell, write to files for |
37054 |
++ which he does not have write access to, etc). |
37055 |
++ |
37056 |
++ Enabling this option will let you choose from various features |
37057 |
++ that prevent the injection and execution of 'foreign' code in |
37058 |
++ a program. |
37059 |
++ |
37060 |
++ This will also break programs that rely on the old behaviour and |
37061 |
++ expect that dynamically allocated memory via the malloc() family |
37062 |
++ of functions is executable (which it is not). Notable examples |
37063 |
++ are the XFree86 4.x server, the java runtime and wine. |
37064 |
++ |
37065 |
++config PAX_PAGEEXEC |
37066 |
++ bool "Paging based non-executable pages" |
37067 |
++ depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2) |
37068 |
++ help |
37069 |
++ This implementation is based on the paging feature of the CPU. |
37070 |
++ On i386 without hardware non-executable bit support there is a |
37071 |
++ variable but usually low performance impact, however on Intel's |
37072 |
++ P4 core based CPUs it is very high so you should not enable this |
37073 |
++ for kernels meant to be used on such CPUs. |
37074 |
++ |
37075 |
++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386 |
37076 |
++ with hardware non-executable bit support there is no performance |
37077 |
++ impact, on ppc the impact is negligible. |
37078 |
++ |
37079 |
++ Note that several architectures require various emulations due to |
37080 |
++ badly designed userland ABIs, this will cause a performance impact |
37081 |
++ but will disappear as soon as userland is fixed (e.g., ppc users |
37082 |
++ can make use of the secure-plt feature found in binutils). |
37083 |
++ |
37084 |
++config PAX_SEGMEXEC |
37085 |
++ bool "Segmentation based non-executable pages" |
37086 |
++ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32 |
37087 |
++ help |
37088 |
++ This implementation is based on the segmentation feature of the |
37089 |
++ CPU and has a very small performance impact, however applications |
37090 |
++ will be limited to a 1.5 GB address space instead of the normal |
37091 |
++ 3 GB. |
37092 |
++ |
37093 |
++config PAX_EMUTRAMP |
37094 |
++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86) |
37095 |
++ default y if PARISC || PPC32 |
37096 |
++ help |
37097 |
++ There are some programs and libraries that for one reason or |
37098 |
++ another attempt to execute special small code snippets from |
37099 |
++ non-executable memory pages. Most notable examples are the |
37100 |
++ signal handler return code generated by the kernel itself and |
37101 |
++ the GCC trampolines. |
37102 |
++ |
37103 |
++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then |
37104 |
++ such programs will no longer work under your kernel. |
37105 |
++ |
37106 |
++ As a remedy you can say Y here and use the 'chpax' or 'paxctl' |
37107 |
++ utilities to enable trampoline emulation for the affected programs |
37108 |
++ yet still have the protection provided by the non-executable pages. |
37109 |
++ |
37110 |
++ On parisc and ppc you MUST enable this option and EMUSIGRT as |
37111 |
++ well, otherwise your system will not even boot. |
37112 |
++ |
37113 |
++ Alternatively you can say N here and use the 'chpax' or 'paxctl' |
37114 |
++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC |
37115 |
++ for the affected files. |
37116 |
++ |
37117 |
++ NOTE: enabling this feature *may* open up a loophole in the |
37118 |
++ protection provided by non-executable pages that an attacker |
37119 |
++ could abuse. Therefore the best solution is to not have any |
37120 |
++ files on your system that would require this option. This can |
37121 |
++ be achieved by not using libc5 (which relies on the kernel |
37122 |
++ signal handler return code) and not using or rewriting programs |
37123 |
++ that make use of the nested function implementation of GCC. |
37124 |
++ Skilled users can just fix GCC itself so that it implements |
37125 |
++ nested function calls in a way that does not interfere with PaX. |
37126 |
++ |
37127 |
++config PAX_EMUSIGRT |
37128 |
++ bool "Automatically emulate sigreturn trampolines" |
37129 |
++ depends on PAX_EMUTRAMP && (PARISC || PPC32) |
37130 |
++ default y |
37131 |
++ help |
37132 |
++ Enabling this option will have the kernel automatically detect |
37133 |
++ and emulate signal return trampolines executing on the stack |
37134 |
++ that would otherwise lead to task termination. |
37135 |
++ |
37136 |
++ This solution is intended as a temporary one for users with |
37137 |
++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17, |
37138 |
++ Modula-3 runtime, etc) or executables linked to such, basically |
37139 |
++ everything that does not specify its own SA_RESTORER function in |
37140 |
++ normal executable memory like glibc 2.1+ does. |
37141 |
++ |
37142 |
++ On parisc and ppc you MUST enable this option, otherwise your |
37143 |
++ system will not even boot. |
37144 |
++ |
37145 |
++ NOTE: this feature cannot be disabled on a per executable basis |
37146 |
++ and since it *does* open up a loophole in the protection provided |
37147 |
++ by non-executable pages, the best solution is to not have any |
37148 |
++ files on your system that would require this option. |
37149 |
++ |
37150 |
++config PAX_MPROTECT |
37151 |
++ bool "Restrict mprotect()" |
37152 |
++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64 |
37153 |
++ help |
37154 |
++ Enabling this option will prevent programs from |
37155 |
++ - changing the executable status of memory pages that were |
37156 |
++ not originally created as executable, |
37157 |
++ - making read-only executable pages writable again, |
37158 |
++ - creating executable pages from anonymous memory. |
37159 |
++ |
37160 |
++ You should say Y here to complete the protection provided by |
37161 |
++ the enforcement of non-executable pages. |
37162 |
++ |
37163 |
++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control |
37164 |
++ this feature on a per file basis. |
37165 |
++ |
37166 |
++config PAX_NOELFRELOCS |
37167 |
++ bool "Disallow ELF text relocations" |
37168 |
++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64) |
37169 |
++ help |
37170 |
++ Non-executable pages and mprotect() restrictions are effective |
37171 |
++ in preventing the introduction of new executable code into an |
37172 |
++ attacked task's address space. There remain only two venues |
37173 |
++ for this kind of attack: if the attacker can execute already |
37174 |
++ existing code in the attacked task then he can either have it |
37175 |
++ create and mmap() a file containing his code or have it mmap() |
37176 |
++ an already existing ELF library that does not have position |
37177 |
++ independent code in it and use mprotect() on it to make it |
37178 |
++ writable and copy his code there. While protecting against |
37179 |
++ the former approach is beyond PaX, the latter can be prevented |
37180 |
++ by having only PIC ELF libraries on one's system (which do not |
37181 |
++ need to relocate their code). If you are sure this is your case, |
37182 |
++ then enable this option otherwise be careful as you may not even |
37183 |
++ be able to boot or log on your system (for example, some PAM |
37184 |
++ modules are erroneously compiled as non-PIC by default). |
37185 |
++ |
37186 |
++ NOTE: if you are using dynamic ELF executables (as suggested |
37187 |
++ when using ASLR) then you must have made sure that you linked |
37188 |
++ your files using the PIC version of crt1 (the et_dyn.tar.gz package |
37189 |
++ referenced there has already been updated to support this). |
37190 |
++ |
37191 |
++config PAX_ETEXECRELOCS |
37192 |
++ bool "Allow ELF ET_EXEC text relocations" |
37193 |
++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC) |
37194 |
++ default y |
37195 |
++ help |
37196 |
++ On some architectures there are incorrectly created applications |
37197 |
++ that require text relocations and would not work without enabling |
37198 |
++ this option. If you are an alpha, ia64 or parisc user, you should |
37199 |
++ enable this option and disable it once you have made sure that |
37200 |
++ none of your applications need it. |
37201 |
++ |
37202 |
++config PAX_EMUPLT |
37203 |
++ bool "Automatically emulate ELF PLT" |
37204 |
++ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64) |
37205 |
++ default y |
37206 |
++ help |
37207 |
++ Enabling this option will have the kernel automatically detect |
37208 |
++ and emulate the Procedure Linkage Table entries in ELF files. |
37209 |
++ On some architectures such entries are in writable memory, and |
37210 |
++ become non-executable leading to task termination. Therefore |
37211 |
++ it is mandatory that you enable this option on alpha, parisc, |
37212 |
++ ppc (if secure-plt is not used throughout in userland), sparc |
37213 |
++ and sparc64, otherwise your system would not even boot. |
37214 |
++ |
37215 |
++ NOTE: this feature *does* open up a loophole in the protection |
37216 |
++ provided by the non-executable pages, therefore the proper |
37217 |
++ solution is to modify the toolchain to produce a PLT that does |
37218 |
++ not need to be writable. |
37219 |
++ |
37220 |
++config PAX_DLRESOLVE |
37221 |
++ bool |
37222 |
++ depends on PAX_EMUPLT && (SPARC32 || SPARC64) |
37223 |
++ default y |
37224 |
++ |
37225 |
++config PAX_SYSCALL |
37226 |
++ bool |
37227 |
++ depends on PAX_PAGEEXEC && PPC32 |
37228 |
++ default y |
37229 |
++ |
37230 |
++config PAX_KERNEXEC |
37231 |
++ bool "Enforce non-executable kernel pages" |
37232 |
++ depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT |
37233 |
++ help |
37234 |
++ This is the kernel land equivalent of PAGEEXEC and MPROTECT, |
37235 |
++ that is, enabling this option will make it harder to inject |
37236 |
++ and execute 'foreign' code in kernel memory itself. |
37237 |
++ |
37238 |
++endmenu |
37239 |
++ |
37240 |
++menu "Address Space Layout Randomization" |
37241 |
++ depends on PAX |
37242 |
++ |
37243 |
++config PAX_ASLR |
37244 |
++ bool "Address Space Layout Randomization" |
37245 |
++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS |
37246 |
++ help |
37247 |
++ Many if not most exploit techniques rely on the knowledge of |
37248 |
++ certain addresses in the attacked program. The following options |
37249 |
++ will allow the kernel to apply a certain amount of randomization |
37250 |
++ to specific parts of the program thereby forcing an attacker to |
37251 |
++ guess them in most cases. Any failed guess will most likely crash |
37252 |
++ the attacked program which allows the kernel to detect such attempts |
37253 |
++ and react on them. PaX itself provides no reaction mechanisms, |
37254 |
++ instead it is strongly encouraged that you make use of Nergal's |
37255 |
++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's |
37256 |
++ (http://www.grsecurity.net/) built-in crash detection features or |
37257 |
++ develop one yourself. |
37258 |
++ |
37259 |
++ By saying Y here you can choose to randomize the following areas: |
37260 |
++ - top of the task's kernel stack |
37261 |
++ - top of the task's userland stack |
37262 |
++ - base address for mmap() requests that do not specify one |
37263 |
++ (this includes all libraries) |
37264 |
++ - base address of the main executable |
37265 |
++ |
37266 |
++ It is strongly recommended to say Y here as address space layout |
37267 |
++ randomization has negligible impact on performance yet it provides |
37268 |
++ a very effective protection. |
37269 |
++ |
37270 |
++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control |
37271 |
++ this feature on a per file basis. |
37272 |
++ |
37273 |
++config PAX_RANDKSTACK |
37274 |
++ bool "Randomize kernel stack base" |
37275 |
++ depends on PAX_ASLR && X86_TSC && X86_32 |
37276 |
++ help |
37277 |
++ By saying Y here the kernel will randomize every task's kernel |
37278 |
++ stack on every system call. This will not only force an attacker |
37279 |
++ to guess it but also prevent him from making use of possible |
37280 |
++ leaked information about it. |
37281 |
++ |
37282 |
++ Since the kernel stack is a rather scarce resource, randomization |
37283 |
++ may cause unexpected stack overflows, therefore you should very |
37284 |
++ carefully test your system. Note that once enabled in the kernel |
37285 |
++ configuration, this feature cannot be disabled on a per file basis. |
37286 |
++ |
37287 |
++config PAX_RANDUSTACK |
37288 |
++ bool "Randomize user stack base" |
37289 |
++ depends on PAX_ASLR |
37290 |
++ help |
37291 |
++ By saying Y here the kernel will randomize every task's userland |
37292 |
++ stack. The randomization is done in two steps where the second |
37293 |
++ one may apply a big amount of shift to the top of the stack and |
37294 |
++ cause problems for programs that want to use lots of memory (more |
37295 |
++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is). |
37296 |
++ For this reason the second step can be controlled by 'chpax' or |
37297 |
++ 'paxctl' on a per file basis. |
37298 |
++ |
37299 |
++config PAX_RANDMMAP |
37300 |
++ bool "Randomize mmap() base" |
37301 |
++ depends on PAX_ASLR |
37302 |
++ help |
37303 |
++ By saying Y here the kernel will use a randomized base address for |
37304 |
++ mmap() requests that do not specify one themselves. As a result |
37305 |
++ all dynamically loaded libraries will appear at random addresses |
37306 |
++ and therefore be harder to exploit by a technique where an attacker |
37307 |
++ attempts to execute library code for his purposes (e.g. spawn a |
37308 |
++ shell from an exploited program that is running at an elevated |
37309 |
++ privilege level). |
37310 |
++ |
37311 |
++ Furthermore, if a program is relinked as a dynamic ELF file, its |
37312 |
++ base address will be randomized as well, completing the full |
37313 |
++ randomization of the address space layout. Attacking such programs |
37314 |
++ becomes a guess game. You can find an example of doing this at |
37315 |
++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at |
37316 |
++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz . |
37317 |
++ |
37318 |
++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this |
37319 |
++ feature on a per file basis. |
37320 |
++ |
37321 |
++endmenu |
37322 |
++ |
37323 |
++menu "Miscellaneous hardening features" |
37324 |
++ |
37325 |
++config PAX_MEMORY_SANITIZE |
37326 |
++ bool "Sanitize all freed memory" |
37327 |
++ help |
37328 |
++ By saying Y here the kernel will erase memory pages as soon as they |
37329 |
++ are freed. This in turn reduces the lifetime of data stored in the |
37330 |
++ pages, making it less likely that sensitive information such as |
37331 |
++ passwords, cryptographic secrets, etc stay in memory for too long. |
37332 |
++ |
37333 |
++ This is especially useful for programs whose runtime is short, long |
37334 |
++ lived processes and the kernel itself benefit from this as long as |
37335 |
++ they operate on whole memory pages and ensure timely freeing of pages |
37336 |
++ that may hold sensitive information. |
37337 |
++ |
37338 |
++ The tradeoff is performance impact, on a single CPU system kernel |
37339 |
++ compilation sees a 3% slowdown, other systems and workloads may vary |
37340 |
++ and you are advised to test this feature on your expected workload |
37341 |
++ before deploying it. |
37342 |
++ |
37343 |
++ Note that this feature does not protect data stored in live pages, |
37344 |
++ e.g., process memory swapped to disk may stay there for a long time. |
37345 |
++ |
37346 |
++config PAX_MEMORY_UDEREF |
37347 |
++ bool "Prevent invalid userland pointer dereference" |
37348 |
++ depends on X86_32 && !COMPAT_VDSO |
37349 |
++ help |
37350 |
++ By saying Y here the kernel will be prevented from dereferencing |
37351 |
++ userland pointers in contexts where the kernel expects only kernel |
37352 |
++ pointers. This is both a useful runtime debugging feature and a |
37353 |
++ security measure that prevents exploiting a class of kernel bugs. |
37354 |
++ |
37355 |
++ The tradeoff is that some virtualization solutions may experience |
37356 |
++ a huge slowdown and therefore you should not enable this feature |
37357 |
++ for kernels meant to run in such environments. Whether a given VM |
37358 |
++ solution is affected or not is best determined by simply trying it |
37359 |
++ out, the performance impact will be obvious right on boot as this |
37360 |
++ mechanism engages from very early on. A good rule of thumb is that |
37361 |
++ VMs running on CPUs without hardware virtualization support (i.e., |
37362 |
++ the majority of IA-32 CPUs) will likely experience the slowdown. |
37363 |
++ |
37364 |
++endmenu |
37365 |
++ |
37366 |
++endmenu |
37367 |
++ |
37368 |
+ config KEYS |
37369 |
+ bool "Enable access key retention support" |
37370 |
+ help |
37371 |
+diff -urNp linux-2.6.24.4/sound/core/oss/pcm_oss.c linux-2.6.24.4/sound/core/oss/pcm_oss.c |
37372 |
+--- linux-2.6.24.4/sound/core/oss/pcm_oss.c 2008-03-24 14:49:18.000000000 -0400 |
37373 |
++++ linux-2.6.24.4/sound/core/oss/pcm_oss.c 2008-03-26 17:56:56.000000000 -0400 |
37374 |
+@@ -2913,8 +2913,8 @@ static void snd_pcm_oss_proc_done(struct |
37375 |
+ } |
37376 |
+ } |
37377 |
+ #else /* !CONFIG_SND_VERBOSE_PROCFS */ |
37378 |
+-#define snd_pcm_oss_proc_init(pcm) |
37379 |
+-#define snd_pcm_oss_proc_done(pcm) |
37380 |
++#define snd_pcm_oss_proc_init(pcm) do {} while (0) |
37381 |
++#define snd_pcm_oss_proc_done(pcm) do {} while (0) |
37382 |
+ #endif /* CONFIG_SND_VERBOSE_PROCFS */ |
37383 |
+ |
37384 |
+ /* |
37385 |
+diff -urNp linux-2.6.24.4/sound/core/seq/seq_lock.h linux-2.6.24.4/sound/core/seq/seq_lock.h |
37386 |
+--- linux-2.6.24.4/sound/core/seq/seq_lock.h 2008-03-24 14:49:18.000000000 -0400 |
37387 |
++++ linux-2.6.24.4/sound/core/seq/seq_lock.h 2008-03-26 17:56:56.000000000 -0400 |
37388 |
+@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo |
37389 |
+ #else /* SMP || CONFIG_SND_DEBUG */ |
37390 |
+ |
37391 |
+ typedef spinlock_t snd_use_lock_t; /* dummy */ |
37392 |
+-#define snd_use_lock_init(lockp) /**/ |
37393 |
+-#define snd_use_lock_use(lockp) /**/ |
37394 |
+-#define snd_use_lock_free(lockp) /**/ |
37395 |
+-#define snd_use_lock_sync(lockp) /**/ |
37396 |
++#define snd_use_lock_init(lockp) do {} while (0) |
37397 |
++#define snd_use_lock_use(lockp) do {} while (0) |
37398 |
++#define snd_use_lock_free(lockp) do {} while (0) |
37399 |
++#define snd_use_lock_sync(lockp) do {} while (0) |
37400 |
+ |
37401 |
+ #endif /* SMP || CONFIG_SND_DEBUG */ |
37402 |
+ |
37403 |
+diff -urNp linux-2.6.24.4/sound/pci/ac97/ac97_patch.c linux-2.6.24.4/sound/pci/ac97/ac97_patch.c |
37404 |
+--- linux-2.6.24.4/sound/pci/ac97/ac97_patch.c 2008-03-24 14:49:18.000000000 -0400 |
37405 |
++++ linux-2.6.24.4/sound/pci/ac97/ac97_patch.c 2008-03-26 17:56:56.000000000 -0400 |
37406 |
+@@ -1478,7 +1478,7 @@ static const struct snd_ac97_res_table a |
37407 |
+ { AC97_VIDEO, 0x9f1f }, |
37408 |
+ { AC97_AUX, 0x9f1f }, |
37409 |
+ { AC97_PCM, 0x9f1f }, |
37410 |
+- { } /* terminator */ |
37411 |
++ { 0, 0 } /* terminator */ |
37412 |
+ }; |
37413 |
+ |
37414 |
+ static int patch_ad1819(struct snd_ac97 * ac97) |
37415 |
+@@ -3537,7 +3537,7 @@ static struct snd_ac97_res_table lm4550_ |
37416 |
+ { AC97_AUX, 0x1f1f }, |
37417 |
+ { AC97_PCM, 0x1f1f }, |
37418 |
+ { AC97_REC_GAIN, 0x0f0f }, |
37419 |
+- { } /* terminator */ |
37420 |
++ { 0, 0 } /* terminator */ |
37421 |
+ }; |
37422 |
+ |
37423 |
+ static int patch_lm4550(struct snd_ac97 *ac97) |
37424 |
+diff -urNp linux-2.6.24.4/sound/pci/ens1370.c linux-2.6.24.4/sound/pci/ens1370.c |
37425 |
+--- linux-2.6.24.4/sound/pci/ens1370.c 2008-03-24 14:49:18.000000000 -0400 |
37426 |
++++ linux-2.6.24.4/sound/pci/ens1370.c 2008-03-26 17:56:56.000000000 -0400 |
37427 |
+@@ -453,7 +453,7 @@ static struct pci_device_id snd_audiopci |
37428 |
+ { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */ |
37429 |
+ { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */ |
37430 |
+ #endif |
37431 |
+- { 0, } |
37432 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
37433 |
+ }; |
37434 |
+ |
37435 |
+ MODULE_DEVICE_TABLE(pci, snd_audiopci_ids); |
37436 |
+diff -urNp linux-2.6.24.4/sound/pci/intel8x0.c linux-2.6.24.4/sound/pci/intel8x0.c |
37437 |
+--- linux-2.6.24.4/sound/pci/intel8x0.c 2008-03-24 14:49:18.000000000 -0400 |
37438 |
++++ linux-2.6.24.4/sound/pci/intel8x0.c 2008-03-26 17:56:56.000000000 -0400 |
37439 |
+@@ -436,7 +436,7 @@ static struct pci_device_id snd_intel8x0 |
37440 |
+ { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ |
37441 |
+ { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */ |
37442 |
+ { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */ |
37443 |
+- { 0, } |
37444 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
37445 |
+ }; |
37446 |
+ |
37447 |
+ MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids); |
37448 |
+@@ -2044,7 +2044,7 @@ static struct ac97_quirk ac97_quirks[] _ |
37449 |
+ .type = AC97_TUNE_HP_ONLY |
37450 |
+ }, |
37451 |
+ #endif |
37452 |
+- { } /* terminator */ |
37453 |
++ { 0, 0, 0, 0, NULL, 0 } /* terminator */ |
37454 |
+ }; |
37455 |
+ |
37456 |
+ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, |
37457 |
+diff -urNp linux-2.6.24.4/sound/pci/intel8x0m.c linux-2.6.24.4/sound/pci/intel8x0m.c |
37458 |
+--- linux-2.6.24.4/sound/pci/intel8x0m.c 2008-03-24 14:49:18.000000000 -0400 |
37459 |
++++ linux-2.6.24.4/sound/pci/intel8x0m.c 2008-03-26 17:56:56.000000000 -0400 |
37460 |
+@@ -240,7 +240,7 @@ static struct pci_device_id snd_intel8x0 |
37461 |
+ { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ |
37462 |
+ { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */ |
37463 |
+ #endif |
37464 |
+- { 0, } |
37465 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
37466 |
+ }; |
37467 |
+ |
37468 |
+ MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids); |
37469 |
+@@ -1261,7 +1261,7 @@ static struct shortname_table { |
37470 |
+ { 0x5455, "ALi M5455" }, |
37471 |
+ { 0x746d, "AMD AMD8111" }, |
37472 |
+ #endif |
37473 |
+- { 0 }, |
37474 |
++ { 0, NULL }, |
37475 |
+ }; |
37476 |
+ |
37477 |
+ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci, |
37478 |
|
37479 |
Added: hardened-sources/2.6/tags/2.6.24-1/4421_remove-localversion-grsec.patch |
37480 |
=================================================================== |
37481 |
--- hardened-sources/2.6/tags/2.6.24-1/4421_remove-localversion-grsec.patch (rev 0) |
37482 |
+++ hardened-sources/2.6/tags/2.6.24-1/4421_remove-localversion-grsec.patch 2008-04-30 11:39:06 UTC (rev 94) |
37483 |
@@ -0,0 +1,4 @@ |
37484 |
+--- a/localversion-grsec 2008-02-24 14:26:59.000000000 +0000 |
37485 |
++++ b/localversion-grsec 1970-01-01 01:00:00.000000000 +0100 |
37486 |
+@@ -1 +0,0 @@ |
37487 |
+--grsec |
37488 |
|
37489 |
Added: hardened-sources/2.6/tags/2.6.24-1/4425_alpha-sysctl-uac-for-hardened.patch |
37490 |
=================================================================== |
37491 |
--- hardened-sources/2.6/tags/2.6.24-1/4425_alpha-sysctl-uac-for-hardened.patch (rev 0) |
37492 |
+++ hardened-sources/2.6/tags/2.6.24-1/4425_alpha-sysctl-uac-for-hardened.patch 2008-04-30 11:39:06 UTC (rev 94) |
37493 |
@@ -0,0 +1,181 @@ |
37494 |
+--- a/arch/alpha/Kconfig |
37495 |
++++ b/arch/alpha/Kconfig |
37496 |
+@@ -616,6 +616,32 @@ config VERBOSE_MCHECK_ON |
37497 |
+ |
37498 |
+ Take the default (1) unless you want more control or more info. |
37499 |
+ |
37500 |
++config ALPHA_UAC_SYSCTL |
37501 |
++ bool "Configure UAC policy via sysctl" |
37502 |
++ depends on SYSCTL |
37503 |
++ default y |
37504 |
++ ---help--- |
37505 |
++ Configuring the UAC (unaligned access control) policy on a Linux |
37506 |
++ system usually involves setting a compile time define. If you say |
37507 |
++ Y here, you will be able to modify the UAC policy at runtime using |
37508 |
++ the /proc interface. |
37509 |
++ |
37510 |
++ The UAC policy defines the action Linux should take when an |
37511 |
++ unaligned memory access occurs. The action can include printing a |
37512 |
++ warning message (NOPRINT), sending a signal to the offending |
37513 |
++ program to help developers debug their applications (SIGBUS), or |
37514 |
++ disabling the transparent fixing (NOFIX). |
37515 |
++ |
37516 |
++ The sysctls will be initialized to the compile-time defined UAC |
37517 |
++ policy. You can change these manually, or with the sysctl(8) |
37518 |
++ userspace utility. |
37519 |
++ |
37520 |
++ To disable the warning messages at runtime, you would use |
37521 |
++ |
37522 |
++ echo 1 > /proc/sys/kernel/uac/noprint |
37523 |
++ |
37524 |
++ This is pretty harmless. Say Y if you're not sure. |
37525 |
++ |
37526 |
+ source "drivers/pci/Kconfig" |
37527 |
+ source "drivers/eisa/Kconfig" |
37528 |
+ |
37529 |
+--- a/arch/alpha/kernel/traps.c |
37530 |
++++ b/arch/alpha/kernel/traps.c |
37531 |
+@@ -14,6 +14,7 @@ |
37532 |
+ #include <linux/delay.h> |
37533 |
+ #include <linux/smp_lock.h> |
37534 |
+ #include <linux/module.h> |
37535 |
++#include <linux/sysctl.h> |
37536 |
+ #include <linux/init.h> |
37537 |
+ #include <linux/kallsyms.h> |
37538 |
+ |
37539 |
+@@ -102,6 +103,38 @@ static char * ireg_name[] = {"v0", "t0", |
37540 |
+ "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"}; |
37541 |
+ #endif |
37542 |
+ |
37543 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
37544 |
++static struct ctl_table_header *uac_sysctl_header; |
37545 |
++ |
37546 |
++static int enabled_noprint = 0; |
37547 |
++static int enabled_sigbus = 0; |
37548 |
++static int enabled_nofix = 0; |
37549 |
++ |
37550 |
++ctl_table uac_table[] = { |
37551 |
++ {KERN_UAC_NOPRINT, "noprint", &enabled_noprint, sizeof (int), 0644, NULL, NULL, &proc_dointvec}, |
37552 |
++ {KERN_UAC_SIGBUS, "sigbus", &enabled_sigbus, sizeof (int), 0644, NULL, NULL, &proc_dointvec}, |
37553 |
++ {KERN_UAC_NOFIX, "nofix", &enabled_nofix, sizeof (int), 0644, NULL, NULL, &proc_dointvec}, |
37554 |
++ {0} |
37555 |
++}; |
37556 |
++ |
37557 |
++static int __init init_uac_sysctl(void) |
37558 |
++{ |
37559 |
++ /* Initialize sysctls with the #defined UAC policy */ |
37560 |
++ enabled_noprint = (test_thread_flag (TIF_UAC_NOPRINT)) ? 1 : 0; |
37561 |
++ enabled_sigbus = (test_thread_flag (TIF_UAC_SIGBUS)) ? 1 : 0; |
37562 |
++ enabled_nofix = (test_thread_flag (TIF_UAC_NOFIX)) ? 1 : 0; |
37563 |
++ |
37564 |
++ /* save this for later so we can clean up */ |
37565 |
++ uac_sysctl_header = register_sysctl_table(uac_table); |
37566 |
++ return 0; |
37567 |
++} |
37568 |
++ |
37569 |
++static void __exit exit_uac_sysctl(void) |
37570 |
++{ |
37571 |
++ unregister_sysctl_table(uac_sysctl_header); |
37572 |
++} |
37573 |
++#endif |
37574 |
++ |
37575 |
+ static void |
37576 |
+ dik_show_code(unsigned int *pc) |
37577 |
+ { |
37578 |
+@@ -780,7 +813,11 @@ do_entUnaUser(void __user * va, unsigned |
37579 |
+ /* Check the UAC bits to decide what the user wants us to do |
37580 |
+ with the unaliged access. */ |
37581 |
+ |
37582 |
++#ifndef CONFIG_ALPHA_UAC_SYSCTL |
37583 |
+ if (!test_thread_flag (TIF_UAC_NOPRINT)) { |
37584 |
++#else /* CONFIG_ALPHA_UAC_SYSCTL */ |
37585 |
++ if (!(enabled_noprint)) { |
37586 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
37587 |
+ if (cnt >= 5 && jiffies - last_time > 5*HZ) { |
37588 |
+ cnt = 0; |
37589 |
+ } |
37590 |
+@@ -791,10 +828,18 @@ do_entUnaUser(void __user * va, unsigned |
37591 |
+ } |
37592 |
+ last_time = jiffies; |
37593 |
+ } |
37594 |
++#ifndef CONFIG_ALPHA_UAC_SYSCTL |
37595 |
+ if (test_thread_flag (TIF_UAC_SIGBUS)) |
37596 |
++#else /* CONFIG_ALPHA_UAC_SYSCTL */ |
37597 |
++ if (enabled_sigbus) |
37598 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
37599 |
+ goto give_sigbus; |
37600 |
+ /* Not sure why you'd want to use this, but... */ |
37601 |
++#ifndef CONFIG_ALPHA_UAC_SYSCTL |
37602 |
+ if (test_thread_flag (TIF_UAC_NOFIX)) |
37603 |
++#else /* CONFIG_ALPHA_UAC_SYSCTL */ |
37604 |
++ if (enabled_nofix) |
37605 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
37606 |
+ return; |
37607 |
+ |
37608 |
+ /* Don't bother reading ds in the access check since we already |
37609 |
+@@ -1089,3 +1134,7 @@ trap_init(void) |
37610 |
+ wrent(entSys, 5); |
37611 |
+ wrent(entDbg, 6); |
37612 |
+ } |
37613 |
++ |
37614 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
37615 |
++__initcall(init_uac_sysctl); |
37616 |
++#endif |
37617 |
+--- a/include/linux/sysctl.h |
37618 |
++++ b/include/linux/sysctl.h |
37619 |
+@@ -164,6 +164,10 @@ enum |
37620 |
+ KERN_MAX_LOCK_DEPTH=74, |
37621 |
+ KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */ |
37622 |
+ KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */ |
37623 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
37624 |
++ KERN_UAC_POLICY=77, /* int: Alpha unaligned access control policy flags */ |
37625 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
37626 |
++ |
37627 |
+ #ifdef CONFIG_GRKERNSEC |
37628 |
+ KERN_GRSECURITY=98, /* grsecurity */ |
37629 |
+ #endif |
37630 |
+@@ -265,6 +269,17 @@ enum |
37631 |
+ PTY_NR=2 |
37632 |
+ }; |
37633 |
+ |
37634 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
37635 |
++/* /proc/sys/kernel/uac */ |
37636 |
++enum |
37637 |
++{ |
37638 |
++ /* UAC policy on Alpha */ |
37639 |
++ KERN_UAC_NOPRINT=1, /* int: printk() on unaligned access */ |
37640 |
++ KERN_UAC_SIGBUS=2, /* int: send SIGBUS on unaligned access */ |
37641 |
++ KERN_UAC_NOFIX=3, /* int: don't fix the unaligned access */ |
37642 |
++}; |
37643 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
37644 |
++ |
37645 |
+ /* /proc/sys/bus/isa */ |
37646 |
+ enum |
37647 |
+ { |
37648 |
+--- a/kernel/sysctl.c |
37649 |
++++ b/kernel/sysctl.c |
37650 |
+@@ -153,6 +153,9 @@ extern int max_lock_depth; |
37651 |
+ static int parse_table(int __user *, int, void __user *, size_t __user *, |
37652 |
+ void __user *, size_t, struct ctl_table *); |
37653 |
+ #endif |
37654 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
37655 |
++extern ctl_table uac_table[]; |
37656 |
++#endif |
37657 |
+ |
37658 |
+ |
37659 |
+ #ifdef CONFIG_PROC_SYSCTL |
37660 |
+@@ -254,6 +257,14 @@ static struct ctl_table root_table[] = { |
37661 |
+ * NOTE: do not add new entries to this table unless you have read |
37662 |
+ * Documentation/sysctl/ctl_unnumbered.txt |
37663 |
+ */ |
37664 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
37665 |
++ { |
37666 |
++ .ctl_name = KERN_UAC_POLICY, |
37667 |
++ .procname = "uac", |
37668 |
++ .mode = 0555, |
37669 |
++ .child = uac_table, |
37670 |
++ }, |
37671 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
37672 |
+ { .ctl_name = 0 } |
37673 |
+ }; |
37674 |
+ |
37675 |
|
37676 |
Added: hardened-sources/2.6/tags/2.6.24-1/4430_grsec-kconfig-default-gids.patch |
37677 |
=================================================================== |
37678 |
--- hardened-sources/2.6/tags/2.6.24-1/4430_grsec-kconfig-default-gids.patch (rev 0) |
37679 |
+++ hardened-sources/2.6/tags/2.6.24-1/4430_grsec-kconfig-default-gids.patch 2008-04-30 11:39:06 UTC (rev 94) |
37680 |
@@ -0,0 +1,76 @@ |
37681 |
+From: Kerin Millar <kerframil@×××××.com> |
37682 |
+ |
37683 |
+grsecurity contains a number of options which allow certain protections |
37684 |
+to be applied to or exempted from members of a given group. However, the |
37685 |
+default GIDs specified in the upstream patch are entirely arbitrary and |
37686 |
+there is no telling which (if any) groups the GIDs will correlate with |
37687 |
+on an end-user's system. Because some users don't pay a great deal of |
37688 |
+attention to the finer points of kernel configuration, it is probably |
37689 |
+wise to specify some reasonable defaults so as to stop careless users |
37690 |
+from shooting themselves in the foot. |
37691 |
+ |
37692 |
+--- a/grsecurity/Kconfig |
37693 |
++++ b/grsecurity/Kconfig |
37694 |
+@@ -352,7 +564,7 @@ |
37695 |
+ config GRKERNSEC_PROC_GID |
37696 |
+ int "GID for special group" |
37697 |
+ depends on GRKERNSEC_PROC_USERGROUP |
37698 |
+- default 1001 |
37699 |
++ default 10 |
37700 |
+ |
37701 |
+ config GRKERNSEC_PROC_ADD |
37702 |
+ bool "Additional restrictions" |
37703 |
+@@ -547,7 +759,7 @@ |
37704 |
+ config GRKERNSEC_AUDIT_GID |
37705 |
+ int "GID for auditing" |
37706 |
+ depends on GRKERNSEC_AUDIT_GROUP |
37707 |
+- default 1007 |
37708 |
++ default 100 |
37709 |
+ |
37710 |
+ config GRKERNSEC_EXECLOG |
37711 |
+ bool "Exec logging" |
37712 |
+@@ -700,7 +912,7 @@ |
37713 |
+ config GRKERNSEC_TPE_GID |
37714 |
+ int "GID for untrusted users" |
37715 |
+ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT |
37716 |
+- default 1005 |
37717 |
++ default 100 |
37718 |
+ help |
37719 |
+ If you have selected the "Invert GID option" above, setting this |
37720 |
+ GID determines what group TPE restrictions will be *disabled* for. |
37721 |
+@@ -712,7 +924,7 @@ |
37722 |
+ config GRKERNSEC_TPE_GID |
37723 |
+ int "GID for trusted users" |
37724 |
+ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT |
37725 |
+- default 1005 |
37726 |
++ default 10 |
37727 |
+ help |
37728 |
+ If you have selected the "Invert GID option" above, setting this |
37729 |
+ GID determines what group TPE restrictions will be *disabled* for. |
37730 |
+@@ -754,7 +966,7 @@ |
37731 |
+ config GRKERNSEC_SOCKET_ALL_GID |
37732 |
+ int "GID to deny all sockets for" |
37733 |
+ depends on GRKERNSEC_SOCKET_ALL |
37734 |
+- default 1004 |
37735 |
++ default 65534 |
37736 |
+ help |
37737 |
+ Here you can choose the GID to disable socket access for. Remember to |
37738 |
+ add the users you want socket access disabled for to the GID |
37739 |
+@@ -775,7 +987,7 @@ |
37740 |
+ config GRKERNSEC_SOCKET_CLIENT_GID |
37741 |
+ int "GID to deny client sockets for" |
37742 |
+ depends on GRKERNSEC_SOCKET_CLIENT |
37743 |
+- default 1003 |
37744 |
++ default 65534 |
37745 |
+ help |
37746 |
+ Here you can choose the GID to disable client socket access for. |
37747 |
+ Remember to add the users you want client socket access disabled for to |
37748 |
+@@ -793,7 +1005,7 @@ |
37749 |
+ config GRKERNSEC_SOCKET_SERVER_GID |
37750 |
+ int "GID to deny server sockets for" |
37751 |
+ depends on GRKERNSEC_SOCKET_SERVER |
37752 |
+- default 1002 |
37753 |
++ default 65534 |
37754 |
+ help |
37755 |
+ Here you can choose the GID to disable server socket access for. |
37756 |
+ Remember to add the users you want server socket access disabled for to |
37757 |
|
37758 |
Added: hardened-sources/2.6/tags/2.6.24-1/4435_grsec-kconfig-gentoo.patch |
37759 |
=================================================================== |
37760 |
--- hardened-sources/2.6/tags/2.6.24-1/4435_grsec-kconfig-gentoo.patch (rev 0) |
37761 |
+++ hardened-sources/2.6/tags/2.6.24-1/4435_grsec-kconfig-gentoo.patch 2008-04-30 11:39:06 UTC (rev 94) |
37762 |
@@ -0,0 +1,239 @@ |
37763 |
+From: Gordon Malm <bugs-gentoo-org-02@××××××.org> |
37764 |
+From: Kerin Millar <kerframil@×××××.com> |
37765 |
+ |
37766 |
+Add Hardened Gentoo [server/workstation] predefined grsecurity |
37767 |
+levels. They're designed to provide a comparitively high level of |
37768 |
+security while remaining generally suitable for as great a majority |
37769 |
+of the userbase as possible (particularly new users). |
37770 |
+ |
37771 |
+Make Hardened Gentoo [workstation] predefined grsecurity level the |
37772 |
+default. The Hardened Gentoo [server] level is more restrictive |
37773 |
+and conflicts with some software and thus would be less suitable. |
37774 |
+ |
37775 |
+The original version of this patch was conceived and created by: |
37776 |
+Ned Ludd <solar@g.o> |
37777 |
+ |
37778 |
+--- a/grsecurity/Kconfig |
37779 |
++++ b/grsecurity/Kconfig |
37780 |
+@@ -20,7 +20,7 @@ |
37781 |
+ choice |
37782 |
+ prompt "Security Level" |
37783 |
+ depends on GRKERNSEC |
37784 |
+- default GRKERNSEC_CUSTOM |
37785 |
++ default GRKERNSEC_HARDENED_WORKSTATION |
37786 |
+ |
37787 |
+ config GRKERNSEC_LOW |
37788 |
+ bool "Low" |
37789 |
+@@ -181,6 +181,212 @@ |
37790 |
+ - Mount/unmount/remount logging |
37791 |
+ - Kernel symbol hiding |
37792 |
+ - Prevention of memory exhaustion-based exploits |
37793 |
++ |
37794 |
++config GRKERNSEC_HARDENED_SERVER |
37795 |
++ bool "Hardened Gentoo [server]" |
37796 |
++# select GRKERNSEC_AUDIT_MOUNT |
37797 |
++ select GRKERNSEC_BRUTE |
37798 |
++ select GRKERNSEC_CHROOT |
37799 |
++ select GRKERNSEC_CHROOT_CAPS |
37800 |
++ select GRKERNSEC_CHROOT_CHDIR |
37801 |
++ select GRKERNSEC_CHROOT_CHMOD |
37802 |
++ select GRKERNSEC_CHROOT_DOUBLE |
37803 |
++ select GRKERNSEC_CHROOT_FCHDIR |
37804 |
++ select GRKERNSEC_CHROOT_FINDTASK |
37805 |
++ select GRKERNSEC_CHROOT_MKNOD |
37806 |
++ select GRKERNSEC_CHROOT_MOUNT |
37807 |
++ select GRKERNSEC_CHROOT_NICE |
37808 |
++ select GRKERNSEC_CHROOT_PIVOT |
37809 |
++ select GRKERNSEC_CHROOT_SHMAT |
37810 |
++ select GRKERNSEC_CHROOT_SYSCTL |
37811 |
++ select GRKERNSEC_CHROOT_UNIX |
37812 |
++ select GRKERNSEC_DMESG |
37813 |
++ select GRKERNSEC_EXECVE |
37814 |
++ select GRKERNSEC_FIFO |
37815 |
++ select GRKERNSEC_FORKFAIL |
37816 |
++ select GRKERNSEC_HIDESYM |
37817 |
++ select GRKERNSEC_IO if (X86) |
37818 |
++ select GRKERNSEC_KMEM |
37819 |
++ select GRKERNSEC_LINK |
37820 |
++ select GRKERNSEC_MODSTOP if (MODULES) |
37821 |
++ select GRKERNSEC_PROC |
37822 |
++ select GRKERNSEC_PROC_ADD |
37823 |
++ select GRKERNSEC_PROC_IPADDR |
37824 |
++ select GRKERNSEC_PROC_MEMMAP |
37825 |
++ select GRKERNSEC_PROC_USERGROUP |
37826 |
++ select GRKERNSEC_RANDNET |
37827 |
++ select GRKERNSEC_RESLOG |
37828 |
++ select GRKERNSEC_SIGNAL |
37829 |
++# select GRKERNSEC_SOCKET |
37830 |
++# select GRKERNSEC_SOCKET_ALL |
37831 |
++ select GRKERNSEC_SYSCTL |
37832 |
++ select GRKERNSEC_SYSCTL_ON |
37833 |
++ select GRKERNSEC_TIME |
37834 |
++ select PAX |
37835 |
++ select PAX_ASLR |
37836 |
++ select PAX_DLRESOLVE if (SPARC32 || SPARC64) |
37837 |
++ select PAX_EI_PAX |
37838 |
++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64) |
37839 |
++ select PAX_EMUSIGRT if (PARISC || PPC32) |
37840 |
++ select PAX_EMUTRAMP if (PARISC || PPC32) |
37841 |
++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC) |
37842 |
++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK)) |
37843 |
++ select PAX_MEMORY_SANITIZE |
37844 |
++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO) |
37845 |
++ select PAX_MPROTECT if (!PPC64) |
37846 |
++ select PAX_HAVE_ACL_FLAGS |
37847 |
++ select PAX_NOEXEC |
37848 |
++ select PAX_PAGEEXEC |
37849 |
++ select PAX_PT_PAX_FLAGS |
37850 |
++ select PAX_RANDKSTACK if (X86_32 && X86_TSC) |
37851 |
++ select PAX_RANDMMAP |
37852 |
++ select PAX_RANDUSTACK |
37853 |
++ select PAX_SEGMEXEC if (X86_32) |
37854 |
++ select PAX_SYSCALL if (PPC32) |
37855 |
++ help |
37856 |
++ If you say Y here, a configuration will be used that is endorsed by |
37857 |
++ the Hardened Gentoo project. Therefore, many of the protections |
37858 |
++ made available by grsecurity and PaX will be enabled. |
37859 |
++ |
37860 |
++ Hardened Gentoo's pre-defined security levels are designed to provide |
37861 |
++ a high level of security while minimizing incompatibilities with the |
37862 |
++ majority of available software. For further information, please |
37863 |
++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as |
37864 |
++ well as the Hardened Gentoo Primer at |
37865 |
++ <http://www.gentoo.org/proj/en/hardened/primer.xml>. |
37866 |
++ |
37867 |
++ This Hardened Gentoo [server] level is identical to the |
37868 |
++ Hardened Gentoo [workstation] level, but with the GRKERNSEC_IO and |
37869 |
++ PAX_KERNEXEC security features enabled. Accordingly, this is the |
37870 |
++ preferred security level if the system will not be utilizing software |
37871 |
++ incompatible with the aforementioned grsecurity/PaX features. |
37872 |
++ |
37873 |
++ You may wish to emerge paxctl, a utility which allows you to toggle |
37874 |
++ PaX features on problematic binaries on an individual basis. Note that |
37875 |
++ this only works for ELF binaries that contain a PT_PAX_FLAGS header. |
37876 |
++ Translated, this means that if you wish to toggle PaX features on |
37877 |
++ binaries provided by applications that are distributed only in binary |
37878 |
++ format (rather than being built locally from sources), you will need to |
37879 |
++ run paxctl -C on the binaries beforehand so as to inject the missing |
37880 |
++ headers. |
37881 |
++ |
37882 |
++ When this level is selected, some options cannot be changed. However, |
37883 |
++ you may opt to fully customize the options that are selected by |
37884 |
++ choosing "Custom" in the Security Level menu. You may find it helpful |
37885 |
++ to inherit the options selected by the "Hardened Gentoo [server]" |
37886 |
++ security level as a starting point for further configuration. To |
37887 |
++ accomplish this, select this security level then exit the menuconfig |
37888 |
++ interface, saving changes when prompted. Then, run make menuconfig |
37889 |
++ again and select the "Custom" level. |
37890 |
++ |
37891 |
++ Note that this security level probably should not be used if the |
37892 |
++ target system is a 32bit x86 virtualized guest. If you intend to run |
37893 |
++ the kernel in a 32bit x86 virtualized guest you will likely need to |
37894 |
++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable |
37895 |
++ impact on performance. |
37896 |
++ |
37897 |
++config GRKERNSEC_HARDENED_WORKSTATION |
37898 |
++ bool "Hardened Gentoo [workstation]" |
37899 |
++# select GRKERNSEC_AUDIT_MOUNT |
37900 |
++ select GRKERNSEC_BRUTE |
37901 |
++ select GRKERNSEC_CHROOT |
37902 |
++ select GRKERNSEC_CHROOT_CAPS |
37903 |
++ select GRKERNSEC_CHROOT_CHDIR |
37904 |
++ select GRKERNSEC_CHROOT_CHMOD |
37905 |
++ select GRKERNSEC_CHROOT_DOUBLE |
37906 |
++ select GRKERNSEC_CHROOT_FCHDIR |
37907 |
++ select GRKERNSEC_CHROOT_FINDTASK |
37908 |
++ select GRKERNSEC_CHROOT_MKNOD |
37909 |
++ select GRKERNSEC_CHROOT_MOUNT |
37910 |
++ select GRKERNSEC_CHROOT_NICE |
37911 |
++ select GRKERNSEC_CHROOT_PIVOT |
37912 |
++ select GRKERNSEC_CHROOT_SHMAT |
37913 |
++ select GRKERNSEC_CHROOT_SYSCTL |
37914 |
++ select GRKERNSEC_CHROOT_UNIX |
37915 |
++ select GRKERNSEC_DMESG |
37916 |
++ select GRKERNSEC_EXECVE |
37917 |
++ select GRKERNSEC_FIFO |
37918 |
++ select GRKERNSEC_FORKFAIL |
37919 |
++ select GRKERNSEC_HIDESYM |
37920 |
++ select GRKERNSEC_KMEM |
37921 |
++ select GRKERNSEC_LINK |
37922 |
++ select GRKERNSEC_MODSTOP if (MODULES) |
37923 |
++ select GRKERNSEC_PROC |
37924 |
++ select GRKERNSEC_PROC_ADD |
37925 |
++ select GRKERNSEC_PROC_IPADDR |
37926 |
++ select GRKERNSEC_PROC_MEMMAP |
37927 |
++ select GRKERNSEC_PROC_USERGROUP |
37928 |
++ select GRKERNSEC_RANDNET |
37929 |
++ select GRKERNSEC_RESLOG |
37930 |
++ select GRKERNSEC_SIGNAL |
37931 |
++# select GRKERNSEC_SOCKET |
37932 |
++# select GRKERNSEC_SOCKET_ALL |
37933 |
++ select GRKERNSEC_SYSCTL |
37934 |
++ select GRKERNSEC_SYSCTL_ON |
37935 |
++ select GRKERNSEC_TIME |
37936 |
++ select PAX |
37937 |
++ select PAX_ASLR |
37938 |
++ select PAX_DLRESOLVE if (SPARC32 || SPARC64) |
37939 |
++ select PAX_EI_PAX |
37940 |
++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64) |
37941 |
++ select PAX_EMUSIGRT if (PARISC || PPC32) |
37942 |
++ select PAX_EMUTRAMP if (PARISC || PPC32) |
37943 |
++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC) |
37944 |
++ select PAX_MEMORY_SANITIZE |
37945 |
++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO) |
37946 |
++ select PAX_MPROTECT if (!PPC64) |
37947 |
++ select PAX_HAVE_ACL_FLAGS |
37948 |
++ select PAX_NOEXEC |
37949 |
++ select PAX_PAGEEXEC |
37950 |
++ select PAX_PT_PAX_FLAGS |
37951 |
++ select PAX_RANDKSTACK if (X86_32 && X86_TSC) |
37952 |
++ select PAX_RANDMMAP |
37953 |
++ select PAX_RANDUSTACK |
37954 |
++ select PAX_SEGMEXEC if (X86_32) |
37955 |
++ select PAX_SYSCALL if (PPC32) |
37956 |
++ help |
37957 |
++ If you say Y here, a configuration will be used that is endorsed by |
37958 |
++ the Hardened Gentoo project. Therefore, many of the protections |
37959 |
++ made available by grsecurity and PaX will be enabled. |
37960 |
++ |
37961 |
++ Hardened Gentoo's pre-defined security levels are designed to provide |
37962 |
++ a high level of security while minimizing incompatibilities with the |
37963 |
++ majority of available software. For further information, please |
37964 |
++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as |
37965 |
++ well as the Hardened Gentoo Primer at |
37966 |
++ <http://www.gentoo.org/proj/en/hardened/primer.xml>. |
37967 |
++ |
37968 |
++ This Hardened Gentoo [workstation] level is designed for machines |
37969 |
++ which are intended to run software not compatible with the GRKERNSEC_IO |
37970 |
++ and PAX_KERNEXEC features of grsecurity. Accordingly, this security |
37971 |
++ level is suitable for use with the X server "Xorg" and/or any system |
37972 |
++ that will act as host OS to the virtualization softwares vmware-server |
37973 |
++ or virtualbox. |
37974 |
++ |
37975 |
++ You may wish to emerge paxctl, a utility which allows you to toggle |
37976 |
++ PaX features on problematic binaries on an individual basis. Note that |
37977 |
++ this only works for ELF binaries that contain a PT_PAX_FLAGS header. |
37978 |
++ Translated, this means that if you wish to toggle PaX features on |
37979 |
++ binaries provided by applications that are distributed only in binary |
37980 |
++ format (rather than being built locally from sources), you will need to |
37981 |
++ run paxctl -C on the binaries beforehand so as to inject the missing |
37982 |
++ headers. |
37983 |
++ |
37984 |
++ When this level is selected, some options cannot be changed. However, |
37985 |
++ you may opt to fully customize the options that are selected by |
37986 |
++ choosing "Custom" in the Security Level menu. You may find it helpful |
37987 |
++ to inherit the options selected by the "Hardened Gentoo [workstation]" |
37988 |
++ security level as a starting point for further configuration. To |
37989 |
++ accomplish this, select this security level then exit the menuconfig |
37990 |
++ interface, saving changes when prompted. Then, run make menuconfig |
37991 |
++ again and select the "Custom" level. |
37992 |
++ |
37993 |
++ Note that this security level probably should not be used if the |
37994 |
++ target system is a 32bit x86 virtualized guest. If you intend to run |
37995 |
++ the kernel in a 32bit x86 virtualized guest you will likely need to |
37996 |
++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable |
37997 |
++ impact on performance. |
37998 |
++ |
37999 |
+ config GRKERNSEC_CUSTOM |
38000 |
+ bool "Custom" |
38001 |
+ help |
38002 |
|
38003 |
Added: hardened-sources/2.6/tags/2.6.24-1/4440_grsec-kconfig-pax-without-grsec.patch |
38004 |
=================================================================== |
38005 |
--- hardened-sources/2.6/tags/2.6.24-1/4440_grsec-kconfig-pax-without-grsec.patch (rev 0) |
38006 |
+++ hardened-sources/2.6/tags/2.6.24-1/4440_grsec-kconfig-pax-without-grsec.patch 2008-04-30 11:39:06 UTC (rev 94) |
38007 |
@@ -0,0 +1,11 @@ |
38008 |
+--- a/security/Kconfig |
38009 |
++++ b/security/Kconfig |
38010 |
+@@ -10,7 +10,7 @@ menu "PaX" |
38011 |
+ |
38012 |
+ config PAX |
38013 |
+ bool "Enable various PaX features" |
38014 |
+- depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64) |
38015 |
++ depends on (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64) |
38016 |
+ help |
38017 |
+ This allows you to enable various PaX features. PaX adds |
38018 |
+ intrusion prevention mechanisms to the kernel that reduce |
38019 |
|
38020 |
Added: hardened-sources/2.6/tags/2.6.24-1/4445_disable-compat_vdso.patch |
38021 |
=================================================================== |
38022 |
--- hardened-sources/2.6/tags/2.6.24-1/4445_disable-compat_vdso.patch (rev 0) |
38023 |
+++ hardened-sources/2.6/tags/2.6.24-1/4445_disable-compat_vdso.patch 2008-04-30 11:39:06 UTC (rev 94) |
38024 |
@@ -0,0 +1,66 @@ |
38025 |
+From: Gordon Malm <bugs-gentoo-org-02@××××××.org> |
38026 |
+From: Kerin Millar <kerframil@×××××.com> |
38027 |
+ |
38028 |
+COMPAT_VDSO is inappropriate for any modern Hardened Gentoo system. It |
38029 |
+conflicts with various parts of PaX, crashing the system if enabled |
38030 |
+while PaX's NOEXEC or UDEREF features are active. Moreover, it prevents |
38031 |
+a number of important PaX options from appearing in the configuration |
38032 |
+menu, including all PaX NOEXEC implementations. Unfortunately, the |
38033 |
+reason for the disappearance of these PaX configuration options is |
38034 |
+often far from obvious to inexperienced users. |
38035 |
+ |
38036 |
+Therefore, we disable the COMPAT_VDSO menu entry entirely. However, |
38037 |
+COMPAT_VDSO operation can still be enabled via bootparam and sysctl |
38038 |
+interfaces. Consequently, we must also disable the ability to select |
38039 |
+COMPAT_VDSO operation at boot or runtime. Here we patch the kernel so |
38040 |
+that selecting COMPAT_VDSO operation at boot/runtime has no effect if |
38041 |
+conflicting PaX options are enabled, leaving VDSO_ENABLED operation |
38042 |
+intact. |
38043 |
+ |
38044 |
+Closes bug: http://bugs.gentoo.org/show_bug.cgi?id=210138 |
38045 |
+ |
38046 |
+--- a/arch/x86/Kconfig |
38047 |
++++ b/arch/x86/Kconfig |
38048 |
+@@ -1188,17 +1188,9 @@ config HOTPLUG_CPU |
38049 |
+ suspend. |
38050 |
+ |
38051 |
+ config COMPAT_VDSO |
38052 |
+- bool "Compat VDSO support" |
38053 |
++ bool |
38054 |
+ default n |
38055 |
+ depends on X86_32 && !PAX_NOEXEC |
38056 |
+- help |
38057 |
+- Map the VDSO to the predictable old-style address too. |
38058 |
+- ---help--- |
38059 |
+- Say N here if you are running a sufficiently recent glibc |
38060 |
+- version (2.3.3 or later), to remove the high-mapped |
38061 |
+- VDSO mapping and to exclusively use the randomized VDSO. |
38062 |
+- |
38063 |
+- If unsure, say Y. |
38064 |
+ |
38065 |
+ endmenu |
38066 |
+ |
38067 |
+--- a/arch/x86/kernel/sysenter_32.c |
38068 |
++++ b/arch/x86/kernel/sysenter_32.c |
38069 |
+@@ -278,9 +278,11 @@ int arch_setup_additional_pages(struct l |
38070 |
+ |
38071 |
+ map_compat_vdso(compat); |
38072 |
+ |
38073 |
++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF) |
38074 |
+ if (compat) |
38075 |
+ addr = VDSO_HIGH_BASE; |
38076 |
+ else { |
38077 |
++#endif |
38078 |
+ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE); |
38079 |
+ if (IS_ERR_VALUE(addr)) { |
38080 |
+ ret = addr; |
38081 |
+@@ -304,7 +306,9 @@ int arch_setup_additional_pages(struct l |
38082 |
+ |
38083 |
+ if (ret) |
38084 |
+ goto up_fail; |
38085 |
++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF) |
38086 |
+ } |
38087 |
++#endif |
38088 |
+ |
38089 |
+ current->mm->context.vdso = addr; |
38090 |
+ current_thread_info()->sysenter_return = |
38091 |
|
38092 |
Added: hardened-sources/2.6/tags/2.6.24-1/4450_grsec-2.1.11-mute-warnings.patch |
38093 |
=================================================================== |
38094 |
--- hardened-sources/2.6/tags/2.6.24-1/4450_grsec-2.1.11-mute-warnings.patch (rev 0) |
38095 |
+++ hardened-sources/2.6/tags/2.6.24-1/4450_grsec-2.1.11-mute-warnings.patch 2008-04-30 11:39:06 UTC (rev 94) |
38096 |
@@ -0,0 +1,19 @@ |
38097 |
+From: Alexander Gabert <gaberta@××××××××.de> |
38098 |
+ |
38099 |
+This patch removes the warnings introduced by grsec patch 2.1.11 and later. |
38100 |
+It removes the -W options added by the patch and restores the original |
38101 |
+warning flags of vanilla kernel versions. |
38102 |
+ |
38103 |
+Acked-by: Christian Heim <phreak@g.o> |
38104 |
+ |
38105 |
+--- a/Makefile |
38106 |
++++ b/Makefile |
38107 |
+@@ -214,7 +214,7 @@ |
38108 |
+ |
38109 |
+ HOSTCC = gcc |
38110 |
+ HOSTCXX = g++ |
38111 |
+-HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer |
38112 |
++HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer |
38113 |
+ HOSTCXXFLAGS = -O2 |
38114 |
+ |
38115 |
+ # Decide whether to build built-in, modular, or both. |
38116 |
|
38117 |
Added: hardened-sources/2.6/tags/2.6.24-1/4455_grsec-2.1.11-pax-curr_ip-fixes.patch |
38118 |
=================================================================== |
38119 |
--- hardened-sources/2.6/tags/2.6.24-1/4455_grsec-2.1.11-pax-curr_ip-fixes.patch (rev 0) |
38120 |
+++ hardened-sources/2.6/tags/2.6.24-1/4455_grsec-2.1.11-pax-curr_ip-fixes.patch 2008-04-30 11:39:06 UTC (rev 94) |
38121 |
@@ -0,0 +1,29 @@ |
38122 |
+--- a/arch/x86/mm/fault_32.c |
38123 |
++++ b/arch/x86/mm/fault_32.c |
38124 |
+@@ -730,10 +730,12 @@ |
38125 |
+ #else |
38126 |
+ else if (init_mm.start_code <= address && address < init_mm.end_code) |
38127 |
+ #endif |
38128 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
38129 |
+ if (tsk->signal->curr_ip) |
38130 |
+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", |
38131 |
+ NIPQUAD(tsk->signal->curr_ip), tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid); |
38132 |
+ else |
38133 |
++#endif |
38134 |
+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", |
38135 |
+ tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid); |
38136 |
+ #endif |
38137 |
+--- a/fs/exec.c |
38138 |
++++ b/fs/exec.c |
38139 |
+@@ -1695,9 +1695,11 @@ void pax_report_fault(struct pt_regs *re |
38140 |
+ } |
38141 |
+ up_read(&mm->mmap_sem); |
38142 |
+ } |
38143 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
38144 |
+ if (tsk->signal->curr_ip) |
38145 |
+ 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); |
38146 |
+ else |
38147 |
++#endif |
38148 |
+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset); |
38149 |
+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, " |
38150 |
+ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk), |
38151 |
|
38152 |
Added: hardened-sources/2.6/tags/2.6.24-1/4460_selinux-avc_audit-log-curr_ip.patch |
38153 |
=================================================================== |
38154 |
--- hardened-sources/2.6/tags/2.6.24-1/4460_selinux-avc_audit-log-curr_ip.patch (rev 0) |
38155 |
+++ hardened-sources/2.6/tags/2.6.24-1/4460_selinux-avc_audit-log-curr_ip.patch 2008-04-30 11:39:06 UTC (rev 94) |
38156 |
@@ -0,0 +1,25 @@ |
38157 |
+Provides support for a new field ipaddr within the SELinux |
38158 |
+AVC audit log, relying in task_struct->curr_ip (ipv4 only) |
38159 |
+provided by grSecurity patch to be applied before. |
38160 |
+ |
38161 |
+Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@×××.org> |
38162 |
+--- |
38163 |
+ |
38164 |
+ security/selinux/avc.c | 6 ++++++ |
38165 |
+ 1 file changed, 6 insertions(+) |
38166 |
+ |
38167 |
+--- a/security/selinux/avc.c |
38168 |
++++ b/security/selinux/avc.c |
38169 |
+@@ -202,6 +202,12 @@ static void avc_dump_query(struct audit_ |
38170 |
+ char *scontext; |
38171 |
+ u32 scontext_len; |
38172 |
+ |
38173 |
++/* CONFIG_PROC_IPADDR if task-signal-curr_ip patch from lorenzo@×××.org is present */ |
38174 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
38175 |
++ if (current->signal->curr_ip) |
38176 |
++ audit_log_format(ab, "ipaddr=%u.%u.%u.%u ", NIPQUAD(current->signal->curr_ip)); |
38177 |
++#endif /* CONFIG_GRKERNSEC_PROC_IPADDR */ |
38178 |
++ |
38179 |
+ rc = security_sid_to_context(ssid, &scontext, &scontext_len); |
38180 |
+ if (rc) |
38181 |
+ audit_log_format(ab, "ssid=%d", ssid); |
38182 |
|
38183 |
-- |
38184 |
gentoo-commits@l.g.o mailing list |