]> git.ipfire.org Git - ipfire-3.x.git/blob - pkgs/core/kernel/patches/grsecurity-2.1.14-2.6.31.1-200910012153.patch
kernel: glibc is not a dependency.
[ipfire-3.x.git] / pkgs / core / kernel / patches / grsecurity-2.1.14-2.6.31.1-200910012153.patch
1 diff -urNp linux-2.6.31.1/arch/alpha/include/asm/atomic.h linux-2.6.31.1/arch/alpha/include/asm/atomic.h
2 --- linux-2.6.31.1/arch/alpha/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
3 +++ linux-2.6.31.1/arch/alpha/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
4 @@ -18,9 +18,11 @@
5 #define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } )
6
7 #define atomic_read(v) ((v)->counter + 0)
8 +#define atomic_read_unchecked(v) ((v)->counter + 0)
9 #define atomic64_read(v) ((v)->counter + 0)
10
11 #define atomic_set(v,i) ((v)->counter = (i))
12 +#define atomic_set_unchecked(v,i) ((v)->counter = (i))
13 #define atomic64_set(v,i) ((v)->counter = (i))
14
15 /*
16 @@ -44,6 +46,11 @@ static __inline__ void atomic_add(int i,
17 :"Ir" (i), "m" (v->counter));
18 }
19
20 +static __inline__ void atomic_add_unchecked(int i, atomic_unchecked_t * v)
21 +{
22 + atomic_add(i, (atomic_t *)v);
23 +}
24 +
25 static __inline__ void atomic64_add(long i, atomic64_t * v)
26 {
27 unsigned long temp;
28 @@ -74,6 +81,11 @@ static __inline__ void atomic_sub(int i,
29 :"Ir" (i), "m" (v->counter));
30 }
31
32 +static __inline__ void atomic_sub_unchecked(int i, atomic_unchecked_t * v)
33 +{
34 + atomic_sub(i, (atomic_t *)v);
35 +}
36 +
37 static __inline__ void atomic64_sub(long i, atomic64_t * v)
38 {
39 unsigned long temp;
40 @@ -246,6 +258,7 @@ static __inline__ int atomic64_add_unles
41 #define atomic64_dec_and_test(v) (atomic64_sub_return(1, (v)) == 0)
42
43 #define atomic_inc(v) atomic_add(1,(v))
44 +#define atomic_inc_unchecked(v) atomic_add_unchecked(1,(v))
45 #define atomic64_inc(v) atomic64_add(1,(v))
46
47 #define atomic_dec(v) atomic_sub(1,(v))
48 diff -urNp linux-2.6.31.1/arch/alpha/include/asm/elf.h linux-2.6.31.1/arch/alpha/include/asm/elf.h
49 --- linux-2.6.31.1/arch/alpha/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400
50 +++ linux-2.6.31.1/arch/alpha/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400
51 @@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
52
53 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
54
55 +#ifdef CONFIG_PAX_ASLR
56 +#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
57 +
58 +#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
59 +#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
60 +#endif
61 +
62 /* $0 is set by ld.so to a pointer to a function which might be
63 registered using atexit. This provides a mean for the dynamic
64 linker to call DT_FINI functions for shared libraries that have
65 diff -urNp linux-2.6.31.1/arch/alpha/include/asm/pgtable.h linux-2.6.31.1/arch/alpha/include/asm/pgtable.h
66 --- linux-2.6.31.1/arch/alpha/include/asm/pgtable.h 2009-09-24 11:45:25.000000000 -0400
67 +++ linux-2.6.31.1/arch/alpha/include/asm/pgtable.h 2009-10-01 20:12:42.000000000 -0400
68 @@ -101,6 +101,17 @@ struct vm_area_struct;
69 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
70 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
71 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
72 +
73 +#ifdef CONFIG_PAX_PAGEEXEC
74 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
75 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
76 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
77 +#else
78 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
79 +# define PAGE_COPY_NOEXEC PAGE_COPY
80 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
81 +#endif
82 +
83 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
84
85 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
86 diff -urNp linux-2.6.31.1/arch/alpha/kernel/module.c linux-2.6.31.1/arch/alpha/kernel/module.c
87 --- linux-2.6.31.1/arch/alpha/kernel/module.c 2009-09-24 11:45:25.000000000 -0400
88 +++ linux-2.6.31.1/arch/alpha/kernel/module.c 2009-10-01 20:12:42.000000000 -0400
89 @@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
90
91 /* The small sections were sorted to the end of the segment.
92 The following should definitely cover them. */
93 - gp = (u64)me->module_core + me->core_size - 0x8000;
94 + gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
95 got = sechdrs[me->arch.gotsecindex].sh_addr;
96
97 for (i = 0; i < n; i++) {
98 diff -urNp linux-2.6.31.1/arch/alpha/kernel/osf_sys.c linux-2.6.31.1/arch/alpha/kernel/osf_sys.c
99 --- linux-2.6.31.1/arch/alpha/kernel/osf_sys.c 2009-09-24 11:45:25.000000000 -0400
100 +++ linux-2.6.31.1/arch/alpha/kernel/osf_sys.c 2009-10-01 20:12:42.000000000 -0400
101 @@ -1212,6 +1212,10 @@ arch_get_unmapped_area(struct file *filp
102 merely specific addresses, but regions of memory -- perhaps
103 this feature should be incorporated into all ports? */
104
105 +#ifdef CONFIG_PAX_RANDMMAP
106 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
107 +#endif
108 +
109 if (addr) {
110 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
111 if (addr != (unsigned long) -ENOMEM)
112 @@ -1219,8 +1223,8 @@ arch_get_unmapped_area(struct file *filp
113 }
114
115 /* Next, try allocating at TASK_UNMAPPED_BASE. */
116 - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
117 - len, limit);
118 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
119 +
120 if (addr != (unsigned long) -ENOMEM)
121 return addr;
122
123 diff -urNp linux-2.6.31.1/arch/alpha/mm/fault.c linux-2.6.31.1/arch/alpha/mm/fault.c
124 --- linux-2.6.31.1/arch/alpha/mm/fault.c 2009-09-24 11:45:25.000000000 -0400
125 +++ linux-2.6.31.1/arch/alpha/mm/fault.c 2009-10-01 20:12:42.000000000 -0400
126 @@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
127 __reload_thread(pcb);
128 }
129
130 +#ifdef CONFIG_PAX_PAGEEXEC
131 +/*
132 + * PaX: decide what to do with offenders (regs->pc = fault address)
133 + *
134 + * returns 1 when task should be killed
135 + * 2 when patched PLT trampoline was detected
136 + * 3 when unpatched PLT trampoline was detected
137 + */
138 +static int pax_handle_fetch_fault(struct pt_regs *regs)
139 +{
140 +
141 +#ifdef CONFIG_PAX_EMUPLT
142 + int err;
143 +
144 + do { /* PaX: patched PLT emulation #1 */
145 + unsigned int ldah, ldq, jmp;
146 +
147 + err = get_user(ldah, (unsigned int *)regs->pc);
148 + err |= get_user(ldq, (unsigned int *)(regs->pc+4));
149 + err |= get_user(jmp, (unsigned int *)(regs->pc+8));
150 +
151 + if (err)
152 + break;
153 +
154 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
155 + (ldq & 0xFFFF0000U) == 0xA77B0000U &&
156 + jmp == 0x6BFB0000U)
157 + {
158 + unsigned long r27, addr;
159 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
160 + unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
161 +
162 + addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
163 + err = get_user(r27, (unsigned long *)addr);
164 + if (err)
165 + break;
166 +
167 + regs->r27 = r27;
168 + regs->pc = r27;
169 + return 2;
170 + }
171 + } while (0);
172 +
173 + do { /* PaX: patched PLT emulation #2 */
174 + unsigned int ldah, lda, br;
175 +
176 + err = get_user(ldah, (unsigned int *)regs->pc);
177 + err |= get_user(lda, (unsigned int *)(regs->pc+4));
178 + err |= get_user(br, (unsigned int *)(regs->pc+8));
179 +
180 + if (err)
181 + break;
182 +
183 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
184 + (lda & 0xFFFF0000U) == 0xA77B0000U &&
185 + (br & 0xFFE00000U) == 0xC3E00000U)
186 + {
187 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
188 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
189 + unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
190 +
191 + regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
192 + regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
193 + return 2;
194 + }
195 + } while (0);
196 +
197 + do { /* PaX: unpatched PLT emulation */
198 + unsigned int br;
199 +
200 + err = get_user(br, (unsigned int *)regs->pc);
201 +
202 + if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
203 + unsigned int br2, ldq, nop, jmp;
204 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
205 +
206 + addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
207 + err = get_user(br2, (unsigned int *)addr);
208 + err |= get_user(ldq, (unsigned int *)(addr+4));
209 + err |= get_user(nop, (unsigned int *)(addr+8));
210 + err |= get_user(jmp, (unsigned int *)(addr+12));
211 + err |= get_user(resolver, (unsigned long *)(addr+16));
212 +
213 + if (err)
214 + break;
215 +
216 + if (br2 == 0xC3600000U &&
217 + ldq == 0xA77B000CU &&
218 + nop == 0x47FF041FU &&
219 + jmp == 0x6B7B0000U)
220 + {
221 + regs->r28 = regs->pc+4;
222 + regs->r27 = addr+16;
223 + regs->pc = resolver;
224 + return 3;
225 + }
226 + }
227 + } while (0);
228 +#endif
229 +
230 + return 1;
231 +}
232 +
233 +void pax_report_insns(void *pc, void *sp)
234 +{
235 + unsigned long i;
236 +
237 + printk(KERN_ERR "PAX: bytes at PC: ");
238 + for (i = 0; i < 5; i++) {
239 + unsigned int c;
240 + if (get_user(c, (unsigned int *)pc+i))
241 + printk(KERN_CONT "???????? ");
242 + else
243 + printk(KERN_CONT "%08x ", c);
244 + }
245 + printk("\n");
246 +}
247 +#endif
248
249 /*
250 * This routine handles page faults. It determines the address,
251 @@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
252 good_area:
253 si_code = SEGV_ACCERR;
254 if (cause < 0) {
255 - if (!(vma->vm_flags & VM_EXEC))
256 + if (!(vma->vm_flags & VM_EXEC)) {
257 +
258 +#ifdef CONFIG_PAX_PAGEEXEC
259 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
260 + goto bad_area;
261 +
262 + up_read(&mm->mmap_sem);
263 + switch (pax_handle_fetch_fault(regs)) {
264 +
265 +#ifdef CONFIG_PAX_EMUPLT
266 + case 2:
267 + case 3:
268 + return;
269 +#endif
270 +
271 + }
272 + pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
273 + do_group_exit(SIGKILL);
274 +#else
275 goto bad_area;
276 +#endif
277 +
278 + }
279 } else if (!cause) {
280 /* Allow reads even for write-only mappings */
281 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
282 diff -urNp linux-2.6.31.1/arch/arm/include/asm/atomic.h linux-2.6.31.1/arch/arm/include/asm/atomic.h
283 --- linux-2.6.31.1/arch/arm/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
284 +++ linux-2.6.31.1/arch/arm/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
285 @@ -20,6 +20,7 @@
286 #ifdef __KERNEL__
287
288 #define atomic_read(v) ((v)->counter)
289 +#define atomic_read_unchecked(v) ((v)->counter)
290
291 #if __LINUX_ARM_ARCH__ >= 6
292
293 @@ -44,6 +45,11 @@ static inline void atomic_set(atomic_t *
294 : "cc");
295 }
296
297 +static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
298 +{
299 + atomic_set((atomic_t *)v, i);
300 +}
301 +
302 static inline void atomic_add(int i, atomic_t *v)
303 {
304 unsigned long tmp;
305 @@ -60,6 +66,11 @@ static inline void atomic_add(int i, ato
306 : "cc");
307 }
308
309 +static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
310 +{
311 + atomic_add(i, (atomic_t *)v);
312 +}
313 +
314 static inline int atomic_add_return(int i, atomic_t *v)
315 {
316 unsigned long tmp;
317 @@ -98,6 +109,11 @@ static inline void atomic_sub(int i, ato
318 : "cc");
319 }
320
321 +static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
322 +{
323 + atomic_sub(i, (atomic_t *)v);
324 +}
325 +
326 static inline int atomic_sub_return(int i, atomic_t *v)
327 {
328 unsigned long tmp;
329 @@ -164,6 +180,7 @@ static inline void atomic_clear_mask(uns
330 #endif
331
332 #define atomic_set(v,i) (((v)->counter) = (i))
333 +#define atomic_set_unchecked(v,i) (((v)->counter) = (i))
334
335 static inline int atomic_add_return(int i, atomic_t *v)
336 {
337 @@ -232,6 +249,7 @@ static inline int atomic_add_unless(atom
338 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
339
340 #define atomic_inc(v) atomic_add(1, v)
341 +#define atomic_inc_unchecked(v) atomic_add_unchecked(1, v)
342 #define atomic_dec(v) atomic_sub(1, v)
343
344 #define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
345 diff -urNp linux-2.6.31.1/arch/arm/include/asm/elf.h linux-2.6.31.1/arch/arm/include/asm/elf.h
346 --- linux-2.6.31.1/arch/arm/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400
347 +++ linux-2.6.31.1/arch/arm/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400
348 @@ -103,7 +103,14 @@ extern int arm_elf_read_implies_exec(con
349 the loader. We need to make sure that it is out of the way of the program
350 that it will "exec", and that there is sufficient room for the brk. */
351
352 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
353 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
354 +
355 +#ifdef CONFIG_PAX_ASLR
356 +#define PAX_ELF_ET_DYN_BASE 0x00008000UL
357 +
358 +#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
359 +#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
360 +#endif
361
362 /* When the program starts, a1 contains a pointer to a function to be
363 registered with atexit, as per the SVR4 ABI. A value of 0 means we
364 diff -urNp linux-2.6.31.1/arch/arm/include/asm/kmap_types.h linux-2.6.31.1/arch/arm/include/asm/kmap_types.h
365 --- linux-2.6.31.1/arch/arm/include/asm/kmap_types.h 2009-09-24 11:45:25.000000000 -0400
366 +++ linux-2.6.31.1/arch/arm/include/asm/kmap_types.h 2009-10-01 20:12:42.000000000 -0400
367 @@ -19,6 +19,7 @@ enum km_type {
368 KM_SOFTIRQ0,
369 KM_SOFTIRQ1,
370 KM_L2_CACHE,
371 + KM_CLEARPAGE,
372 KM_TYPE_NR
373 };
374
375 diff -urNp linux-2.6.31.1/arch/arm/include/asm/uaccess.h linux-2.6.31.1/arch/arm/include/asm/uaccess.h
376 --- linux-2.6.31.1/arch/arm/include/asm/uaccess.h 2009-09-24 11:45:25.000000000 -0400
377 +++ linux-2.6.31.1/arch/arm/include/asm/uaccess.h 2009-10-01 20:12:42.000000000 -0400
378 @@ -400,6 +400,9 @@ extern unsigned long __must_check __strn
379
380 static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
381 {
382 + if ((long)n < 0)
383 + return n;
384 +
385 if (access_ok(VERIFY_READ, from, n))
386 n = __copy_from_user(to, from, n);
387 else /* security hole - plug it */
388 @@ -409,6 +412,9 @@ static inline unsigned long __must_check
389
390 static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
391 {
392 + if ((long)n < 0)
393 + return n;
394 +
395 if (access_ok(VERIFY_WRITE, to, n))
396 n = __copy_to_user(to, from, n);
397 return n;
398 diff -urNp linux-2.6.31.1/arch/arm/mach-ns9xxx/clock.c linux-2.6.31.1/arch/arm/mach-ns9xxx/clock.c
399 --- linux-2.6.31.1/arch/arm/mach-ns9xxx/clock.c 2009-09-24 11:45:25.000000000 -0400
400 +++ linux-2.6.31.1/arch/arm/mach-ns9xxx/clock.c 2009-10-01 20:12:42.000000000 -0400
401 @@ -195,7 +195,7 @@ static int clk_debugfs_open(struct inode
402 return single_open(file, clk_debugfs_show, NULL);
403 }
404
405 -static struct file_operations clk_debugfs_operations = {
406 +static const struct file_operations clk_debugfs_operations = {
407 .open = clk_debugfs_open,
408 .read = seq_read,
409 .llseek = seq_lseek,
410 diff -urNp linux-2.6.31.1/arch/arm/mm/mmap.c linux-2.6.31.1/arch/arm/mm/mmap.c
411 --- linux-2.6.31.1/arch/arm/mm/mmap.c 2009-09-24 11:45:25.000000000 -0400
412 +++ linux-2.6.31.1/arch/arm/mm/mmap.c 2009-10-01 20:12:42.000000000 -0400
413 @@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
414 if (len > TASK_SIZE)
415 return -ENOMEM;
416
417 +#ifdef CONFIG_PAX_RANDMMAP
418 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
419 +#endif
420 +
421 if (addr) {
422 if (do_align)
423 addr = COLOUR_ALIGN(addr, pgoff);
424 @@ -74,10 +78,10 @@ arch_get_unmapped_area(struct file *filp
425 return addr;
426 }
427 if (len > mm->cached_hole_size) {
428 - start_addr = addr = mm->free_area_cache;
429 + start_addr = addr = mm->free_area_cache;
430 } else {
431 - start_addr = addr = TASK_UNMAPPED_BASE;
432 - mm->cached_hole_size = 0;
433 + start_addr = addr = mm->mmap_base;
434 + mm->cached_hole_size = 0;
435 }
436
437 full_search:
438 @@ -93,8 +97,8 @@ full_search:
439 * Start a new search - just in case we missed
440 * some holes.
441 */
442 - if (start_addr != TASK_UNMAPPED_BASE) {
443 - start_addr = addr = TASK_UNMAPPED_BASE;
444 + if (start_addr != mm->mmap_base) {
445 + start_addr = addr = mm->mmap_base;
446 mm->cached_hole_size = 0;
447 goto full_search;
448 }
449 diff -urNp linux-2.6.31.1/arch/avr32/include/asm/atomic.h linux-2.6.31.1/arch/avr32/include/asm/atomic.h
450 --- linux-2.6.31.1/arch/avr32/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
451 +++ linux-2.6.31.1/arch/avr32/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
452 @@ -20,7 +20,9 @@
453 #define ATOMIC_INIT(i) { (i) }
454
455 #define atomic_read(v) ((v)->counter)
456 +#define atomic_read_unchecked(v) ((v)->counter)
457 #define atomic_set(v, i) (((v)->counter) = i)
458 +#define atomic_set_unchecked(v, i) (((v)->counter) = i)
459
460 /*
461 * atomic_sub_return - subtract the atomic variable
462 @@ -48,6 +50,18 @@ static inline int atomic_sub_return(int
463 }
464
465 /*
466 + * atomic_sub_return_unchecked - subtract the atomic variable
467 + * @i: integer value to subtract
468 + * @v: pointer of type atomic_unchecked_t
469 + *
470 + * Atomically subtracts @i from @v. Returns the resulting value.
471 + */
472 +static inline int atomic_sub_return_unchecked(int i, atomic_unchecked_t *v)
473 +{
474 + return atomic_sub_return(i, (atomic_t *)v);
475 +}
476 +
477 +/*
478 * atomic_add_return - add integer to atomic variable
479 * @i: integer value to add
480 * @v: pointer of type atomic_t
481 @@ -76,6 +90,18 @@ static inline int atomic_add_return(int
482 }
483
484 /*
485 + * atomic_add_return_unchecked - add integer to atomic variable
486 + * @i: integer value to add
487 + * @v: pointer of type atomic_unchecked_t
488 + *
489 + * Atomically adds @i to @v. Returns the resulting value.
490 + */
491 +static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
492 +{
493 + return atomic_add_return(i, (atomic_t *)v);
494 +}
495 +
496 +/*
497 * atomic_sub_unless - sub unless the number is a given value
498 * @v: pointer of type atomic_t
499 * @a: the amount to add to v...
500 @@ -176,9 +202,12 @@ static inline int atomic_sub_if_positive
501 #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
502
503 #define atomic_sub(i, v) (void)atomic_sub_return(i, v)
504 +#define atomic_sub_unchecked(i, v) (void)atomic_sub_return_unchecked(i, v)
505 #define atomic_add(i, v) (void)atomic_add_return(i, v)
506 +#define atomic_add_unchecked(i, v) (void)atomic_add_return_unchecked(i, v)
507 #define atomic_dec(v) atomic_sub(1, (v))
508 #define atomic_inc(v) atomic_add(1, (v))
509 +#define atomic_inc_unchecked(v) (void)atomic_add_return_unchecked(1, (v))
510
511 #define atomic_dec_return(v) atomic_sub_return(1, v)
512 #define atomic_inc_return(v) atomic_add_return(1, v)
513 diff -urNp linux-2.6.31.1/arch/avr32/include/asm/elf.h linux-2.6.31.1/arch/avr32/include/asm/elf.h
514 --- linux-2.6.31.1/arch/avr32/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400
515 +++ linux-2.6.31.1/arch/avr32/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400
516 @@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
517 the loader. We need to make sure that it is out of the way of the program
518 that it will "exec", and that there is sufficient room for the brk. */
519
520 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
521 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
522
523 +#ifdef CONFIG_PAX_ASLR
524 +#define PAX_ELF_ET_DYN_BASE 0x00001000UL
525 +
526 +#define PAX_DELTA_MMAP_LEN 15
527 +#define PAX_DELTA_STACK_LEN 15
528 +#endif
529
530 /* This yields a mask that user programs can use to figure out what
531 instruction set this CPU supports. This could be done in user space,
532 diff -urNp linux-2.6.31.1/arch/avr32/include/asm/kmap_types.h linux-2.6.31.1/arch/avr32/include/asm/kmap_types.h
533 --- linux-2.6.31.1/arch/avr32/include/asm/kmap_types.h 2009-09-24 11:45:25.000000000 -0400
534 +++ linux-2.6.31.1/arch/avr32/include/asm/kmap_types.h 2009-10-01 20:12:42.000000000 -0400
535 @@ -22,7 +22,8 @@ D(10) KM_IRQ0,
536 D(11) KM_IRQ1,
537 D(12) KM_SOFTIRQ0,
538 D(13) KM_SOFTIRQ1,
539 -D(14) KM_TYPE_NR
540 +D(14) KM_CLEARPAGE,
541 +D(15) KM_TYPE_NR
542 };
543
544 #undef D
545 diff -urNp linux-2.6.31.1/arch/avr32/mm/fault.c linux-2.6.31.1/arch/avr32/mm/fault.c
546 --- linux-2.6.31.1/arch/avr32/mm/fault.c 2009-09-24 11:45:25.000000000 -0400
547 +++ linux-2.6.31.1/arch/avr32/mm/fault.c 2009-10-01 20:12:42.000000000 -0400
548 @@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
549
550 int exception_trace = 1;
551
552 +#ifdef CONFIG_PAX_PAGEEXEC
553 +void pax_report_insns(void *pc, void *sp)
554 +{
555 + unsigned long i;
556 +
557 + printk(KERN_ERR "PAX: bytes at PC: ");
558 + for (i = 0; i < 20; i++) {
559 + unsigned char c;
560 + if (get_user(c, (unsigned char *)pc+i))
561 + printk(KERN_CONT "???????? ");
562 + else
563 + printk(KERN_CONT "%02x ", c);
564 + }
565 + printk("\n");
566 +}
567 +#endif
568 +
569 /*
570 * This routine handles page faults. It determines the address and the
571 * problem, and then passes it off to one of the appropriate routines.
572 @@ -157,6 +174,16 @@ bad_area:
573 up_read(&mm->mmap_sem);
574
575 if (user_mode(regs)) {
576 +
577 +#ifdef CONFIG_PAX_PAGEEXEC
578 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
579 + if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
580 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
581 + do_group_exit(SIGKILL);
582 + }
583 + }
584 +#endif
585 +
586 if (exception_trace && printk_ratelimit())
587 printk("%s%s[%d]: segfault at %08lx pc %08lx "
588 "sp %08lx ecr %lu\n",
589 diff -urNp linux-2.6.31.1/arch/blackfin/include/asm/atomic.h linux-2.6.31.1/arch/blackfin/include/asm/atomic.h
590 --- linux-2.6.31.1/arch/blackfin/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
591 +++ linux-2.6.31.1/arch/blackfin/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
592 @@ -15,8 +15,10 @@
593
594 #define ATOMIC_INIT(i) { (i) }
595 #define atomic_set(v, i) (((v)->counter) = i)
596 +#define atomic_set_unchecked(v, i) (((v)->counter) = i)
597
598 #define atomic_read(v) __raw_uncached_fetch_asm(&(v)->counter)
599 +#define atomic_read_unchecked(v) __raw_uncached_fetch_asm(&(v)->counter)
600
601 asmlinkage int __raw_uncached_fetch_asm(const volatile int *ptr);
602
603 @@ -35,11 +37,21 @@ static inline void atomic_add(int i, ato
604 __raw_atomic_update_asm(&v->counter, i);
605 }
606
607 +static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
608 +{
609 + atomic_add(i, (atomic_t *)v);
610 +}
611 +
612 static inline void atomic_sub(int i, atomic_t *v)
613 {
614 __raw_atomic_update_asm(&v->counter, -i);
615 }
616
617 +static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
618 +{
619 + atomic_sub(i, (atomic_t *)v);
620 +}
621 +
622 static inline int atomic_add_return(int i, atomic_t *v)
623 {
624 return __raw_atomic_update_asm(&v->counter, i);
625 @@ -55,6 +67,11 @@ static inline void atomic_inc(volatile a
626 __raw_atomic_update_asm(&v->counter, 1);
627 }
628
629 +static inline void atomic_inc_unchecked(volatile atomic_unchecked_t *v)
630 +{
631 + atomic_inc((atomic_t *)v);
632 +}
633 +
634 static inline void atomic_dec(volatile atomic_t *v)
635 {
636 __raw_atomic_update_asm(&v->counter, -1);
637 diff -urNp linux-2.6.31.1/arch/blackfin/mach-bf561/coreb.c linux-2.6.31.1/arch/blackfin/mach-bf561/coreb.c
638 --- linux-2.6.31.1/arch/blackfin/mach-bf561/coreb.c 2009-09-24 11:45:25.000000000 -0400
639 +++ linux-2.6.31.1/arch/blackfin/mach-bf561/coreb.c 2009-10-01 20:12:42.000000000 -0400
640 @@ -48,7 +48,7 @@ coreb_ioctl(struct inode *inode, struct
641 return ret;
642 }
643
644 -static struct file_operations coreb_fops = {
645 +static const struct file_operations coreb_fops = {
646 .owner = THIS_MODULE,
647 .ioctl = coreb_ioctl,
648 };
649 diff -urNp linux-2.6.31.1/arch/cris/arch-v10/drivers/sync_serial.c linux-2.6.31.1/arch/cris/arch-v10/drivers/sync_serial.c
650 --- linux-2.6.31.1/arch/cris/arch-v10/drivers/sync_serial.c 2009-09-24 11:45:25.000000000 -0400
651 +++ linux-2.6.31.1/arch/cris/arch-v10/drivers/sync_serial.c 2009-10-01 20:12:42.000000000 -0400
652 @@ -244,7 +244,7 @@ static unsigned sync_serial_prescale_sha
653
654 #define NUMBER_OF_PORTS 2
655
656 -static struct file_operations sync_serial_fops = {
657 +static const struct file_operations sync_serial_fops = {
658 .owner = THIS_MODULE,
659 .write = sync_serial_write,
660 .read = sync_serial_read,
661 diff -urNp linux-2.6.31.1/arch/cris/arch-v32/drivers/mach-fs/gpio.c linux-2.6.31.1/arch/cris/arch-v32/drivers/mach-fs/gpio.c
662 --- linux-2.6.31.1/arch/cris/arch-v32/drivers/mach-fs/gpio.c 2009-09-24 11:45:25.000000000 -0400
663 +++ linux-2.6.31.1/arch/cris/arch-v32/drivers/mach-fs/gpio.c 2009-10-01 20:12:42.000000000 -0400
664 @@ -855,7 +855,7 @@ gpio_leds_ioctl(unsigned int cmd, unsign
665 return 0;
666 }
667
668 -struct file_operations gpio_fops = {
669 +struct struct file_operations gpio_fops = {
670 .owner = THIS_MODULE,
671 .poll = gpio_poll,
672 .ioctl = gpio_ioctl,
673 diff -urNp linux-2.6.31.1/arch/cris/include/asm/atomic.h linux-2.6.31.1/arch/cris/include/asm/atomic.h
674 --- linux-2.6.31.1/arch/cris/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
675 +++ linux-2.6.31.1/arch/cris/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
676 @@ -16,7 +16,9 @@
677 #define ATOMIC_INIT(i) { (i) }
678
679 #define atomic_read(v) ((v)->counter)
680 +#define atomic_read_unchecked(v) ((v)->counter)
681 #define atomic_set(v,i) (((v)->counter) = (i))
682 +#define atomic_set_unchecked(v,i) (((v)->counter) = (i))
683
684 /* These should be written in asm but we do it in C for now. */
685
686 @@ -28,6 +30,11 @@ static inline void atomic_add(int i, vol
687 cris_atomic_restore(v, flags);
688 }
689
690 +static inline void atomic_add_unchecked(int i, volatile atomic_unchecked_t *v)
691 +{
692 + atomic_add(i, (volatile atomic_t *)v);
693 +}
694 +
695 static inline void atomic_sub(int i, volatile atomic_t *v)
696 {
697 unsigned long flags;
698 @@ -36,6 +43,11 @@ static inline void atomic_sub(int i, vol
699 cris_atomic_restore(v, flags);
700 }
701
702 +static inline void atomic_sub_unchecked(int i, volatile atomic_unchecked_t *v)
703 +{
704 + atomic_sub(i, (volatile atomic_t *)v);
705 +}
706 +
707 static inline int atomic_add_return(int i, volatile atomic_t *v)
708 {
709 unsigned long flags;
710 @@ -76,6 +88,11 @@ static inline void atomic_inc(volatile a
711 cris_atomic_restore(v, flags);
712 }
713
714 +static inline void atomic_inc_unchecked(volatile atomic_unchecked_t *v)
715 +{
716 + atomic_inc((volatile atomic_t *)v);
717 +}
718 +
719 static inline void atomic_dec(volatile atomic_t *v)
720 {
721 unsigned long flags;
722 diff -urNp linux-2.6.31.1/arch/frv/include/asm/atomic.h linux-2.6.31.1/arch/frv/include/asm/atomic.h
723 --- linux-2.6.31.1/arch/frv/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
724 +++ linux-2.6.31.1/arch/frv/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
725 @@ -37,7 +37,9 @@
726
727 #define ATOMIC_INIT(i) { (i) }
728 #define atomic_read(v) ((v)->counter)
729 +#define atomic_read_unchecked(v) ((v)->counter)
730 #define atomic_set(v, i) (((v)->counter) = (i))
731 +#define atomic_set_unchecked(v, i) (((v)->counter) = (i))
732
733 #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
734 static inline int atomic_add_return(int i, atomic_t *v)
735 @@ -99,16 +101,31 @@ static inline void atomic_add(int i, ato
736 atomic_add_return(i, v);
737 }
738
739 +static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
740 +{
741 + atomic_add_return(i, (atomic_t *)v);
742 +}
743 +
744 static inline void atomic_sub(int i, atomic_t *v)
745 {
746 atomic_sub_return(i, v);
747 }
748
749 +static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
750 +{
751 + atomic_sub_return(i, (atomic_t *)v);
752 +}
753 +
754 static inline void atomic_inc(atomic_t *v)
755 {
756 atomic_add_return(1, v);
757 }
758
759 +static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
760 +{
761 + atomic_add_return(1, (atomic_t *)v);
762 +}
763 +
764 static inline void atomic_dec(atomic_t *v)
765 {
766 atomic_sub_return(1, v);
767 diff -urNp linux-2.6.31.1/arch/frv/include/asm/kmap_types.h linux-2.6.31.1/arch/frv/include/asm/kmap_types.h
768 --- linux-2.6.31.1/arch/frv/include/asm/kmap_types.h 2009-09-24 11:45:25.000000000 -0400
769 +++ linux-2.6.31.1/arch/frv/include/asm/kmap_types.h 2009-10-01 20:12:42.000000000 -0400
770 @@ -23,6 +23,7 @@ enum km_type {
771 KM_IRQ1,
772 KM_SOFTIRQ0,
773 KM_SOFTIRQ1,
774 + KM_CLEARPAGE,
775 KM_TYPE_NR
776 };
777
778 diff -urNp linux-2.6.31.1/arch/h8300/include/asm/atomic.h linux-2.6.31.1/arch/h8300/include/asm/atomic.h
779 --- linux-2.6.31.1/arch/h8300/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
780 +++ linux-2.6.31.1/arch/h8300/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
781 @@ -11,7 +11,9 @@
782 #define ATOMIC_INIT(i) { (i) }
783
784 #define atomic_read(v) ((v)->counter)
785 +#define atomic_read_unchecked(v) ((v)->counter)
786 #define atomic_set(v, i) (((v)->counter) = i)
787 +#define atomic_set_unchecked(v, i) (((v)->counter) = i)
788
789 #include <asm/system.h>
790 #include <linux/kernel.h>
791 @@ -25,7 +27,13 @@ static __inline__ int atomic_add_return(
792 return ret;
793 }
794
795 +static __inline__ int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
796 +{
797 + return atomic_add_return(i, (atomic_t *)v);
798 +}
799 +
800 #define atomic_add(i, v) atomic_add_return(i, v)
801 +#define atomic_add_unchecked(i, v) atomic_add_return_unchecked(i, v)
802 #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
803
804 static __inline__ int atomic_sub_return(int i, atomic_t *v)
805 @@ -37,7 +45,13 @@ static __inline__ int atomic_sub_return(
806 return ret;
807 }
808
809 +static __inline__ int atomic_sub_return_unchecked(int i, atomic_unchecked_t *v)
810 +{
811 + return atomic_sub_return(i, (atomic_t *)v);
812 +}
813 +
814 #define atomic_sub(i, v) atomic_sub_return(i, v)
815 +#define atomic_sub_unchecked(i, v) atomic_sub_return_unchecked(i, v)
816 #define atomic_sub_and_test(i,v) (atomic_sub_return(i, v) == 0)
817
818 static __inline__ int atomic_inc_return(atomic_t *v)
819 @@ -50,7 +64,13 @@ static __inline__ int atomic_inc_return(
820 return ret;
821 }
822
823 +static __inline__ int atomic_inc_return_unchecked(atomic_unchecked_t *v)
824 +{
825 + return atomic_inc_return((atomic_t *)v);
826 +}
827 +
828 #define atomic_inc(v) atomic_inc_return(v)
829 +#define atomic_inc_unchecked(v) atomic_inc_return_unchecked(v)
830
831 /*
832 * atomic_inc_and_test - increment and test
833 diff -urNp linux-2.6.31.1/arch/ia64/ia32/binfmt_elf32.c linux-2.6.31.1/arch/ia64/ia32/binfmt_elf32.c
834 --- linux-2.6.31.1/arch/ia64/ia32/binfmt_elf32.c 2009-09-24 11:45:25.000000000 -0400
835 +++ linux-2.6.31.1/arch/ia64/ia32/binfmt_elf32.c 2009-10-01 20:12:42.000000000 -0400
836 @@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
837
838 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
839
840 +#ifdef CONFIG_PAX_ASLR
841 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
842 +
843 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
844 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
845 +#endif
846 +
847 /* Ugly but avoids duplication */
848 #include "../../../fs/binfmt_elf.c"
849
850 @@ -69,11 +76,11 @@ ia32_install_gate_page (struct vm_area_s
851 }
852
853
854 -static struct vm_operations_struct ia32_shared_page_vm_ops = {
855 +static const struct vm_operations_struct ia32_shared_page_vm_ops = {
856 .fault = ia32_install_shared_page
857 };
858
859 -static struct vm_operations_struct ia32_gate_page_vm_ops = {
860 +static const struct vm_operations_struct ia32_gate_page_vm_ops = {
861 .fault = ia32_install_gate_page
862 };
863
864 diff -urNp linux-2.6.31.1/arch/ia64/ia32/ia32priv.h linux-2.6.31.1/arch/ia64/ia32/ia32priv.h
865 --- linux-2.6.31.1/arch/ia64/ia32/ia32priv.h 2009-09-24 11:45:25.000000000 -0400
866 +++ linux-2.6.31.1/arch/ia64/ia32/ia32priv.h 2009-10-01 20:12:42.000000000 -0400
867 @@ -296,7 +296,14 @@ typedef struct compat_siginfo {
868 #define ELF_DATA ELFDATA2LSB
869 #define ELF_ARCH EM_386
870
871 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
872 +#ifdef CONFIG_PAX_RANDUSTACK
873 +#define __IA32_DELTA_STACK (current->mm->delta_stack)
874 +#else
875 +#define __IA32_DELTA_STACK 0UL
876 +#endif
877 +
878 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
879 +
880 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
881 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
882
883 diff -urNp linux-2.6.31.1/arch/ia64/include/asm/atomic.h linux-2.6.31.1/arch/ia64/include/asm/atomic.h
884 --- linux-2.6.31.1/arch/ia64/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
885 +++ linux-2.6.31.1/arch/ia64/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
886 @@ -22,9 +22,11 @@
887 #define ATOMIC64_INIT(i) ((atomic64_t) { (i) })
888
889 #define atomic_read(v) ((v)->counter)
890 +#define atomic_read_unchecked(v) ((v)->counter)
891 #define atomic64_read(v) ((v)->counter)
892
893 #define atomic_set(v,i) (((v)->counter) = (i))
894 +#define atomic_set_unchecked(v,i) (((v)->counter) = (i))
895 #define atomic64_set(v,i) (((v)->counter) = (i))
896
897 static __inline__ int
898 @@ -201,8 +203,11 @@ atomic64_add_negative (__s64 i, atomic64
899 #define atomic64_inc_and_test(v) (atomic64_add_return(1, (v)) == 0)
900
901 #define atomic_add(i,v) atomic_add_return((i), (v))
902 +#define atomic_add_unchecked(i,v) atomic_add((i), (atomic_t *)(v))
903 #define atomic_sub(i,v) atomic_sub_return((i), (v))
904 +#define atomic_sub_unchecked(i,v) atomic_sub((i), (atomic_t *)(v))
905 #define atomic_inc(v) atomic_add(1, (v))
906 +#define atomic_inc_unchecked(v) atomic_inc((atomic_t *)(v))
907 #define atomic_dec(v) atomic_sub(1, (v))
908
909 #define atomic64_add(i,v) atomic64_add_return((i), (v))
910 diff -urNp linux-2.6.31.1/arch/ia64/include/asm/elf.h linux-2.6.31.1/arch/ia64/include/asm/elf.h
911 --- linux-2.6.31.1/arch/ia64/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400
912 +++ linux-2.6.31.1/arch/ia64/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400
913 @@ -43,6 +43,13 @@
914 */
915 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
916
917 +#ifdef CONFIG_PAX_ASLR
918 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
919 +
920 +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
921 +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
922 +#endif
923 +
924 #define PT_IA_64_UNWIND 0x70000001
925
926 /* IA-64 relocations: */
927 diff -urNp linux-2.6.31.1/arch/ia64/include/asm/pgtable.h linux-2.6.31.1/arch/ia64/include/asm/pgtable.h
928 --- linux-2.6.31.1/arch/ia64/include/asm/pgtable.h 2009-09-24 11:45:25.000000000 -0400
929 +++ linux-2.6.31.1/arch/ia64/include/asm/pgtable.h 2009-10-01 20:12:42.000000000 -0400
930 @@ -143,6 +143,17 @@
931 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
932 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
933 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
934 +
935 +#ifdef CONFIG_PAX_PAGEEXEC
936 +# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
937 +# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
938 +# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
939 +#else
940 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
941 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
942 +# define PAGE_COPY_NOEXEC PAGE_COPY
943 +#endif
944 +
945 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
946 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
947 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
948 diff -urNp linux-2.6.31.1/arch/ia64/include/asm/uaccess.h linux-2.6.31.1/arch/ia64/include/asm/uaccess.h
949 --- linux-2.6.31.1/arch/ia64/include/asm/uaccess.h 2009-09-24 11:45:25.000000000 -0400
950 +++ linux-2.6.31.1/arch/ia64/include/asm/uaccess.h 2009-10-01 20:12:42.000000000 -0400
951 @@ -257,7 +257,7 @@ __copy_from_user (void *to, const void _
952 const void *__cu_from = (from); \
953 long __cu_len = (n); \
954 \
955 - if (__access_ok(__cu_to, __cu_len, get_fs())) \
956 + if (__cu_len > 0 && __cu_len <= INT_MAX && __access_ok(__cu_to, __cu_len, get_fs())) \
957 __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \
958 __cu_len; \
959 })
960 @@ -269,7 +269,7 @@ __copy_from_user (void *to, const void _
961 long __cu_len = (n); \
962 \
963 __chk_user_ptr(__cu_from); \
964 - if (__access_ok(__cu_from, __cu_len, get_fs())) \
965 + if (__cu_len > 0 && __cu_len <= INT_MAX && __access_ok(__cu_from, __cu_len, get_fs())) \
966 __cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len); \
967 __cu_len; \
968 })
969 diff -urNp linux-2.6.31.1/arch/ia64/kernel/module.c linux-2.6.31.1/arch/ia64/kernel/module.c
970 --- linux-2.6.31.1/arch/ia64/kernel/module.c 2009-09-24 11:45:25.000000000 -0400
971 +++ linux-2.6.31.1/arch/ia64/kernel/module.c 2009-10-01 20:12:42.000000000 -0400
972 @@ -315,8 +315,7 @@ module_alloc (unsigned long size)
973 void
974 module_free (struct module *mod, void *module_region)
975 {
976 - if (mod && mod->arch.init_unw_table &&
977 - module_region == mod->module_init) {
978 + if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
979 unw_remove_unwind_table(mod->arch.init_unw_table);
980 mod->arch.init_unw_table = NULL;
981 }
982 @@ -502,15 +501,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
983 }
984
985 static inline int
986 +in_init_rx (const struct module *mod, uint64_t addr)
987 +{
988 + return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
989 +}
990 +
991 +static inline int
992 +in_init_rw (const struct module *mod, uint64_t addr)
993 +{
994 + return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
995 +}
996 +
997 +static inline int
998 in_init (const struct module *mod, uint64_t addr)
999 {
1000 - return addr - (uint64_t) mod->module_init < mod->init_size;
1001 + return in_init_rx(mod, addr) || in_init_rw(mod, addr);
1002 +}
1003 +
1004 +static inline int
1005 +in_core_rx (const struct module *mod, uint64_t addr)
1006 +{
1007 + return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
1008 +}
1009 +
1010 +static inline int
1011 +in_core_rw (const struct module *mod, uint64_t addr)
1012 +{
1013 + return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
1014 }
1015
1016 static inline int
1017 in_core (const struct module *mod, uint64_t addr)
1018 {
1019 - return addr - (uint64_t) mod->module_core < mod->core_size;
1020 + return in_core_rx(mod, addr) || in_core_rw(mod, addr);
1021 }
1022
1023 static inline int
1024 @@ -693,7 +716,14 @@ do_reloc (struct module *mod, uint8_t r_
1025 break;
1026
1027 case RV_BDREL:
1028 - val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
1029 + if (in_init_rx(mod, val))
1030 + val -= (uint64_t) mod->module_init_rx;
1031 + else if (in_init_rw(mod, val))
1032 + val -= (uint64_t) mod->module_init_rw;
1033 + else if (in_core_rx(mod, val))
1034 + val -= (uint64_t) mod->module_core_rx;
1035 + else if (in_core_rw(mod, val))
1036 + val -= (uint64_t) mod->module_core_rw;
1037 break;
1038
1039 case RV_LTV:
1040 @@ -828,15 +858,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
1041 * addresses have been selected...
1042 */
1043 uint64_t gp;
1044 - if (mod->core_size > MAX_LTOFF)
1045 + if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
1046 /*
1047 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
1048 * at the end of the module.
1049 */
1050 - gp = mod->core_size - MAX_LTOFF / 2;
1051 + gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
1052 else
1053 - gp = mod->core_size / 2;
1054 - gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
1055 + gp = (mod->core_size_rx + mod->core_size_rw) / 2;
1056 + gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
1057 mod->arch.gp = gp;
1058 DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
1059 }
1060 diff -urNp linux-2.6.31.1/arch/ia64/kernel/sys_ia64.c linux-2.6.31.1/arch/ia64/kernel/sys_ia64.c
1061 --- linux-2.6.31.1/arch/ia64/kernel/sys_ia64.c 2009-09-24 11:45:25.000000000 -0400
1062 +++ linux-2.6.31.1/arch/ia64/kernel/sys_ia64.c 2009-10-01 20:12:42.000000000 -0400
1063 @@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
1064 if (REGION_NUMBER(addr) == RGN_HPAGE)
1065 addr = 0;
1066 #endif
1067 +
1068 +#ifdef CONFIG_PAX_RANDMMAP
1069 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1070 + addr = mm->free_area_cache;
1071 + else
1072 +#endif
1073 +
1074 if (!addr)
1075 addr = mm->free_area_cache;
1076
1077 @@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
1078 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
1079 /* At this point: (!vma || addr < vma->vm_end). */
1080 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
1081 - if (start_addr != TASK_UNMAPPED_BASE) {
1082 + if (start_addr != mm->mmap_base) {
1083 /* Start a new search --- just in case we missed some holes. */
1084 - addr = TASK_UNMAPPED_BASE;
1085 + addr = mm->mmap_base;
1086 goto full_search;
1087 }
1088 return -ENOMEM;
1089 diff -urNp linux-2.6.31.1/arch/ia64/mm/fault.c linux-2.6.31.1/arch/ia64/mm/fault.c
1090 --- linux-2.6.31.1/arch/ia64/mm/fault.c 2009-09-24 11:45:25.000000000 -0400
1091 +++ linux-2.6.31.1/arch/ia64/mm/fault.c 2009-10-01 20:12:42.000000000 -0400
1092 @@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
1093 return pte_present(pte);
1094 }
1095
1096 +#ifdef CONFIG_PAX_PAGEEXEC
1097 +void pax_report_insns(void *pc, void *sp)
1098 +{
1099 + unsigned long i;
1100 +
1101 + printk(KERN_ERR "PAX: bytes at PC: ");
1102 + for (i = 0; i < 8; i++) {
1103 + unsigned int c;
1104 + if (get_user(c, (unsigned int *)pc+i))
1105 + printk(KERN_CONT "???????? ");
1106 + else
1107 + printk(KERN_CONT "%08x ", c);
1108 + }
1109 + printk("\n");
1110 +}
1111 +#endif
1112 +
1113 void __kprobes
1114 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
1115 {
1116 @@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
1117 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
1118 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
1119
1120 - if ((vma->vm_flags & mask) != mask)
1121 + if ((vma->vm_flags & mask) != mask) {
1122 +
1123 +#ifdef CONFIG_PAX_PAGEEXEC
1124 + if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
1125 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
1126 + goto bad_area;
1127 +
1128 + up_read(&mm->mmap_sem);
1129 + pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
1130 + do_group_exit(SIGKILL);
1131 + }
1132 +#endif
1133 +
1134 goto bad_area;
1135
1136 + }
1137 +
1138 survive:
1139 /*
1140 * If for any reason at all we couldn't handle the fault, make
1141 diff -urNp linux-2.6.31.1/arch/ia64/mm/init.c linux-2.6.31.1/arch/ia64/mm/init.c
1142 --- linux-2.6.31.1/arch/ia64/mm/init.c 2009-09-24 11:45:25.000000000 -0400
1143 +++ linux-2.6.31.1/arch/ia64/mm/init.c 2009-10-01 20:12:42.000000000 -0400
1144 @@ -122,6 +122,19 @@ ia64_init_addr_space (void)
1145 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
1146 vma->vm_end = vma->vm_start + PAGE_SIZE;
1147 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
1148 +
1149 +#ifdef CONFIG_PAX_PAGEEXEC
1150 + if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
1151 + vma->vm_flags &= ~VM_EXEC;
1152 +
1153 +#ifdef CONFIG_PAX_MPROTECT
1154 + if (current->mm->pax_flags & MF_PAX_MPROTECT)
1155 + vma->vm_flags &= ~VM_MAYEXEC;
1156 +#endif
1157 +
1158 + }
1159 +#endif
1160 +
1161 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1162 down_write(&current->mm->mmap_sem);
1163 if (insert_vm_struct(current->mm, vma)) {
1164 diff -urNp linux-2.6.31.1/arch/m32r/include/asm/atomic.h linux-2.6.31.1/arch/m32r/include/asm/atomic.h
1165 --- linux-2.6.31.1/arch/m32r/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
1166 +++ linux-2.6.31.1/arch/m32r/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
1167 @@ -29,6 +29,14 @@
1168 #define atomic_read(v) ((v)->counter)
1169
1170 /**
1171 + * atomic_read_unchecked - read atomic variable
1172 + * @v: pointer of type atomic_unchecked_t
1173 + *
1174 + * Atomically reads the value of @v.
1175 + */
1176 +#define atomic_read_unchecked(v) ((v)->counter)
1177 +
1178 +/**
1179 * atomic_set - set atomic variable
1180 * @v: pointer of type atomic_t
1181 * @i: required value
1182 @@ -38,6 +46,15 @@
1183 #define atomic_set(v,i) (((v)->counter) = (i))
1184
1185 /**
1186 + * atomic_set_unchecked - set atomic variable
1187 + * @v: pointer of type atomic_unchecked_t
1188 + * @i: required value
1189 + *
1190 + * Atomically sets the value of @v to @i.
1191 + */
1192 +#define atomic_set_unchecked(v,i) (((v)->counter) = (i))
1193 +
1194 +/**
1195 * atomic_add_return - add integer to atomic variable and return it
1196 * @i: integer value to add
1197 * @v: pointer of type atomic_t
1198 @@ -308,6 +325,10 @@ static __inline__ void atomic_set_mask(u
1199 local_irq_restore(flags);
1200 }
1201
1202 +#define atomic_inc_unchecked(v) atomic_inc((atomic_t *)(v))
1203 +#define atomic_add_unchecked(i,v) atomic_add((i),(atomic_t *)(v))
1204 +#define atomic_sub_unchecked(i,v) atomic_sub((i),(atomic_t *)(v))
1205 +
1206 /* Atomic operations are already serializing on m32r */
1207 #define smp_mb__before_atomic_dec() barrier()
1208 #define smp_mb__after_atomic_dec() barrier()
1209 diff -urNp linux-2.6.31.1/arch/m32r/lib/usercopy.c linux-2.6.31.1/arch/m32r/lib/usercopy.c
1210 --- linux-2.6.31.1/arch/m32r/lib/usercopy.c 2009-09-24 11:45:25.000000000 -0400
1211 +++ linux-2.6.31.1/arch/m32r/lib/usercopy.c 2009-10-01 20:12:42.000000000 -0400
1212 @@ -14,6 +14,9 @@
1213 unsigned long
1214 __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
1215 {
1216 + if ((long)n < 0)
1217 + return n;
1218 +
1219 prefetch(from);
1220 if (access_ok(VERIFY_WRITE, to, n))
1221 __copy_user(to,from,n);
1222 @@ -23,6 +26,9 @@ __generic_copy_to_user(void __user *to,
1223 unsigned long
1224 __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
1225 {
1226 + if ((long)n < 0)
1227 + return n;
1228 +
1229 prefetchw(to);
1230 if (access_ok(VERIFY_READ, from, n))
1231 __copy_user_zeroing(to,from,n);
1232 diff -urNp linux-2.6.31.1/arch/m68k/include/asm/atomic_mm.h linux-2.6.31.1/arch/m68k/include/asm/atomic_mm.h
1233 --- linux-2.6.31.1/arch/m68k/include/asm/atomic_mm.h 2009-09-24 11:45:25.000000000 -0400
1234 +++ linux-2.6.31.1/arch/m68k/include/asm/atomic_mm.h 2009-10-01 20:12:42.000000000 -0400
1235 @@ -16,23 +16,40 @@
1236 #define ATOMIC_INIT(i) { (i) }
1237
1238 #define atomic_read(v) ((v)->counter)
1239 +#define atomic_read_unchecked(v) ((v)->counter)
1240 #define atomic_set(v, i) (((v)->counter) = i)
1241 +#define atomic_set_unchecked(v, i) (((v)->counter) = i)
1242
1243 static inline void atomic_add(int i, atomic_t *v)
1244 {
1245 __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "id" (i));
1246 }
1247
1248 +static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
1249 +{
1250 + atomic_add(i, (atomic_t *)v);
1251 +}
1252 +
1253 static inline void atomic_sub(int i, atomic_t *v)
1254 {
1255 __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "id" (i));
1256 }
1257
1258 +static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
1259 +{
1260 + atomic_sub(i, (atomic_t *)v);
1261 +}
1262 +
1263 static inline void atomic_inc(atomic_t *v)
1264 {
1265 __asm__ __volatile__("addql #1,%0" : "+m" (*v));
1266 }
1267
1268 +static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
1269 +{
1270 + atomic_inc((atomic_t *)v);
1271 +}
1272 +
1273 static inline void atomic_dec(atomic_t *v)
1274 {
1275 __asm__ __volatile__("subql #1,%0" : "+m" (*v));
1276 diff -urNp linux-2.6.31.1/arch/m68k/include/asm/atomic_no.h linux-2.6.31.1/arch/m68k/include/asm/atomic_no.h
1277 --- linux-2.6.31.1/arch/m68k/include/asm/atomic_no.h 2009-09-24 11:45:25.000000000 -0400
1278 +++ linux-2.6.31.1/arch/m68k/include/asm/atomic_no.h 2009-10-01 20:12:42.000000000 -0400
1279 @@ -16,7 +16,9 @@
1280 #define ATOMIC_INIT(i) { (i) }
1281
1282 #define atomic_read(v) ((v)->counter)
1283 +#define atomic_read_unchecked(v) ((v)->counter)
1284 #define atomic_set(v, i) (((v)->counter) = i)
1285 +#define atomic_set_unchecked(v, i) (((v)->counter) = i)
1286
1287 static __inline__ void atomic_add(int i, atomic_t *v)
1288 {
1289 @@ -27,6 +29,11 @@ static __inline__ void atomic_add(int i,
1290 #endif
1291 }
1292
1293 +static __inline__ void atomic_add_unchecked(int i, atomic_unchecked_t *v)
1294 +{
1295 + atomic_add(i, (atomic_t *)v);
1296 +}
1297 +
1298 static __inline__ void atomic_sub(int i, atomic_t *v)
1299 {
1300 #ifdef CONFIG_COLDFIRE
1301 @@ -36,6 +43,11 @@ static __inline__ void atomic_sub(int i,
1302 #endif
1303 }
1304
1305 +static __inline__ void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
1306 +{
1307 + atomic_sub(i, (atomic_t *)v);
1308 +}
1309 +
1310 static __inline__ int atomic_sub_and_test(int i, atomic_t * v)
1311 {
1312 char c;
1313 @@ -56,6 +68,11 @@ static __inline__ void atomic_inc(volati
1314 __asm__ __volatile__("addql #1,%0" : "+m" (*v));
1315 }
1316
1317 +static __inline__ void atomic_inc_unchecked(volatile atomic_unchecked_t *v)
1318 +{
1319 + atomic_inc((volatile atomic_t *)v);
1320 +}
1321 +
1322 /*
1323 * atomic_inc_and_test - increment and test
1324 * @v: pointer of type atomic_t
1325 diff -urNp linux-2.6.31.1/arch/mips/include/asm/atomic.h linux-2.6.31.1/arch/mips/include/asm/atomic.h
1326 --- linux-2.6.31.1/arch/mips/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
1327 +++ linux-2.6.31.1/arch/mips/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
1328 @@ -32,6 +32,14 @@
1329 #define atomic_read(v) ((v)->counter)
1330
1331 /*
1332 + * atomic_read_unchecked - read atomic variable
1333 + * @v: pointer of type atomic_unchecked_t
1334 + *
1335 + * Atomically reads the value of @v.
1336 + */
1337 +#define atomic_read_unchecked(v) ((v)->counter)
1338 +
1339 +/*
1340 * atomic_set - set atomic variable
1341 * @v: pointer of type atomic_t
1342 * @i: required value
1343 @@ -41,6 +49,15 @@
1344 #define atomic_set(v, i) ((v)->counter = (i))
1345
1346 /*
1347 + * atomic_set_unchecked - set atomic variable
1348 + * @v: pointer of type atomic_unchecked_t
1349 + * @i: required value
1350 + *
1351 + * Atomically sets the value of @v to @i.
1352 + */
1353 +#define atomic_set_unchecked(v, i) ((v)->counter = (i))
1354 +
1355 +/*
1356 * atomic_add - add integer to atomic variable
1357 * @i: integer value to add
1358 * @v: pointer of type atomic_t
1359 @@ -381,6 +398,9 @@ static __inline__ int atomic_add_unless(
1360 * Atomically increments @v by 1.
1361 */
1362 #define atomic_inc(v) atomic_add(1, (v))
1363 +#define atomic_inc_unchecked(v) atomic_inc((atomic_t *)(v))
1364 +#define atomic_add_unchecked(i, v) atomic_add((i), (atomic_t *)(v))
1365 +#define atomic_sub_unchecked(i, v) atomic_sub((i), (atomic_t *)(v))
1366
1367 /*
1368 * atomic_dec - decrement and test
1369 diff -urNp linux-2.6.31.1/arch/mips/include/asm/elf.h linux-2.6.31.1/arch/mips/include/asm/elf.h
1370 --- linux-2.6.31.1/arch/mips/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400
1371 +++ linux-2.6.31.1/arch/mips/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400
1372 @@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
1373 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
1374 #endif
1375
1376 +#ifdef CONFIG_PAX_ASLR
1377 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1378 +
1379 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1380 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1381 +#endif
1382 +
1383 #endif /* _ASM_ELF_H */
1384 diff -urNp linux-2.6.31.1/arch/mips/include/asm/page.h linux-2.6.31.1/arch/mips/include/asm/page.h
1385 --- linux-2.6.31.1/arch/mips/include/asm/page.h 2009-09-24 11:45:25.000000000 -0400
1386 +++ linux-2.6.31.1/arch/mips/include/asm/page.h 2009-10-01 20:12:42.000000000 -0400
1387 @@ -92,7 +92,7 @@ extern void copy_user_highpage(struct pa
1388 #ifdef CONFIG_CPU_MIPS32
1389 typedef struct { unsigned long pte_low, pte_high; } pte_t;
1390 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
1391 - #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
1392 + #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
1393 #else
1394 typedef struct { unsigned long long pte; } pte_t;
1395 #define pte_val(x) ((x).pte)
1396 diff -urNp linux-2.6.31.1/arch/mips/include/asm/system.h linux-2.6.31.1/arch/mips/include/asm/system.h
1397 --- linux-2.6.31.1/arch/mips/include/asm/system.h 2009-09-24 11:45:25.000000000 -0400
1398 +++ linux-2.6.31.1/arch/mips/include/asm/system.h 2009-10-01 20:12:42.000000000 -0400
1399 @@ -217,6 +217,6 @@ extern void per_cpu_trap_init(void);
1400 */
1401 #define __ARCH_WANT_UNLOCKED_CTXSW
1402
1403 -extern unsigned long arch_align_stack(unsigned long sp);
1404 +#define arch_align_stack(x) ((x) & ALMASK)
1405
1406 #endif /* _ASM_SYSTEM_H */
1407 diff -urNp linux-2.6.31.1/arch/mips/kernel/binfmt_elfn32.c linux-2.6.31.1/arch/mips/kernel/binfmt_elfn32.c
1408 --- linux-2.6.31.1/arch/mips/kernel/binfmt_elfn32.c 2009-09-24 11:45:25.000000000 -0400
1409 +++ linux-2.6.31.1/arch/mips/kernel/binfmt_elfn32.c 2009-10-01 20:12:42.000000000 -0400
1410 @@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
1411 #undef ELF_ET_DYN_BASE
1412 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
1413
1414 +#ifdef CONFIG_PAX_ASLR
1415 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1416 +
1417 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1418 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1419 +#endif
1420 +
1421 #include <asm/processor.h>
1422 #include <linux/module.h>
1423 #include <linux/elfcore.h>
1424 diff -urNp linux-2.6.31.1/arch/mips/kernel/binfmt_elfo32.c linux-2.6.31.1/arch/mips/kernel/binfmt_elfo32.c
1425 --- linux-2.6.31.1/arch/mips/kernel/binfmt_elfo32.c 2009-09-24 11:45:25.000000000 -0400
1426 +++ linux-2.6.31.1/arch/mips/kernel/binfmt_elfo32.c 2009-10-01 20:12:42.000000000 -0400
1427 @@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
1428 #undef ELF_ET_DYN_BASE
1429 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
1430
1431 +#ifdef CONFIG_PAX_ASLR
1432 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1433 +
1434 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1435 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1436 +#endif
1437 +
1438 #include <asm/processor.h>
1439
1440 /*
1441 diff -urNp linux-2.6.31.1/arch/mips/kernel/process.c linux-2.6.31.1/arch/mips/kernel/process.c
1442 --- linux-2.6.31.1/arch/mips/kernel/process.c 2009-09-24 11:45:25.000000000 -0400
1443 +++ linux-2.6.31.1/arch/mips/kernel/process.c 2009-10-01 20:12:42.000000000 -0400
1444 @@ -470,15 +470,3 @@ unsigned long get_wchan(struct task_stru
1445 out:
1446 return pc;
1447 }
1448 -
1449 -/*
1450 - * Don't forget that the stack pointer must be aligned on a 8 bytes
1451 - * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
1452 - */
1453 -unsigned long arch_align_stack(unsigned long sp)
1454 -{
1455 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
1456 - sp -= get_random_int() & ~PAGE_MASK;
1457 -
1458 - return sp & ALMASK;
1459 -}
1460 diff -urNp linux-2.6.31.1/arch/mips/kernel/syscall.c linux-2.6.31.1/arch/mips/kernel/syscall.c
1461 --- linux-2.6.31.1/arch/mips/kernel/syscall.c 2009-09-24 11:45:25.000000000 -0400
1462 +++ linux-2.6.31.1/arch/mips/kernel/syscall.c 2009-10-01 20:12:42.000000000 -0400
1463 @@ -99,6 +99,11 @@ unsigned long arch_get_unmapped_area(str
1464 do_color_align = 0;
1465 if (filp || (flags & MAP_SHARED))
1466 do_color_align = 1;
1467 +
1468 +#ifdef CONFIG_PAX_RANDMMAP
1469 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
1470 +#endif
1471 +
1472 if (addr) {
1473 if (do_color_align)
1474 addr = COLOUR_ALIGN(addr, pgoff);
1475 @@ -109,7 +114,7 @@ unsigned long arch_get_unmapped_area(str
1476 (!vmm || addr + len <= vmm->vm_start))
1477 return addr;
1478 }
1479 - addr = TASK_UNMAPPED_BASE;
1480 + addr = current->mm->mmap_base;
1481 if (do_color_align)
1482 addr = COLOUR_ALIGN(addr, pgoff);
1483 else
1484 diff -urNp linux-2.6.31.1/arch/mips/mm/fault.c linux-2.6.31.1/arch/mips/mm/fault.c
1485 --- linux-2.6.31.1/arch/mips/mm/fault.c 2009-09-24 11:45:25.000000000 -0400
1486 +++ linux-2.6.31.1/arch/mips/mm/fault.c 2009-10-01 20:12:42.000000000 -0400
1487 @@ -26,6 +26,23 @@
1488 #include <asm/ptrace.h>
1489 #include <asm/highmem.h> /* For VMALLOC_END */
1490
1491 +#ifdef CONFIG_PAX_PAGEEXEC
1492 +void pax_report_insns(void *pc)
1493 +{
1494 + unsigned long i;
1495 +
1496 + printk(KERN_ERR "PAX: bytes at PC: ");
1497 + for (i = 0; i < 5; i++) {
1498 + unsigned int c;
1499 + if (get_user(c, (unsigned int *)pc+i))
1500 + printk(KERN_CONT "???????? ");
1501 + else
1502 + printk(KERN_CONT "%08x ", c);
1503 + }
1504 + printk("\n");
1505 +}
1506 +#endif
1507 +
1508 /*
1509 * This routine handles page faults. It determines the address,
1510 * and the problem, and then passes it off to one of the appropriate
1511 diff -urNp linux-2.6.31.1/arch/mn10300/include/asm/atomic.h linux-2.6.31.1/arch/mn10300/include/asm/atomic.h
1512 --- linux-2.6.31.1/arch/mn10300/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
1513 +++ linux-2.6.31.1/arch/mn10300/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
1514 @@ -34,6 +34,15 @@
1515 #define atomic_read(v) ((v)->counter)
1516
1517 /**
1518 + * atomic_read_unchecked - read atomic variable
1519 + * @v: pointer of type atomic_unchecked_t
1520 + *
1521 + * Atomically reads the value of @v. Note that the guaranteed
1522 + * useful range of an atomic_unchecked_t is only 24 bits.
1523 + */
1524 +#define atomic_read_unchecked(v) ((v)->counter)
1525 +
1526 +/**
1527 * atomic_set - set atomic variable
1528 * @v: pointer of type atomic_t
1529 * @i: required value
1530 @@ -43,6 +52,16 @@
1531 */
1532 #define atomic_set(v, i) (((v)->counter) = (i))
1533
1534 +/**
1535 + * atomic_set_unchecked - set atomic variable
1536 + * @v: pointer of type atomic_unchecked_t
1537 + * @i: required value
1538 + *
1539 + * Atomically sets the value of @v to @i. Note that the guaranteed
1540 + * useful range of an atomic_unchecked_t is only 24 bits.
1541 + */
1542 +#define atomic_set_unchecked(v, i) (((v)->counter) = (i))
1543 +
1544 #include <asm/system.h>
1545
1546 /**
1547 @@ -99,16 +118,31 @@ static inline void atomic_add(int i, ato
1548 atomic_add_return(i, v);
1549 }
1550
1551 +static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
1552 +{
1553 + atomic_add_return(i, (atomic_t *)v);
1554 +}
1555 +
1556 static inline void atomic_sub(int i, atomic_t *v)
1557 {
1558 atomic_sub_return(i, v);
1559 }
1560
1561 +static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
1562 +{
1563 + atomic_sub_return(i, (atomic_t *)v);
1564 +}
1565 +
1566 static inline void atomic_inc(atomic_t *v)
1567 {
1568 atomic_add_return(1, v);
1569 }
1570
1571 +static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
1572 +{
1573 + atomic_add_return(1, (atomic_t *)v);
1574 +}
1575 +
1576 static inline void atomic_dec(atomic_t *v)
1577 {
1578 atomic_sub_return(1, v);
1579 diff -urNp linux-2.6.31.1/arch/mn10300/kernel/setup.c linux-2.6.31.1/arch/mn10300/kernel/setup.c
1580 --- linux-2.6.31.1/arch/mn10300/kernel/setup.c 2009-09-24 11:45:25.000000000 -0400
1581 +++ linux-2.6.31.1/arch/mn10300/kernel/setup.c 2009-10-01 20:12:42.000000000 -0400
1582 @@ -285,7 +285,7 @@ static void c_stop(struct seq_file *m, v
1583 {
1584 }
1585
1586 -struct seq_operations cpuinfo_op = {
1587 +const struct seq_operations cpuinfo_op = {
1588 .start = c_start,
1589 .next = c_next,
1590 .stop = c_stop,
1591 diff -urNp linux-2.6.31.1/arch/parisc/include/asm/atomic.h linux-2.6.31.1/arch/parisc/include/asm/atomic.h
1592 --- linux-2.6.31.1/arch/parisc/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
1593 +++ linux-2.6.31.1/arch/parisc/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
1594 @@ -177,6 +177,18 @@ static __inline__ int __atomic_add_retur
1595 return ret;
1596 }
1597
1598 +static __inline__ int __atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
1599 +{
1600 + int ret;
1601 + unsigned long flags;
1602 + _atomic_spin_lock_irqsave(v, flags);
1603 +
1604 + ret = (v->counter += i);
1605 +
1606 + _atomic_spin_unlock_irqrestore(v, flags);
1607 + return ret;
1608 +}
1609 +
1610 static __inline__ void atomic_set(atomic_t *v, int i)
1611 {
1612 unsigned long flags;
1613 @@ -187,11 +199,26 @@ static __inline__ void atomic_set(atomic
1614 _atomic_spin_unlock_irqrestore(v, flags);
1615 }
1616
1617 +static __inline__ void atomic_set_unchecked(atomic_unchecked_t *v, int i)
1618 +{
1619 + unsigned long flags;
1620 + _atomic_spin_lock_irqsave(v, flags);
1621 +
1622 + v->counter = i;
1623 +
1624 + _atomic_spin_unlock_irqrestore(v, flags);
1625 +}
1626 +
1627 static __inline__ int atomic_read(const atomic_t *v)
1628 {
1629 return v->counter;
1630 }
1631
1632 +static __inline__ int atomic_read_unchecked(const atomic_unchecked_t *v)
1633 +{
1634 + return v->counter;
1635 +}
1636 +
1637 /* exported interface */
1638 #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
1639 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
1640 @@ -223,8 +250,11 @@ static __inline__ int atomic_add_unless(
1641 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
1642
1643 #define atomic_add(i,v) ((void)(__atomic_add_return( (i),(v))))
1644 +#define atomic_add_unchecked(i,v) ((void)(__atomic_add_return_unchecked( ((i),(v))))
1645 #define atomic_sub(i,v) ((void)(__atomic_add_return(-(i),(v))))
1646 +#define atomic_sub_unchecked(i,v) ((void)(__atomic_add_return_unchecked(-(i),(v))))
1647 #define atomic_inc(v) ((void)(__atomic_add_return( 1,(v))))
1648 +#define atomic_inc_unchecked(v) ((void)(__atomic_add_return_unchecked( 1,(v))))
1649 #define atomic_dec(v) ((void)(__atomic_add_return( -1,(v))))
1650
1651 #define atomic_add_return(i,v) (__atomic_add_return( (i),(v)))
1652 diff -urNp linux-2.6.31.1/arch/parisc/include/asm/elf.h linux-2.6.31.1/arch/parisc/include/asm/elf.h
1653 --- linux-2.6.31.1/arch/parisc/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400
1654 +++ linux-2.6.31.1/arch/parisc/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400
1655 @@ -343,6 +343,13 @@ struct pt_regs; /* forward declaration..
1656
1657 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
1658
1659 +#ifdef CONFIG_PAX_ASLR
1660 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
1661 +
1662 +#define PAX_DELTA_MMAP_LEN 16
1663 +#define PAX_DELTA_STACK_LEN 16
1664 +#endif
1665 +
1666 /* This yields a mask that user programs can use to figure out what
1667 instruction set this CPU supports. This could be done in user space,
1668 but it's not easy, and we've already done it here. */
1669 diff -urNp linux-2.6.31.1/arch/parisc/include/asm/pgtable.h linux-2.6.31.1/arch/parisc/include/asm/pgtable.h
1670 --- linux-2.6.31.1/arch/parisc/include/asm/pgtable.h 2009-09-24 11:45:25.000000000 -0400
1671 +++ linux-2.6.31.1/arch/parisc/include/asm/pgtable.h 2009-10-01 20:12:42.000000000 -0400
1672 @@ -207,6 +207,17 @@
1673 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
1674 #define PAGE_COPY PAGE_EXECREAD
1675 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
1676 +
1677 +#ifdef CONFIG_PAX_PAGEEXEC
1678 +# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
1679 +# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
1680 +# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
1681 +#else
1682 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
1683 +# define PAGE_COPY_NOEXEC PAGE_COPY
1684 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
1685 +#endif
1686 +
1687 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
1688 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
1689 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
1690 diff -urNp linux-2.6.31.1/arch/parisc/kernel/module.c linux-2.6.31.1/arch/parisc/kernel/module.c
1691 --- linux-2.6.31.1/arch/parisc/kernel/module.c 2009-09-24 11:45:25.000000000 -0400
1692 +++ linux-2.6.31.1/arch/parisc/kernel/module.c 2009-10-01 20:12:42.000000000 -0400
1693 @@ -95,16 +95,38 @@
1694
1695 /* three functions to determine where in the module core
1696 * or init pieces the location is */
1697 +static inline int in_init_rx(struct module *me, void *loc)
1698 +{
1699 + return (loc >= me->module_init_rx &&
1700 + loc < (me->module_init_rx + me->init_size_rx));
1701 +}
1702 +
1703 +static inline int in_init_rw(struct module *me, void *loc)
1704 +{
1705 + return (loc >= me->module_init_rw &&
1706 + loc < (me->module_init_rw + me->init_size_rw));
1707 +}
1708 +
1709 static inline int in_init(struct module *me, void *loc)
1710 {
1711 - return (loc >= me->module_init &&
1712 - loc <= (me->module_init + me->init_size));
1713 + return in_init_rx(me, loc) || in_init_rw(me, loc);
1714 +}
1715 +
1716 +static inline int in_core_rx(struct module *me, void *loc)
1717 +{
1718 + return (loc >= me->module_core_rx &&
1719 + loc < (me->module_core_rx + me->core_size_rx));
1720 +}
1721 +
1722 +static inline int in_core_rw(struct module *me, void *loc)
1723 +{
1724 + return (loc >= me->module_core_rw &&
1725 + loc < (me->module_core_rw + me->core_size_rw));
1726 }
1727
1728 static inline int in_core(struct module *me, void *loc)
1729 {
1730 - return (loc >= me->module_core &&
1731 - loc <= (me->module_core + me->core_size));
1732 + return in_core_rx(me, loc) || in_core_rw(me, loc);
1733 }
1734
1735 static inline int in_local(struct module *me, void *loc)
1736 @@ -364,13 +386,13 @@ int module_frob_arch_sections(CONST Elf_
1737 }
1738
1739 /* align things a bit */
1740 - me->core_size = ALIGN(me->core_size, 16);
1741 - me->arch.got_offset = me->core_size;
1742 - me->core_size += gots * sizeof(struct got_entry);
1743 -
1744 - me->core_size = ALIGN(me->core_size, 16);
1745 - me->arch.fdesc_offset = me->core_size;
1746 - me->core_size += fdescs * sizeof(Elf_Fdesc);
1747 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
1748 + me->arch.got_offset = me->core_size_rw;
1749 + me->core_size_rw += gots * sizeof(struct got_entry);
1750 +
1751 + me->core_size_rw = ALIGN(me->core_size_rw, 16);
1752 + me->arch.fdesc_offset = me->core_size_rw;
1753 + me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
1754
1755 me->arch.got_max = gots;
1756 me->arch.fdesc_max = fdescs;
1757 @@ -388,7 +410,7 @@ static Elf64_Word get_got(struct module
1758
1759 BUG_ON(value == 0);
1760
1761 - got = me->module_core + me->arch.got_offset;
1762 + got = me->module_core_rw + me->arch.got_offset;
1763 for (i = 0; got[i].addr; i++)
1764 if (got[i].addr == value)
1765 goto out;
1766 @@ -406,7 +428,7 @@ static Elf64_Word get_got(struct module
1767 #ifdef CONFIG_64BIT
1768 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
1769 {
1770 - Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
1771 + Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
1772
1773 if (!value) {
1774 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
1775 @@ -424,7 +446,7 @@ static Elf_Addr get_fdesc(struct module
1776
1777 /* Create new one */
1778 fdesc->addr = value;
1779 - fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
1780 + fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1781 return (Elf_Addr)fdesc;
1782 }
1783 #endif /* CONFIG_64BIT */
1784 @@ -848,7 +870,7 @@ register_unwind_table(struct module *me,
1785
1786 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
1787 end = table + sechdrs[me->arch.unwind_section].sh_size;
1788 - gp = (Elf_Addr)me->module_core + me->arch.got_offset;
1789 + gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1790
1791 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
1792 me->arch.unwind_section, table, end, gp);
1793 diff -urNp linux-2.6.31.1/arch/parisc/kernel/sys_parisc.c linux-2.6.31.1/arch/parisc/kernel/sys_parisc.c
1794 --- linux-2.6.31.1/arch/parisc/kernel/sys_parisc.c 2009-09-24 11:45:25.000000000 -0400
1795 +++ linux-2.6.31.1/arch/parisc/kernel/sys_parisc.c 2009-10-01 20:12:42.000000000 -0400
1796 @@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
1797 if (flags & MAP_FIXED)
1798 return addr;
1799 if (!addr)
1800 - addr = TASK_UNMAPPED_BASE;
1801 + addr = current->mm->mmap_base;
1802
1803 if (filp) {
1804 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
1805 diff -urNp linux-2.6.31.1/arch/parisc/kernel/traps.c linux-2.6.31.1/arch/parisc/kernel/traps.c
1806 --- linux-2.6.31.1/arch/parisc/kernel/traps.c 2009-09-24 11:45:25.000000000 -0400
1807 +++ linux-2.6.31.1/arch/parisc/kernel/traps.c 2009-10-01 20:12:42.000000000 -0400
1808 @@ -733,9 +733,7 @@ void notrace handle_interruption(int cod
1809
1810 down_read(&current->mm->mmap_sem);
1811 vma = find_vma(current->mm,regs->iaoq[0]);
1812 - if (vma && (regs->iaoq[0] >= vma->vm_start)
1813 - && (vma->vm_flags & VM_EXEC)) {
1814 -
1815 + if (vma && (regs->iaoq[0] >= vma->vm_start)) {
1816 fault_address = regs->iaoq[0];
1817 fault_space = regs->iasq[0];
1818
1819 diff -urNp linux-2.6.31.1/arch/parisc/mm/fault.c linux-2.6.31.1/arch/parisc/mm/fault.c
1820 --- linux-2.6.31.1/arch/parisc/mm/fault.c 2009-09-24 11:45:25.000000000 -0400
1821 +++ linux-2.6.31.1/arch/parisc/mm/fault.c 2009-10-01 20:12:42.000000000 -0400
1822 @@ -15,6 +15,7 @@
1823 #include <linux/sched.h>
1824 #include <linux/interrupt.h>
1825 #include <linux/module.h>
1826 +#include <linux/unistd.h>
1827
1828 #include <asm/uaccess.h>
1829 #include <asm/traps.h>
1830 @@ -52,7 +53,7 @@ DEFINE_PER_CPU(struct exception_data, ex
1831 static unsigned long
1832 parisc_acctyp(unsigned long code, unsigned int inst)
1833 {
1834 - if (code == 6 || code == 16)
1835 + if (code == 6 || code == 7 || code == 16)
1836 return VM_EXEC;
1837
1838 switch (inst & 0xf0000000) {
1839 @@ -138,6 +139,116 @@ parisc_acctyp(unsigned long code, unsign
1840 }
1841 #endif
1842
1843 +#ifdef CONFIG_PAX_PAGEEXEC
1844 +/*
1845 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
1846 + *
1847 + * returns 1 when task should be killed
1848 + * 2 when rt_sigreturn trampoline was detected
1849 + * 3 when unpatched PLT trampoline was detected
1850 + */
1851 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1852 +{
1853 +
1854 +#ifdef CONFIG_PAX_EMUPLT
1855 + int err;
1856 +
1857 + do { /* PaX: unpatched PLT emulation */
1858 + unsigned int bl, depwi;
1859 +
1860 + err = get_user(bl, (unsigned int *)instruction_pointer(regs));
1861 + err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
1862 +
1863 + if (err)
1864 + break;
1865 +
1866 + if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
1867 + unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
1868 +
1869 + err = get_user(ldw, (unsigned int *)addr);
1870 + err |= get_user(bv, (unsigned int *)(addr+4));
1871 + err |= get_user(ldw2, (unsigned int *)(addr+8));
1872 +
1873 + if (err)
1874 + break;
1875 +
1876 + if (ldw == 0x0E801096U &&
1877 + bv == 0xEAC0C000U &&
1878 + ldw2 == 0x0E881095U)
1879 + {
1880 + unsigned int resolver, map;
1881 +
1882 + err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
1883 + err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
1884 + if (err)
1885 + break;
1886 +
1887 + regs->gr[20] = instruction_pointer(regs)+8;
1888 + regs->gr[21] = map;
1889 + regs->gr[22] = resolver;
1890 + regs->iaoq[0] = resolver | 3UL;
1891 + regs->iaoq[1] = regs->iaoq[0] + 4;
1892 + return 3;
1893 + }
1894 + }
1895 + } while (0);
1896 +#endif
1897 +
1898 +#ifdef CONFIG_PAX_EMUTRAMP
1899 +
1900 +#ifndef CONFIG_PAX_EMUSIGRT
1901 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
1902 + return 1;
1903 +#endif
1904 +
1905 + do { /* PaX: rt_sigreturn emulation */
1906 + unsigned int ldi1, ldi2, bel, nop;
1907 +
1908 + err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
1909 + err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
1910 + err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
1911 + err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
1912 +
1913 + if (err)
1914 + break;
1915 +
1916 + if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
1917 + ldi2 == 0x3414015AU &&
1918 + bel == 0xE4008200U &&
1919 + nop == 0x08000240U)
1920 + {
1921 + regs->gr[25] = (ldi1 & 2) >> 1;
1922 + regs->gr[20] = __NR_rt_sigreturn;
1923 + regs->gr[31] = regs->iaoq[1] + 16;
1924 + regs->sr[0] = regs->iasq[1];
1925 + regs->iaoq[0] = 0x100UL;
1926 + regs->iaoq[1] = regs->iaoq[0] + 4;
1927 + regs->iasq[0] = regs->sr[2];
1928 + regs->iasq[1] = regs->sr[2];
1929 + return 2;
1930 + }
1931 + } while (0);
1932 +#endif
1933 +
1934 + return 1;
1935 +}
1936 +
1937 +void pax_report_insns(void *pc, void *sp)
1938 +{
1939 + unsigned long i;
1940 +
1941 + printk(KERN_ERR "PAX: bytes at PC: ");
1942 + for (i = 0; i < 5; i++) {
1943 + unsigned int c;
1944 + if (get_user(c, (unsigned int *)pc+i))
1945 + printk(KERN_CONT "???????? ");
1946 + else
1947 + printk(KERN_CONT "%08x ", c);
1948 + }
1949 + printk("\n");
1950 +}
1951 +#endif
1952 +
1953 int fixup_exception(struct pt_regs *regs)
1954 {
1955 const struct exception_table_entry *fix;
1956 @@ -192,8 +303,33 @@ good_area:
1957
1958 acc_type = parisc_acctyp(code,regs->iir);
1959
1960 - if ((vma->vm_flags & acc_type) != acc_type)
1961 + if ((vma->vm_flags & acc_type) != acc_type) {
1962 +
1963 +#ifdef CONFIG_PAX_PAGEEXEC
1964 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
1965 + (address & ~3UL) == instruction_pointer(regs))
1966 + {
1967 + up_read(&mm->mmap_sem);
1968 + switch (pax_handle_fetch_fault(regs)) {
1969 +
1970 +#ifdef CONFIG_PAX_EMUPLT
1971 + case 3:
1972 + return;
1973 +#endif
1974 +
1975 +#ifdef CONFIG_PAX_EMUTRAMP
1976 + case 2:
1977 + return;
1978 +#endif
1979 +
1980 + }
1981 + pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1982 + do_group_exit(SIGKILL);
1983 + }
1984 +#endif
1985 +
1986 goto bad_area;
1987 + }
1988
1989 /*
1990 * If for any reason at all we couldn't handle the fault, make
1991 diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/atomic.h linux-2.6.31.1/arch/powerpc/include/asm/atomic.h
1992 --- linux-2.6.31.1/arch/powerpc/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
1993 +++ linux-2.6.31.1/arch/powerpc/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
1994 @@ -24,11 +24,21 @@ static __inline__ int atomic_read(const
1995 return t;
1996 }
1997
1998 +static __inline__ int atomic_read_unchecked(const atomic_unchecked_t *v)
1999 +{
2000 + return atomic_read((const atomic_t *)v);
2001 +}
2002 +
2003 static __inline__ void atomic_set(atomic_t *v, int i)
2004 {
2005 __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));
2006 }
2007
2008 +static __inline__ void atomic_set_unchecked(atomic_unchecked_t *v, int i)
2009 +{
2010 + atomic_set((atomic_t *)v, i);
2011 +}
2012 +
2013 static __inline__ void atomic_add(int a, atomic_t *v)
2014 {
2015 int t;
2016 @@ -44,6 +54,11 @@ static __inline__ void atomic_add(int a,
2017 : "cc");
2018 }
2019
2020 +static __inline__ void atomic_add_unchecked(int a, atomic_unchecked_t *v)
2021 +{
2022 + atomic_add(a, (atomic_t *)v);
2023 +}
2024 +
2025 static __inline__ int atomic_add_return(int a, atomic_t *v)
2026 {
2027 int t;
2028 @@ -80,6 +95,11 @@ static __inline__ void atomic_sub(int a,
2029 : "cc");
2030 }
2031
2032 +static __inline__ void atomic_sub_unchecked(int a, atomic_unchecked_t *v)
2033 +{
2034 + atomic_sub(a, (atomic_t *)v);
2035 +}
2036 +
2037 static __inline__ int atomic_sub_return(int a, atomic_t *v)
2038 {
2039 int t;
2040 @@ -114,6 +134,11 @@ static __inline__ void atomic_inc(atomic
2041 : "cc", "xer");
2042 }
2043
2044 +static __inline__ void atomic_inc_unchecked(atomic_unchecked_t *v)
2045 +{
2046 + atomic_inc((atomic_t *)v);
2047 +}
2048 +
2049 static __inline__ int atomic_inc_return(atomic_t *v)
2050 {
2051 int t;
2052 diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/elf.h linux-2.6.31.1/arch/powerpc/include/asm/elf.h
2053 --- linux-2.6.31.1/arch/powerpc/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400
2054 +++ linux-2.6.31.1/arch/powerpc/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400
2055 @@ -179,8 +179,19 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
2056 the loader. We need to make sure that it is out of the way of the program
2057 that it will "exec", and that there is sufficient room for the brk. */
2058
2059 -extern unsigned long randomize_et_dyn(unsigned long base);
2060 -#define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000))
2061 +#define ELF_ET_DYN_BASE (0x20000000)
2062 +
2063 +#ifdef CONFIG_PAX_ASLR
2064 +#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
2065 +
2066 +#ifdef __powerpc64__
2067 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
2068 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
2069 +#else
2070 +#define PAX_DELTA_MMAP_LEN 15
2071 +#define PAX_DELTA_STACK_LEN 15
2072 +#endif
2073 +#endif
2074
2075 /*
2076 * Our registers are always unsigned longs, whether we're a 32 bit
2077 @@ -279,9 +290,6 @@ extern int arch_setup_additional_pages(s
2078 (0x7ff >> (PAGE_SHIFT - 12)) : \
2079 (0x3ffff >> (PAGE_SHIFT - 12)))
2080
2081 -extern unsigned long arch_randomize_brk(struct mm_struct *mm);
2082 -#define arch_randomize_brk arch_randomize_brk
2083 -
2084 #endif /* __KERNEL__ */
2085
2086 /*
2087 diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/kmap_types.h linux-2.6.31.1/arch/powerpc/include/asm/kmap_types.h
2088 --- linux-2.6.31.1/arch/powerpc/include/asm/kmap_types.h 2009-09-24 11:45:25.000000000 -0400
2089 +++ linux-2.6.31.1/arch/powerpc/include/asm/kmap_types.h 2009-10-01 20:12:42.000000000 -0400
2090 @@ -26,6 +26,7 @@ enum km_type {
2091 KM_SOFTIRQ1,
2092 KM_PPC_SYNC_PAGE,
2093 KM_PPC_SYNC_ICACHE,
2094 + KM_CLEARPAGE,
2095 KM_TYPE_NR
2096 };
2097
2098 diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/page_64.h linux-2.6.31.1/arch/powerpc/include/asm/page_64.h
2099 --- linux-2.6.31.1/arch/powerpc/include/asm/page_64.h 2009-09-24 11:45:25.000000000 -0400
2100 +++ linux-2.6.31.1/arch/powerpc/include/asm/page_64.h 2009-10-01 20:12:42.000000000 -0400
2101 @@ -170,15 +170,18 @@ do { \
2102 * stack by default, so in the absense of a PT_GNU_STACK program header
2103 * we turn execute permission off.
2104 */
2105 -#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
2106 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2107 +#define VM_STACK_DEFAULT_FLAGS32 \
2108 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
2109 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2110
2111 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
2112 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2113
2114 +#ifndef CONFIG_PAX_PAGEEXEC
2115 #define VM_STACK_DEFAULT_FLAGS \
2116 (test_thread_flag(TIF_32BIT) ? \
2117 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
2118 +#endif
2119
2120 #include <asm-generic/getorder.h>
2121
2122 diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/page.h linux-2.6.31.1/arch/powerpc/include/asm/page.h
2123 --- linux-2.6.31.1/arch/powerpc/include/asm/page.h 2009-09-24 11:45:25.000000000 -0400
2124 +++ linux-2.6.31.1/arch/powerpc/include/asm/page.h 2009-10-01 20:12:42.000000000 -0400
2125 @@ -116,8 +116,9 @@ extern phys_addr_t kernstart_addr;
2126 * and needs to be executable. This means the whole heap ends
2127 * up being executable.
2128 */
2129 -#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
2130 - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2131 +#define VM_DATA_DEFAULT_FLAGS32 \
2132 + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
2133 + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2134
2135 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
2136 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
2137 diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/pte-common.h linux-2.6.31.1/arch/powerpc/include/asm/pte-common.h
2138 --- linux-2.6.31.1/arch/powerpc/include/asm/pte-common.h 2009-09-24 11:45:25.000000000 -0400
2139 +++ linux-2.6.31.1/arch/powerpc/include/asm/pte-common.h 2009-10-01 20:12:42.000000000 -0400
2140 @@ -121,11 +121,11 @@ extern unsigned long bad_call_to_PMD_PAG
2141 */
2142 #define PAGE_NONE __pgprot(_PAGE_BASE)
2143 #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
2144 -#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
2145 +#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
2146 #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
2147 -#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
2148 +#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
2149 #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
2150 -#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
2151 +#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
2152
2153 #define __P000 PAGE_NONE
2154 #define __P001 PAGE_READONLY
2155 diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/pte-hash32.h linux-2.6.31.1/arch/powerpc/include/asm/pte-hash32.h
2156 --- linux-2.6.31.1/arch/powerpc/include/asm/pte-hash32.h 2009-09-24 11:45:25.000000000 -0400
2157 +++ linux-2.6.31.1/arch/powerpc/include/asm/pte-hash32.h 2009-10-01 20:12:42.000000000 -0400
2158 @@ -21,6 +21,7 @@
2159 #define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */
2160 #define _PAGE_USER 0x004 /* usermode access allowed */
2161 #define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
2162 +#define _PAGE_HWEXEC _PAGE_GUARDED
2163 #define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
2164 #define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
2165 #define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
2166 diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/reg.h linux-2.6.31.1/arch/powerpc/include/asm/reg.h
2167 --- linux-2.6.31.1/arch/powerpc/include/asm/reg.h 2009-09-24 11:45:25.000000000 -0400
2168 +++ linux-2.6.31.1/arch/powerpc/include/asm/reg.h 2009-10-01 20:12:42.000000000 -0400
2169 @@ -195,6 +195,7 @@
2170 #define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */
2171 #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
2172 #define DSISR_NOHPTE 0x40000000 /* no translation found */
2173 +#define DSISR_GUARDED 0x10000000 /* fetch from guarded storage */
2174 #define DSISR_PROTFAULT 0x08000000 /* protection fault */
2175 #define DSISR_ISSTORE 0x02000000 /* access was a store */
2176 #define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */
2177 diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/uaccess.h linux-2.6.31.1/arch/powerpc/include/asm/uaccess.h
2178 --- linux-2.6.31.1/arch/powerpc/include/asm/uaccess.h 2009-09-24 11:45:25.000000000 -0400
2179 +++ linux-2.6.31.1/arch/powerpc/include/asm/uaccess.h 2009-10-01 20:12:42.000000000 -0400
2180 @@ -327,52 +327,6 @@ do { \
2181 extern unsigned long __copy_tofrom_user(void __user *to,
2182 const void __user *from, unsigned long size);
2183
2184 -#ifndef __powerpc64__
2185 -
2186 -static inline unsigned long copy_from_user(void *to,
2187 - const void __user *from, unsigned long n)
2188 -{
2189 - unsigned long over;
2190 -
2191 - if (access_ok(VERIFY_READ, from, n))
2192 - return __copy_tofrom_user((__force void __user *)to, from, n);
2193 - if ((unsigned long)from < TASK_SIZE) {
2194 - over = (unsigned long)from + n - TASK_SIZE;
2195 - return __copy_tofrom_user((__force void __user *)to, from,
2196 - n - over) + over;
2197 - }
2198 - return n;
2199 -}
2200 -
2201 -static inline unsigned long copy_to_user(void __user *to,
2202 - const void *from, unsigned long n)
2203 -{
2204 - unsigned long over;
2205 -
2206 - if (access_ok(VERIFY_WRITE, to, n))
2207 - return __copy_tofrom_user(to, (__force void __user *)from, n);
2208 - if ((unsigned long)to < TASK_SIZE) {
2209 - over = (unsigned long)to + n - TASK_SIZE;
2210 - return __copy_tofrom_user(to, (__force void __user *)from,
2211 - n - over) + over;
2212 - }
2213 - return n;
2214 -}
2215 -
2216 -#else /* __powerpc64__ */
2217 -
2218 -#define __copy_in_user(to, from, size) \
2219 - __copy_tofrom_user((to), (from), (size))
2220 -
2221 -extern unsigned long copy_from_user(void *to, const void __user *from,
2222 - unsigned long n);
2223 -extern unsigned long copy_to_user(void __user *to, const void *from,
2224 - unsigned long n);
2225 -extern unsigned long copy_in_user(void __user *to, const void __user *from,
2226 - unsigned long n);
2227 -
2228 -#endif /* __powerpc64__ */
2229 -
2230 static inline unsigned long __copy_from_user_inatomic(void *to,
2231 const void __user *from, unsigned long n)
2232 {
2233 @@ -396,6 +350,9 @@ static inline unsigned long __copy_from_
2234 if (ret == 0)
2235 return 0;
2236 }
2237 + if (!__builtin_constant_p(n))
2238 + check_object_size(to, n, false);
2239 +
2240 return __copy_tofrom_user((__force void __user *)to, from, n);
2241 }
2242
2243 @@ -422,6 +379,9 @@ static inline unsigned long __copy_to_us
2244 if (ret == 0)
2245 return 0;
2246 }
2247 + if (!__builtin_constant_p(n))
2248 + check_object_size(from, n, true);
2249 +
2250 return __copy_tofrom_user(to, (__force const void __user *)from, n);
2251 }
2252
2253 @@ -439,6 +399,97 @@ static inline unsigned long __copy_to_us
2254 return __copy_to_user_inatomic(to, from, size);
2255 }
2256
2257 +#ifndef __powerpc64__
2258 +
2259 +static inline unsigned long __must_check copy_from_user(void *to,
2260 + const void __user *from, unsigned long n)
2261 +{
2262 + unsigned long over;
2263 +
2264 + if (((long)n < 0) || (n > INT_MAX))
2265 + return n;
2266 +
2267 + if (access_ok(VERIFY_READ, from, n)) {
2268 + if (!__builtin_constant_p(n))
2269 + check_object_size(to, n, false);
2270 +
2271 + return __copy_tofrom_user((__force void __user *)to, from, n);
2272 + }
2273 + if ((unsigned long)from < TASK_SIZE) {
2274 + over = (unsigned long)from + n - TASK_SIZE;
2275 + if (!__builtin_constant_p(n - over))
2276 + check_object_size(to, n - over, false);
2277 + return __copy_tofrom_user((__force void __user *)to, from,
2278 + n - over) + over;
2279 + }
2280 + return n;
2281 +}
2282 +
2283 +static inline unsigned long __must_check copy_to_user(void __user *to,
2284 + const void *from, unsigned long n)
2285 +{
2286 + unsigned long over;
2287 +
2288 + if (((long)n < 0) || (n > INT_MAX))
2289 + return n;
2290 +
2291 + if (access_ok(VERIFY_WRITE, to, n)) {
2292 + if (!__builtin_constant_p(n))
2293 + check_object_size(from, n, true);
2294 + return __copy_tofrom_user(to, (__force void __user *)from, n);
2295 + }
2296 + if ((unsigned long)to < TASK_SIZE) {
2297 + over = (unsigned long)to + n - TASK_SIZE;
2298 + if (!__builtin_constant_p(n))
2299 + check_object_size(from, n - over, true);
2300 + return __copy_tofrom_user(to, (__force void __user *)from,
2301 + n - over) + over;
2302 + }
2303 + return n;
2304 +}
2305 +
2306 +#else /* __powerpc64__ */
2307 +
2308 +#define __copy_in_user(to, from, size) \
2309 + __copy_tofrom_user((to), (from), (size))
2310 +
2311 +static inline unsigned long __must_check copy_from_user(void *to,
2312 + const void __user *from, unsigned long n)
2313 +{
2314 + if (unlikely(((long)n < 0) || (n > INT_MAX)))
2315 + return n;
2316 +
2317 + if (!__builtin_constant_p(n))
2318 + check_object_size(to, n, false);
2319 +
2320 + if (likely(access_ok(VERIFY_READ, from, n)))
2321 + n = __copy_from_user(to, from, n);
2322 + else
2323 + memset(to, 0, n);
2324 +
2325 + return n;
2326 +}
2327 +
2328 +static inline unsigned long __must_check copy_to_user(void __user *to,
2329 + const void *from, unsigned long n)
2330 +{
2331 + if (unlikely(((long)n < 0) || (n > INT_MAX)))
2332 + return n;
2333 +
2334 + if (likely(access_ok(VERIFY_WRITE, to, n))) {
2335 + if (!__builtin_constant_p(n))
2336 + check_object_size(from, n, true);
2337 + n = __copy_to_user(to, from, n);
2338 + }
2339 +
2340 + return n;
2341 +}
2342 +
2343 +extern unsigned long copy_in_user(void __user *to, const void __user *from,
2344 + unsigned long n);
2345 +
2346 +#endif /* __powerpc64__ */
2347 +
2348 extern unsigned long __clear_user(void __user *addr, unsigned long size);
2349
2350 static inline unsigned long clear_user(void __user *addr, unsigned long size)
2351 diff -urNp linux-2.6.31.1/arch/powerpc/kernel/module_32.c linux-2.6.31.1/arch/powerpc/kernel/module_32.c
2352 --- linux-2.6.31.1/arch/powerpc/kernel/module_32.c 2009-09-24 11:45:25.000000000 -0400
2353 +++ linux-2.6.31.1/arch/powerpc/kernel/module_32.c 2009-10-01 20:12:42.000000000 -0400
2354 @@ -162,7 +162,7 @@ int module_frob_arch_sections(Elf32_Ehdr
2355 me->arch.core_plt_section = i;
2356 }
2357 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
2358 - printk("Module doesn't contain .plt or .init.plt sections.\n");
2359 + printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
2360 return -ENOEXEC;
2361 }
2362
2363 @@ -203,11 +203,16 @@ static uint32_t do_plt_call(void *locati
2364
2365 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
2366 /* Init, or core PLT? */
2367 - if (location >= mod->module_core
2368 - && location < mod->module_core + mod->core_size)
2369 + if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
2370 + (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
2371 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
2372 - else
2373 + else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
2374 + (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
2375 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
2376 + else {
2377 + printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
2378 + return ~0UL;
2379 + }
2380
2381 /* Find this entry, or if that fails, the next avail. entry */
2382 while (entry->jump[0]) {
2383 diff -urNp linux-2.6.31.1/arch/powerpc/kernel/process.c linux-2.6.31.1/arch/powerpc/kernel/process.c
2384 --- linux-2.6.31.1/arch/powerpc/kernel/process.c 2009-09-24 11:45:25.000000000 -0400
2385 +++ linux-2.6.31.1/arch/powerpc/kernel/process.c 2009-10-01 20:12:42.000000000 -0400
2386 @@ -1147,36 +1147,3 @@ unsigned long arch_align_stack(unsigned
2387 sp -= get_random_int() & ~PAGE_MASK;
2388 return sp & ~0xf;
2389 }
2390 -
2391 -static inline unsigned long brk_rnd(void)
2392 -{
2393 - unsigned long rnd = 0;
2394 -
2395 - /* 8MB for 32bit, 1GB for 64bit */
2396 - if (is_32bit_task())
2397 - rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
2398 - else
2399 - rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
2400 -
2401 - return rnd << PAGE_SHIFT;
2402 -}
2403 -
2404 -unsigned long arch_randomize_brk(struct mm_struct *mm)
2405 -{
2406 - unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
2407 -
2408 - if (ret < mm->brk)
2409 - return mm->brk;
2410 -
2411 - return ret;
2412 -}
2413 -
2414 -unsigned long randomize_et_dyn(unsigned long base)
2415 -{
2416 - unsigned long ret = PAGE_ALIGN(base + brk_rnd());
2417 -
2418 - if (ret < base)
2419 - return base;
2420 -
2421 - return ret;
2422 -}
2423 diff -urNp linux-2.6.31.1/arch/powerpc/kernel/setup-common.c linux-2.6.31.1/arch/powerpc/kernel/setup-common.c
2424 --- linux-2.6.31.1/arch/powerpc/kernel/setup-common.c 2009-09-24 11:45:25.000000000 -0400
2425 +++ linux-2.6.31.1/arch/powerpc/kernel/setup-common.c 2009-10-01 20:12:42.000000000 -0400
2426 @@ -328,7 +328,7 @@ static void c_stop(struct seq_file *m, v
2427 {
2428 }
2429
2430 -struct seq_operations cpuinfo_op = {
2431 +const struct seq_operations cpuinfo_op = {
2432 .start =c_start,
2433 .next = c_next,
2434 .stop = c_stop,
2435 diff -urNp linux-2.6.31.1/arch/powerpc/kernel/signal_32.c linux-2.6.31.1/arch/powerpc/kernel/signal_32.c
2436 --- linux-2.6.31.1/arch/powerpc/kernel/signal_32.c 2009-09-24 11:45:25.000000000 -0400
2437 +++ linux-2.6.31.1/arch/powerpc/kernel/signal_32.c 2009-10-01 20:12:42.000000000 -0400
2438 @@ -857,7 +857,7 @@ int handle_rt_signal32(unsigned long sig
2439 /* Save user registers on the stack */
2440 frame = &rt_sf->uc.uc_mcontext;
2441 addr = frame;
2442 - if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
2443 + if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
2444 if (save_user_regs(regs, frame, 0, 1))
2445 goto badframe;
2446 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
2447 diff -urNp linux-2.6.31.1/arch/powerpc/kernel/signal_64.c linux-2.6.31.1/arch/powerpc/kernel/signal_64.c
2448 --- linux-2.6.31.1/arch/powerpc/kernel/signal_64.c 2009-09-24 11:45:25.000000000 -0400
2449 +++ linux-2.6.31.1/arch/powerpc/kernel/signal_64.c 2009-10-01 20:12:42.000000000 -0400
2450 @@ -429,7 +429,7 @@ int handle_rt_signal64(int signr, struct
2451 current->thread.fpscr.val = 0;
2452
2453 /* Set up to return from userspace. */
2454 - if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
2455 + if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
2456 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
2457 } else {
2458 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
2459 diff -urNp linux-2.6.31.1/arch/powerpc/kernel/sys_ppc32.c linux-2.6.31.1/arch/powerpc/kernel/sys_ppc32.c
2460 --- linux-2.6.31.1/arch/powerpc/kernel/sys_ppc32.c 2009-09-24 11:45:25.000000000 -0400
2461 +++ linux-2.6.31.1/arch/powerpc/kernel/sys_ppc32.c 2009-10-01 20:12:42.000000000 -0400
2462 @@ -552,10 +552,10 @@ asmlinkage long compat_sys_sysctl(struct
2463 if (oldlenp) {
2464 if (!error) {
2465 if (get_user(oldlen, oldlenp) ||
2466 - put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)))
2467 + put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)) ||
2468 + copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
2469 error = -EFAULT;
2470 }
2471 - copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
2472 }
2473 return error;
2474 }
2475 diff -urNp linux-2.6.31.1/arch/powerpc/kernel/vdso.c linux-2.6.31.1/arch/powerpc/kernel/vdso.c
2476 --- linux-2.6.31.1/arch/powerpc/kernel/vdso.c 2009-09-24 11:45:25.000000000 -0400
2477 +++ linux-2.6.31.1/arch/powerpc/kernel/vdso.c 2009-10-01 20:12:42.000000000 -0400
2478 @@ -35,6 +35,7 @@
2479 #include <asm/firmware.h>
2480 #include <asm/vdso.h>
2481 #include <asm/vdso_datapage.h>
2482 +#include <asm/mman.h>
2483
2484 #include "setup.h"
2485
2486 @@ -211,7 +212,7 @@ int arch_setup_additional_pages(struct l
2487 vdso_base = VDSO32_MBASE;
2488 #endif
2489
2490 - current->mm->context.vdso_base = 0;
2491 + current->mm->context.vdso_base = ~0UL;
2492
2493 /* vDSO has a problem and was disabled, just don't "enable" it for the
2494 * process
2495 @@ -228,7 +229,7 @@ int arch_setup_additional_pages(struct l
2496 */
2497 down_write(&mm->mmap_sem);
2498 vdso_base = get_unmapped_area(NULL, vdso_base,
2499 - vdso_pages << PAGE_SHIFT, 0, 0);
2500 + vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
2501 if (IS_ERR_VALUE(vdso_base)) {
2502 rc = vdso_base;
2503 goto fail_mmapsem;
2504 diff -urNp linux-2.6.31.1/arch/powerpc/kvm/timing.c linux-2.6.31.1/arch/powerpc/kvm/timing.c
2505 --- linux-2.6.31.1/arch/powerpc/kvm/timing.c 2009-09-24 11:45:25.000000000 -0400
2506 +++ linux-2.6.31.1/arch/powerpc/kvm/timing.c 2009-10-01 20:12:42.000000000 -0400
2507 @@ -201,7 +201,7 @@ static int kvmppc_exit_timing_open(struc
2508 return single_open(file, kvmppc_exit_timing_show, inode->i_private);
2509 }
2510
2511 -static struct file_operations kvmppc_exit_timing_fops = {
2512 +static const struct file_operations kvmppc_exit_timing_fops = {
2513 .owner = THIS_MODULE,
2514 .open = kvmppc_exit_timing_open,
2515 .read = seq_read,
2516 diff -urNp linux-2.6.31.1/arch/powerpc/lib/usercopy_64.c linux-2.6.31.1/arch/powerpc/lib/usercopy_64.c
2517 --- linux-2.6.31.1/arch/powerpc/lib/usercopy_64.c 2009-09-24 11:45:25.000000000 -0400
2518 +++ linux-2.6.31.1/arch/powerpc/lib/usercopy_64.c 2009-10-01 20:12:42.000000000 -0400
2519 @@ -9,22 +9,6 @@
2520 #include <linux/module.h>
2521 #include <asm/uaccess.h>
2522
2523 -unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
2524 -{
2525 - if (likely(access_ok(VERIFY_READ, from, n)))
2526 - n = __copy_from_user(to, from, n);
2527 - else
2528 - memset(to, 0, n);
2529 - return n;
2530 -}
2531 -
2532 -unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
2533 -{
2534 - if (likely(access_ok(VERIFY_WRITE, to, n)))
2535 - n = __copy_to_user(to, from, n);
2536 - return n;
2537 -}
2538 -
2539 unsigned long copy_in_user(void __user *to, const void __user *from,
2540 unsigned long n)
2541 {
2542 @@ -35,7 +19,5 @@ unsigned long copy_in_user(void __user *
2543 return n;
2544 }
2545
2546 -EXPORT_SYMBOL(copy_from_user);
2547 -EXPORT_SYMBOL(copy_to_user);
2548 EXPORT_SYMBOL(copy_in_user);
2549
2550 diff -urNp linux-2.6.31.1/arch/powerpc/mm/fault.c linux-2.6.31.1/arch/powerpc/mm/fault.c
2551 --- linux-2.6.31.1/arch/powerpc/mm/fault.c 2009-09-24 11:45:25.000000000 -0400
2552 +++ linux-2.6.31.1/arch/powerpc/mm/fault.c 2009-10-01 20:12:42.000000000 -0400
2553 @@ -30,6 +30,10 @@
2554 #include <linux/kprobes.h>
2555 #include <linux/kdebug.h>
2556 #include <linux/perf_counter.h>
2557 +#include <linux/slab.h>
2558 +#include <linux/pagemap.h>
2559 +#include <linux/compiler.h>
2560 +#include <linux/unistd.h>
2561
2562 #include <asm/firmware.h>
2563 #include <asm/page.h>
2564 @@ -40,6 +44,7 @@
2565 #include <asm/uaccess.h>
2566 #include <asm/tlbflush.h>
2567 #include <asm/siginfo.h>
2568 +#include <asm/ptrace.h>
2569
2570
2571 #ifdef CONFIG_KPROBES
2572 @@ -64,6 +69,33 @@ static inline int notify_page_fault(stru
2573 }
2574 #endif
2575
2576 +#ifdef CONFIG_PAX_PAGEEXEC
2577 +/*
2578 + * PaX: decide what to do with offenders (regs->nip = fault address)
2579 + *
2580 + * returns 1 when task should be killed
2581 + */
2582 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2583 +{
2584 + return 1;
2585 +}
2586 +
2587 +void pax_report_insns(void *pc, void *sp)
2588 +{
2589 + unsigned long i;
2590 +
2591 + printk(KERN_ERR "PAX: bytes at PC: ");
2592 + for (i = 0; i < 5; i++) {
2593 + unsigned int c;
2594 + if (get_user(c, (unsigned int *)pc+i))
2595 + printk(KERN_CONT "???????? ");
2596 + else
2597 + printk(KERN_CONT "%08x ", c);
2598 + }
2599 + printk("\n");
2600 +}
2601 +#endif
2602 +
2603 /*
2604 * Check whether the instruction at regs->nip is a store using
2605 * an update addressing form which will update r1.
2606 @@ -134,7 +166,7 @@ int __kprobes do_page_fault(struct pt_re
2607 * indicate errors in DSISR but can validly be set in SRR1.
2608 */
2609 if (trap == 0x400)
2610 - error_code &= 0x48200000;
2611 + error_code &= 0x58200000;
2612 else
2613 is_write = error_code & DSISR_ISSTORE;
2614 #else
2615 @@ -250,7 +282,7 @@ good_area:
2616 * "undefined". Of those that can be set, this is the only
2617 * one which seems bad.
2618 */
2619 - if (error_code & 0x10000000)
2620 + if (error_code & DSISR_GUARDED)
2621 /* Guarded storage error. */
2622 goto bad_area;
2623 #endif /* CONFIG_8xx */
2624 @@ -265,7 +297,7 @@ good_area:
2625 * processors use the same I/D cache coherency mechanism
2626 * as embedded.
2627 */
2628 - if (error_code & DSISR_PROTFAULT)
2629 + if (error_code & (DSISR_PROTFAULT | DSISR_GUARDED))
2630 goto bad_area;
2631 #endif /* CONFIG_PPC_STD_MMU */
2632
2633 @@ -335,6 +367,23 @@ bad_area:
2634 bad_area_nosemaphore:
2635 /* User mode accesses cause a SIGSEGV */
2636 if (user_mode(regs)) {
2637 +
2638 +#ifdef CONFIG_PAX_PAGEEXEC
2639 + if (mm->pax_flags & MF_PAX_PAGEEXEC) {
2640 +#ifdef CONFIG_PPC_STD_MMU
2641 + if (is_exec && (error_code & (DSISR_PROTFAULT | DSISR_GUARDED))) {
2642 +#else
2643 + if (is_exec && regs->nip == address) {
2644 +#endif
2645 + switch (pax_handle_fetch_fault(regs)) {
2646 + }
2647 +
2648 + pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
2649 + do_group_exit(SIGKILL);
2650 + }
2651 + }
2652 +#endif
2653 +
2654 _exception(SIGSEGV, regs, code, address);
2655 return 0;
2656 }
2657 diff -urNp linux-2.6.31.1/arch/powerpc/mm/mmap_64.c linux-2.6.31.1/arch/powerpc/mm/mmap_64.c
2658 --- linux-2.6.31.1/arch/powerpc/mm/mmap_64.c 2009-09-24 11:45:25.000000000 -0400
2659 +++ linux-2.6.31.1/arch/powerpc/mm/mmap_64.c 2009-10-01 20:12:42.000000000 -0400
2660 @@ -99,10 +99,22 @@ void arch_pick_mmap_layout(struct mm_str
2661 */
2662 if (mmap_is_legacy()) {
2663 mm->mmap_base = TASK_UNMAPPED_BASE;
2664 +
2665 +#ifdef CONFIG_PAX_RANDMMAP
2666 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2667 + mm->mmap_base += mm->delta_mmap;
2668 +#endif
2669 +
2670 mm->get_unmapped_area = arch_get_unmapped_area;
2671 mm->unmap_area = arch_unmap_area;
2672 } else {
2673 mm->mmap_base = mmap_base();
2674 +
2675 +#ifdef CONFIG_PAX_RANDMMAP
2676 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2677 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2678 +#endif
2679 +
2680 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2681 mm->unmap_area = arch_unmap_area_topdown;
2682 }
2683 diff -urNp linux-2.6.31.1/arch/powerpc/mm/slice.c linux-2.6.31.1/arch/powerpc/mm/slice.c
2684 --- linux-2.6.31.1/arch/powerpc/mm/slice.c 2009-09-24 11:45:25.000000000 -0400
2685 +++ linux-2.6.31.1/arch/powerpc/mm/slice.c 2009-10-01 20:12:42.000000000 -0400
2686 @@ -426,6 +426,11 @@ unsigned long slice_get_unmapped_area(un
2687 if (fixed && addr > (mm->task_size - len))
2688 return -EINVAL;
2689
2690 +#ifdef CONFIG_PAX_RANDMMAP
2691 + if (!fixed && (mm->pax_flags & MF_PAX_RANDMMAP))
2692 + addr = 0;
2693 +#endif
2694 +
2695 /* If hint, make sure it matches our alignment restrictions */
2696 if (!fixed && addr) {
2697 addr = _ALIGN_UP(addr, 1ul << pshift);
2698 diff -urNp linux-2.6.31.1/arch/powerpc/platforms/cell/spufs/file.c linux-2.6.31.1/arch/powerpc/platforms/cell/spufs/file.c
2699 --- linux-2.6.31.1/arch/powerpc/platforms/cell/spufs/file.c 2009-09-24 11:45:25.000000000 -0400
2700 +++ linux-2.6.31.1/arch/powerpc/platforms/cell/spufs/file.c 2009-10-01 20:12:42.000000000 -0400
2701 @@ -147,7 +147,7 @@ static int __fops ## _open(struct inode
2702 __simple_attr_check_format(__fmt, 0ull); \
2703 return spufs_attr_open(inode, file, __get, __set, __fmt); \
2704 } \
2705 -static struct file_operations __fops = { \
2706 +static const struct file_operations __fops = { \
2707 .owner = THIS_MODULE, \
2708 .open = __fops ## _open, \
2709 .release = spufs_attr_release, \
2710 @@ -309,7 +309,7 @@ static int spufs_mem_mmap_access(struct
2711 return len;
2712 }
2713
2714 -static struct vm_operations_struct spufs_mem_mmap_vmops = {
2715 +static const struct vm_operations_struct spufs_mem_mmap_vmops = {
2716 .fault = spufs_mem_mmap_fault,
2717 .access = spufs_mem_mmap_access,
2718 };
2719 @@ -436,7 +436,7 @@ static int spufs_cntl_mmap_fault(struct
2720 return spufs_ps_fault(vma, vmf, 0x4000, SPUFS_CNTL_MAP_SIZE);
2721 }
2722
2723 -static struct vm_operations_struct spufs_cntl_mmap_vmops = {
2724 +static const struct vm_operations_struct spufs_cntl_mmap_vmops = {
2725 .fault = spufs_cntl_mmap_fault,
2726 };
2727
2728 @@ -1143,7 +1143,7 @@ spufs_signal1_mmap_fault(struct vm_area_
2729 #endif
2730 }
2731
2732 -static struct vm_operations_struct spufs_signal1_mmap_vmops = {
2733 +static const struct vm_operations_struct spufs_signal1_mmap_vmops = {
2734 .fault = spufs_signal1_mmap_fault,
2735 };
2736
2737 @@ -1279,7 +1279,7 @@ spufs_signal2_mmap_fault(struct vm_area_
2738 #endif
2739 }
2740
2741 -static struct vm_operations_struct spufs_signal2_mmap_vmops = {
2742 +static const struct vm_operations_struct spufs_signal2_mmap_vmops = {
2743 .fault = spufs_signal2_mmap_fault,
2744 };
2745
2746 @@ -1397,7 +1397,7 @@ spufs_mss_mmap_fault(struct vm_area_stru
2747 return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_MSS_MAP_SIZE);
2748 }
2749
2750 -static struct vm_operations_struct spufs_mss_mmap_vmops = {
2751 +static const struct vm_operations_struct spufs_mss_mmap_vmops = {
2752 .fault = spufs_mss_mmap_fault,
2753 };
2754
2755 @@ -1458,7 +1458,7 @@ spufs_psmap_mmap_fault(struct vm_area_st
2756 return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_PS_MAP_SIZE);
2757 }
2758
2759 -static struct vm_operations_struct spufs_psmap_mmap_vmops = {
2760 +static const struct vm_operations_struct spufs_psmap_mmap_vmops = {
2761 .fault = spufs_psmap_mmap_fault,
2762 };
2763
2764 @@ -1517,7 +1517,7 @@ spufs_mfc_mmap_fault(struct vm_area_stru
2765 return spufs_ps_fault(vma, vmf, 0x3000, SPUFS_MFC_MAP_SIZE);
2766 }
2767
2768 -static struct vm_operations_struct spufs_mfc_mmap_vmops = {
2769 +static const struct vm_operations_struct spufs_mfc_mmap_vmops = {
2770 .fault = spufs_mfc_mmap_fault,
2771 };
2772
2773 diff -urNp linux-2.6.31.1/arch/powerpc/platforms/pseries/dtl.c linux-2.6.31.1/arch/powerpc/platforms/pseries/dtl.c
2774 --- linux-2.6.31.1/arch/powerpc/platforms/pseries/dtl.c 2009-09-24 11:45:25.000000000 -0400
2775 +++ linux-2.6.31.1/arch/powerpc/platforms/pseries/dtl.c 2009-10-01 20:12:42.000000000 -0400
2776 @@ -209,7 +209,7 @@ static ssize_t dtl_file_read(struct file
2777 return n_read * sizeof(struct dtl_entry);
2778 }
2779
2780 -static struct file_operations dtl_fops = {
2781 +static const struct file_operations dtl_fops = {
2782 .open = dtl_file_open,
2783 .release = dtl_file_release,
2784 .read = dtl_file_read,
2785 diff -urNp linux-2.6.31.1/arch/powerpc/platforms/pseries/hvCall_inst.c linux-2.6.31.1/arch/powerpc/platforms/pseries/hvCall_inst.c
2786 --- linux-2.6.31.1/arch/powerpc/platforms/pseries/hvCall_inst.c 2009-09-24 11:45:25.000000000 -0400
2787 +++ linux-2.6.31.1/arch/powerpc/platforms/pseries/hvCall_inst.c 2009-10-01 20:12:42.000000000 -0400
2788 @@ -71,7 +71,7 @@ static int hc_show(struct seq_file *m, v
2789 return 0;
2790 }
2791
2792 -static struct seq_operations hcall_inst_seq_ops = {
2793 +static const struct seq_operations hcall_inst_seq_ops = {
2794 .start = hc_start,
2795 .next = hc_next,
2796 .stop = hc_stop,
2797 diff -urNp linux-2.6.31.1/arch/s390/hypfs/inode.c linux-2.6.31.1/arch/s390/hypfs/inode.c
2798 --- linux-2.6.31.1/arch/s390/hypfs/inode.c 2009-09-24 11:45:25.000000000 -0400
2799 +++ linux-2.6.31.1/arch/s390/hypfs/inode.c 2009-10-01 20:12:42.000000000 -0400
2800 @@ -41,7 +41,7 @@ struct hypfs_sb_info {
2801
2802 static const struct file_operations hypfs_file_ops;
2803 static struct file_system_type hypfs_type;
2804 -static struct super_operations hypfs_s_ops;
2805 +static const struct super_operations hypfs_s_ops;
2806
2807 /* start of list of all dentries, which have to be deleted on update */
2808 static struct dentry *hypfs_last_dentry;
2809 @@ -476,7 +476,7 @@ static struct file_system_type hypfs_typ
2810 .kill_sb = hypfs_kill_super
2811 };
2812
2813 -static struct super_operations hypfs_s_ops = {
2814 +static const struct super_operations hypfs_s_ops = {
2815 .statfs = simple_statfs,
2816 .drop_inode = hypfs_drop_inode,
2817 .show_options = hypfs_show_options,
2818 diff -urNp linux-2.6.31.1/arch/s390/include/asm/atomic.h linux-2.6.31.1/arch/s390/include/asm/atomic.h
2819 --- linux-2.6.31.1/arch/s390/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
2820 +++ linux-2.6.31.1/arch/s390/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
2821 @@ -71,19 +71,31 @@ static inline int atomic_read(const atom
2822 return v->counter;
2823 }
2824
2825 +static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
2826 +{
2827 + return atomic_read((const atomic_t *)v);
2828 +}
2829 +
2830 static inline void atomic_set(atomic_t *v, int i)
2831 {
2832 v->counter = i;
2833 barrier();
2834 }
2835
2836 +static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
2837 +{
2838 + atomic_set((atomic_t *)v, i);
2839 +}
2840 +
2841 static __inline__ int atomic_add_return(int i, atomic_t * v)
2842 {
2843 return __CS_LOOP(v, i, "ar");
2844 }
2845 #define atomic_add(_i, _v) atomic_add_return(_i, _v)
2846 +#define atomic_add_unchecked(_i, _v) atomic_add((_i), (atomic_t *)(_v))
2847 #define atomic_add_negative(_i, _v) (atomic_add_return(_i, _v) < 0)
2848 #define atomic_inc(_v) atomic_add_return(1, _v)
2849 +#define atomic_inc_unchecked(_v) atomic_inc((atomic_t *)(_v))
2850 #define atomic_inc_return(_v) atomic_add_return(1, _v)
2851 #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0)
2852
2853 @@ -92,6 +104,7 @@ static __inline__ int atomic_sub_return(
2854 return __CS_LOOP(v, i, "sr");
2855 }
2856 #define atomic_sub(_i, _v) atomic_sub_return(_i, _v)
2857 +#define atomic_sub_unchecked(_i, _v) atomic_sub((_i), (atomic_t *)(_v))
2858 #define atomic_sub_and_test(_i, _v) (atomic_sub_return(_i, _v) == 0)
2859 #define atomic_dec(_v) atomic_sub_return(1, _v)
2860 #define atomic_dec_return(_v) atomic_sub_return(1, _v)
2861 diff -urNp linux-2.6.31.1/arch/s390/include/asm/uaccess.h linux-2.6.31.1/arch/s390/include/asm/uaccess.h
2862 --- linux-2.6.31.1/arch/s390/include/asm/uaccess.h 2009-09-24 11:45:25.000000000 -0400
2863 +++ linux-2.6.31.1/arch/s390/include/asm/uaccess.h 2009-10-01 20:12:42.000000000 -0400
2864 @@ -232,6 +232,10 @@ static inline unsigned long __must_check
2865 copy_to_user(void __user *to, const void *from, unsigned long n)
2866 {
2867 might_fault();
2868 +
2869 + if ((long)n < 0)
2870 + return n;
2871 +
2872 if (access_ok(VERIFY_WRITE, to, n))
2873 n = __copy_to_user(to, from, n);
2874 return n;
2875 @@ -257,6 +261,9 @@ copy_to_user(void __user *to, const void
2876 static inline unsigned long __must_check
2877 __copy_from_user(void *to, const void __user *from, unsigned long n)
2878 {
2879 + if ((long)n < 0)
2880 + return n;
2881 +
2882 if (__builtin_constant_p(n) && (n <= 256))
2883 return uaccess.copy_from_user_small(n, from, to);
2884 else
2885 @@ -283,6 +290,10 @@ static inline unsigned long __must_check
2886 copy_from_user(void *to, const void __user *from, unsigned long n)
2887 {
2888 might_fault();
2889 +
2890 + if ((long)n < 0)
2891 + return n;
2892 +
2893 if (access_ok(VERIFY_READ, from, n))
2894 n = __copy_from_user(to, from, n);
2895 else
2896 diff -urNp linux-2.6.31.1/arch/s390/kernel/module.c linux-2.6.31.1/arch/s390/kernel/module.c
2897 --- linux-2.6.31.1/arch/s390/kernel/module.c 2009-09-24 11:45:25.000000000 -0400
2898 +++ linux-2.6.31.1/arch/s390/kernel/module.c 2009-10-01 20:12:42.000000000 -0400
2899 @@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
2900
2901 /* Increase core size by size of got & plt and set start
2902 offsets for got and plt. */
2903 - me->core_size = ALIGN(me->core_size, 4);
2904 - me->arch.got_offset = me->core_size;
2905 - me->core_size += me->arch.got_size;
2906 - me->arch.plt_offset = me->core_size;
2907 - me->core_size += me->arch.plt_size;
2908 + me->core_size_rw = ALIGN(me->core_size_rw, 4);
2909 + me->arch.got_offset = me->core_size_rw;
2910 + me->core_size_rw += me->arch.got_size;
2911 + me->arch.plt_offset = me->core_size_rx;
2912 + me->core_size_rx += me->arch.plt_size;
2913 return 0;
2914 }
2915
2916 @@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2917 if (info->got_initialized == 0) {
2918 Elf_Addr *gotent;
2919
2920 - gotent = me->module_core + me->arch.got_offset +
2921 + gotent = me->module_core_rw + me->arch.got_offset +
2922 info->got_offset;
2923 *gotent = val;
2924 info->got_initialized = 1;
2925 @@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2926 else if (r_type == R_390_GOTENT ||
2927 r_type == R_390_GOTPLTENT)
2928 *(unsigned int *) loc =
2929 - (val + (Elf_Addr) me->module_core - loc) >> 1;
2930 + (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
2931 else if (r_type == R_390_GOT64 ||
2932 r_type == R_390_GOTPLT64)
2933 *(unsigned long *) loc = val;
2934 @@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2935 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
2936 if (info->plt_initialized == 0) {
2937 unsigned int *ip;
2938 - ip = me->module_core + me->arch.plt_offset +
2939 + ip = me->module_core_rx + me->arch.plt_offset +
2940 info->plt_offset;
2941 #ifndef CONFIG_64BIT
2942 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
2943 @@ -317,7 +317,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2944 val - loc + 0xffffUL < 0x1ffffeUL) ||
2945 (r_type == R_390_PLT32DBL &&
2946 val - loc + 0xffffffffULL < 0x1fffffffeULL)))
2947 - val = (Elf_Addr) me->module_core +
2948 + val = (Elf_Addr) me->module_core_rx +
2949 me->arch.plt_offset +
2950 info->plt_offset;
2951 val += rela->r_addend - loc;
2952 @@ -339,7 +339,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2953 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
2954 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
2955 val = val + rela->r_addend -
2956 - ((Elf_Addr) me->module_core + me->arch.got_offset);
2957 + ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
2958 if (r_type == R_390_GOTOFF16)
2959 *(unsigned short *) loc = val;
2960 else if (r_type == R_390_GOTOFF32)
2961 @@ -349,7 +349,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2962 break;
2963 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
2964 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
2965 - val = (Elf_Addr) me->module_core + me->arch.got_offset +
2966 + val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
2967 rela->r_addend - loc;
2968 if (r_type == R_390_GOTPC)
2969 *(unsigned int *) loc = val;
2970 diff -urNp linux-2.6.31.1/arch/sh/include/asm/atomic.h linux-2.6.31.1/arch/sh/include/asm/atomic.h
2971 --- linux-2.6.31.1/arch/sh/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
2972 +++ linux-2.6.31.1/arch/sh/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
2973 @@ -14,7 +14,9 @@
2974 #define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
2975
2976 #define atomic_read(v) ((v)->counter)
2977 +#define atomic_read_unchecked(v) ((v)->counter)
2978 #define atomic_set(v,i) ((v)->counter = (i))
2979 +#define atomic_set_unchecked(v,i) ((v)->counter = (i))
2980
2981 #if defined(CONFIG_GUSA_RB)
2982 #include <asm/atomic-grb.h>
2983 @@ -43,6 +45,9 @@
2984 #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
2985
2986 #define atomic_inc(v) atomic_add(1,(v))
2987 +#define atomic_inc_unchecked(v) atomic_inc((atomic_t *)(v))
2988 +#define atomic_add_unchecked(i,v) atomic_add((i),(atomic_t *)(v))
2989 +#define atomic_sub_unchecked(i,v) atomic_sub((i),(atomic_t *)(v))
2990 #define atomic_dec(v) atomic_sub(1,(v))
2991
2992 #if !defined(CONFIG_GUSA_RB) && !defined(CONFIG_CPU_SH4A)
2993 diff -urNp linux-2.6.31.1/arch/sparc/include/asm/atomic_32.h linux-2.6.31.1/arch/sparc/include/asm/atomic_32.h
2994 --- linux-2.6.31.1/arch/sparc/include/asm/atomic_32.h 2009-09-24 11:45:25.000000000 -0400
2995 +++ linux-2.6.31.1/arch/sparc/include/asm/atomic_32.h 2009-10-01 20:12:42.000000000 -0400
2996 @@ -24,12 +24,17 @@ extern int atomic_cmpxchg(atomic_t *, in
2997 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
2998 extern int atomic_add_unless(atomic_t *, int, int);
2999 extern void atomic_set(atomic_t *, int);
3000 +extern void atomic_set_unchecked(atomic_unchecked_t *, int);
3001
3002 #define atomic_read(v) ((v)->counter)
3003 +#define atomic_read_unchecked(v) ((v)->counter)
3004
3005 #define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v)))
3006 +#define atomic_add_unchecked(i, v) atomic_add((i), (atomic_t *)(v))
3007 #define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v)))
3008 +#define atomic_sub_unchecked(i, v) atomic_sub((i), (atomic_t *)(v))
3009 #define atomic_inc(v) ((void)__atomic_add_return( 1, (v)))
3010 +#define atomic_inc_unchecked(v) atomic_inc((atomic_t *)(v))
3011 #define atomic_dec(v) ((void)__atomic_add_return( -1, (v)))
3012
3013 #define atomic_add_return(i, v) (__atomic_add_return( (int)(i), (v)))
3014 diff -urNp linux-2.6.31.1/arch/sparc/include/asm/atomic_64.h linux-2.6.31.1/arch/sparc/include/asm/atomic_64.h
3015 --- linux-2.6.31.1/arch/sparc/include/asm/atomic_64.h 2009-09-24 11:45:25.000000000 -0400
3016 +++ linux-2.6.31.1/arch/sparc/include/asm/atomic_64.h 2009-10-01 20:12:42.000000000 -0400
3017 @@ -14,14 +14,18 @@
3018 #define ATOMIC64_INIT(i) { (i) }
3019
3020 #define atomic_read(v) ((v)->counter)
3021 +#define atomic_read_unchecked(v) ((v)->counter)
3022 #define atomic64_read(v) ((v)->counter)
3023
3024 #define atomic_set(v, i) (((v)->counter) = i)
3025 +#define atomic_set_unchecked(v, i) (((v)->counter) = i)
3026 #define atomic64_set(v, i) (((v)->counter) = i)
3027
3028 extern void atomic_add(int, atomic_t *);
3029 +extern void atomic_add_unchecked(int, atomic_unchecked_t *);
3030 extern void atomic64_add(int, atomic64_t *);
3031 extern void atomic_sub(int, atomic_t *);
3032 +extern void atomic_sub_unchecked(int, atomic_unchecked_t *);
3033 extern void atomic64_sub(int, atomic64_t *);
3034
3035 extern int atomic_add_ret(int, atomic_t *);
3036 @@ -59,6 +63,7 @@ extern int atomic64_sub_ret(int, atomic6
3037 #define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0)
3038
3039 #define atomic_inc(v) atomic_add(1, v)
3040 +#define atomic_inc_unchecked(v) atomic_add_unchecked(1, v)
3041 #define atomic64_inc(v) atomic64_add(1, v)
3042
3043 #define atomic_dec(v) atomic_sub(1, v)
3044 @@ -72,17 +77,28 @@ extern int atomic64_sub_ret(int, atomic6
3045
3046 static inline int atomic_add_unless(atomic_t *v, int a, int u)
3047 {
3048 - int c, old;
3049 + int c, old, new;
3050 c = atomic_read(v);
3051 for (;;) {
3052 - if (unlikely(c == (u)))
3053 + if (unlikely(c == u))
3054 break;
3055 - old = atomic_cmpxchg((v), c, c + (a));
3056 +
3057 + asm volatile("addcc %2, %0, %0\n"
3058 +
3059 +#ifdef CONFIG_PAX_REFCOUNT
3060 + "tvs %%icc, 6\n"
3061 +#endif
3062 +
3063 + : "=r" (new)
3064 + : "0" (c), "ir" (a)
3065 + : "cc");
3066 +
3067 + old = atomic_cmpxchg(v, c, new);
3068 if (likely(old == c))
3069 break;
3070 c = old;
3071 }
3072 - return c != (u);
3073 + return c != u;
3074 }
3075
3076 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
3077 @@ -93,17 +109,28 @@ static inline int atomic_add_unless(atom
3078
3079 static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
3080 {
3081 - long c, old;
3082 + long c, old, new;
3083 c = atomic64_read(v);
3084 for (;;) {
3085 - if (unlikely(c == (u)))
3086 + if (unlikely(c == u))
3087 break;
3088 - old = atomic64_cmpxchg((v), c, c + (a));
3089 +
3090 + asm volatile("addcc %2, %0, %0\n"
3091 +
3092 +#ifdef CONFIG_PAX_REFCOUNT
3093 + "tvs %%xcc, 6\n"
3094 +#endif
3095 +
3096 + : "=r" (new)
3097 + : "0" (c), "ir" (a)
3098 + : "cc");
3099 +
3100 + old = atomic64_cmpxchg(v, c, new);
3101 if (likely(old == c))
3102 break;
3103 c = old;
3104 }
3105 - return c != (u);
3106 + return c != u;
3107 }
3108
3109 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
3110 diff -urNp linux-2.6.31.1/arch/sparc/include/asm/elf_32.h linux-2.6.31.1/arch/sparc/include/asm/elf_32.h
3111 --- linux-2.6.31.1/arch/sparc/include/asm/elf_32.h 2009-09-24 11:45:25.000000000 -0400
3112 +++ linux-2.6.31.1/arch/sparc/include/asm/elf_32.h 2009-10-01 20:12:42.000000000 -0400
3113 @@ -116,6 +116,13 @@ typedef struct {
3114
3115 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
3116
3117 +#ifdef CONFIG_PAX_ASLR
3118 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
3119 +
3120 +#define PAX_DELTA_MMAP_LEN 16
3121 +#define PAX_DELTA_STACK_LEN 16
3122 +#endif
3123 +
3124 /* This yields a mask that user programs can use to figure out what
3125 instruction set this cpu supports. This can NOT be done in userspace
3126 on Sparc. */
3127 diff -urNp linux-2.6.31.1/arch/sparc/include/asm/elf_64.h linux-2.6.31.1/arch/sparc/include/asm/elf_64.h
3128 --- linux-2.6.31.1/arch/sparc/include/asm/elf_64.h 2009-09-24 11:45:25.000000000 -0400
3129 +++ linux-2.6.31.1/arch/sparc/include/asm/elf_64.h 2009-10-01 20:12:42.000000000 -0400
3130 @@ -163,6 +163,12 @@ typedef struct {
3131 #define ELF_ET_DYN_BASE 0x0000010000000000UL
3132 #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
3133
3134 +#ifdef CONFIG_PAX_ASLR
3135 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
3136 +
3137 +#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
3138 +#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
3139 +#endif
3140
3141 /* This yields a mask that user programs can use to figure out what
3142 instruction set this cpu supports. */
3143 diff -urNp linux-2.6.31.1/arch/sparc/include/asm/pgtable_32.h linux-2.6.31.1/arch/sparc/include/asm/pgtable_32.h
3144 --- linux-2.6.31.1/arch/sparc/include/asm/pgtable_32.h 2009-09-24 11:45:25.000000000 -0400
3145 +++ linux-2.6.31.1/arch/sparc/include/asm/pgtable_32.h 2009-10-01 20:12:42.000000000 -0400
3146 @@ -43,6 +43,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
3147 BTFIXUPDEF_INT(page_none)
3148 BTFIXUPDEF_INT(page_copy)
3149 BTFIXUPDEF_INT(page_readonly)
3150 +
3151 +#ifdef CONFIG_PAX_PAGEEXEC
3152 +BTFIXUPDEF_INT(page_shared_noexec)
3153 +BTFIXUPDEF_INT(page_copy_noexec)
3154 +BTFIXUPDEF_INT(page_readonly_noexec)
3155 +#endif
3156 +
3157 BTFIXUPDEF_INT(page_kernel)
3158
3159 #define PMD_SHIFT SUN4C_PMD_SHIFT
3160 @@ -64,6 +71,16 @@ extern pgprot_t PAGE_SHARED;
3161 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
3162 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
3163
3164 +#ifdef CONFIG_PAX_PAGEEXEC
3165 +extern pgprot_t PAGE_SHARED_NOEXEC;
3166 +# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
3167 +# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
3168 +#else
3169 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
3170 +# define PAGE_COPY_NOEXEC PAGE_COPY
3171 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
3172 +#endif
3173 +
3174 extern unsigned long page_kernel;
3175
3176 #ifdef MODULE
3177 diff -urNp linux-2.6.31.1/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.31.1/arch/sparc/include/asm/pgtsrmmu.h
3178 --- linux-2.6.31.1/arch/sparc/include/asm/pgtsrmmu.h 2009-09-24 11:45:25.000000000 -0400
3179 +++ linux-2.6.31.1/arch/sparc/include/asm/pgtsrmmu.h 2009-10-01 20:12:42.000000000 -0400
3180 @@ -115,6 +115,13 @@
3181 SRMMU_EXEC | SRMMU_REF)
3182 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
3183 SRMMU_EXEC | SRMMU_REF)
3184 +
3185 +#ifdef CONFIG_PAX_PAGEEXEC
3186 +#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
3187 +#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
3188 +#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
3189 +#endif
3190 +
3191 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
3192 SRMMU_DIRTY | SRMMU_REF)
3193
3194 diff -urNp linux-2.6.31.1/arch/sparc/include/asm/spinlock_64.h linux-2.6.31.1/arch/sparc/include/asm/spinlock_64.h
3195 --- linux-2.6.31.1/arch/sparc/include/asm/spinlock_64.h 2009-09-24 11:45:25.000000000 -0400
3196 +++ linux-2.6.31.1/arch/sparc/include/asm/spinlock_64.h 2009-10-01 20:12:42.000000000 -0400
3197 @@ -99,7 +99,12 @@ static void inline __read_lock(raw_rwloc
3198 __asm__ __volatile__ (
3199 "1: ldsw [%2], %0\n"
3200 " brlz,pn %0, 2f\n"
3201 -"4: add %0, 1, %1\n"
3202 +"4: addcc %0, 1, %1\n"
3203 +
3204 +#ifdef CONFIG_PAX_REFCOUNT
3205 +" tvs %%icc, 6\n"
3206 +#endif
3207 +
3208 " cas [%2], %0, %1\n"
3209 " cmp %0, %1\n"
3210 " bne,pn %%icc, 1b\n"
3211 @@ -112,7 +117,7 @@ static void inline __read_lock(raw_rwloc
3212 " .previous"
3213 : "=&r" (tmp1), "=&r" (tmp2)
3214 : "r" (lock)
3215 - : "memory");
3216 + : "memory", "cc");
3217 }
3218
3219 static int inline __read_trylock(raw_rwlock_t *lock)
3220 @@ -123,7 +128,12 @@ static int inline __read_trylock(raw_rwl
3221 "1: ldsw [%2], %0\n"
3222 " brlz,a,pn %0, 2f\n"
3223 " mov 0, %0\n"
3224 -" add %0, 1, %1\n"
3225 +" addcc %0, 1, %1\n"
3226 +
3227 +#ifdef CONFIG_PAX_REFCOUNT
3228 +" tvs %%icc, 6\n"
3229 +#endif
3230 +
3231 " cas [%2], %0, %1\n"
3232 " cmp %0, %1\n"
3233 " bne,pn %%icc, 1b\n"
3234 @@ -142,7 +152,12 @@ static void inline __read_unlock(raw_rwl
3235
3236 __asm__ __volatile__(
3237 "1: lduw [%2], %0\n"
3238 -" sub %0, 1, %1\n"
3239 +" subcc %0, 1, %1\n"
3240 +
3241 +#ifdef CONFIG_PAX_REFCOUNT
3242 +" tvs %%icc, 6\n"
3243 +#endif
3244 +
3245 " cas [%2], %0, %1\n"
3246 " cmp %0, %1\n"
3247 " bne,pn %%xcc, 1b\n"
3248 diff -urNp linux-2.6.31.1/arch/sparc/include/asm/uaccess_32.h linux-2.6.31.1/arch/sparc/include/asm/uaccess_32.h
3249 --- linux-2.6.31.1/arch/sparc/include/asm/uaccess_32.h 2009-09-24 11:45:25.000000000 -0400
3250 +++ linux-2.6.31.1/arch/sparc/include/asm/uaccess_32.h 2009-10-01 20:12:42.000000000 -0400
3251 @@ -249,27 +249,49 @@ extern unsigned long __copy_user(void __
3252
3253 static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
3254 {
3255 - if (n && __access_ok((unsigned long) to, n))
3256 + if ((long)n < 0)
3257 + return n;
3258 +
3259 + if (n && __access_ok((unsigned long) to, n)) {
3260 + if (!__builtin_constant_p(n))
3261 + check_object_size(from, n, true);
3262 return __copy_user(to, (__force void __user *) from, n);
3263 - else
3264 + } else
3265 return n;
3266 }
3267
3268 static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
3269 {
3270 + if ((long)n < 0)
3271 + return n;
3272 +
3273 + if (!__builtin_constant_p(n))
3274 + check_object_size(from, n, true);
3275 +
3276 return __copy_user(to, (__force void __user *) from, n);
3277 }
3278
3279 static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
3280 {
3281 - if (n && __access_ok((unsigned long) from, n))
3282 + if ((long)n < 0)
3283 + return n;
3284 +
3285 + if (n && __access_ok((unsigned long) from, n)) {
3286 + if (!__builtin_constant_p(n))
3287 + check_object_size(to, n, false);
3288 return __copy_user((__force void __user *) to, from, n);
3289 - else
3290 + } else
3291 return n;
3292 }
3293
3294 static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
3295 {
3296 + if ((long)n < 0)
3297 + return n;
3298 +
3299 + if (!__builtin_constant_p(n))
3300 + check_object_size(to, n, false);
3301 +
3302 return __copy_user((__force void __user *) to, from, n);
3303 }
3304
3305 diff -urNp linux-2.6.31.1/arch/sparc/include/asm/uaccess_64.h linux-2.6.31.1/arch/sparc/include/asm/uaccess_64.h
3306 --- linux-2.6.31.1/arch/sparc/include/asm/uaccess_64.h 2009-09-24 11:45:25.000000000 -0400
3307 +++ linux-2.6.31.1/arch/sparc/include/asm/uaccess_64.h 2009-10-01 20:12:42.000000000 -0400
3308 @@ -212,7 +212,15 @@ extern unsigned long copy_from_user_fixu
3309 static inline unsigned long __must_check
3310 copy_from_user(void *to, const void __user *from, unsigned long size)
3311 {
3312 - unsigned long ret = ___copy_from_user(to, from, size);
3313 + unsigned long ret;
3314 +
3315 + if (unlikely(((long)size > INT_MAX) || ((long)size < 0)))
3316 + return size;
3317 +
3318 + if (!__builtin_constant_p(size))
3319 + check_object_size(to, size, false);
3320 +
3321 + ret = ___copy_from_user(to, from, size);
3322
3323 if (unlikely(ret))
3324 ret = copy_from_user_fixup(to, from, size);
3325 @@ -228,7 +236,15 @@ extern unsigned long copy_to_user_fixup(
3326 static inline unsigned long __must_check
3327 copy_to_user(void __user *to, const void *from, unsigned long size)
3328 {
3329 - unsigned long ret = ___copy_to_user(to, from, size);
3330 + unsigned long ret;
3331 +
3332 + if (unlikely(((long)size > INT_MAX) || ((long)size < 0)))
3333 + return size;
3334 +
3335 + if (!__builtin_constant_p(size))
3336 + check_object_size(from, size, true);
3337 +
3338 + ret = ___copy_to_user(to, from, size);
3339
3340 if (unlikely(ret))
3341 ret = copy_to_user_fixup(to, from, size);
3342 diff -urNp linux-2.6.31.1/arch/sparc/kernel/Makefile linux-2.6.31.1/arch/sparc/kernel/Makefile
3343 --- linux-2.6.31.1/arch/sparc/kernel/Makefile 2009-09-24 11:45:25.000000000 -0400
3344 +++ linux-2.6.31.1/arch/sparc/kernel/Makefile 2009-10-01 20:12:42.000000000 -0400
3345 @@ -3,7 +3,7 @@
3346 #
3347
3348 asflags-y := -ansi
3349 -ccflags-y := -Werror
3350 +#ccflags-y := -Werror
3351
3352 extra-y := head_$(BITS).o
3353 extra-y += init_task.o
3354 diff -urNp linux-2.6.31.1/arch/sparc/kernel/sys_sparc_32.c linux-2.6.31.1/arch/sparc/kernel/sys_sparc_32.c
3355 --- linux-2.6.31.1/arch/sparc/kernel/sys_sparc_32.c 2009-09-24 11:45:25.000000000 -0400
3356 +++ linux-2.6.31.1/arch/sparc/kernel/sys_sparc_32.c 2009-10-01 20:12:42.000000000 -0400
3357 @@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
3358 if (ARCH_SUN4C && len > 0x20000000)
3359 return -ENOMEM;
3360 if (!addr)
3361 - addr = TASK_UNMAPPED_BASE;
3362 + addr = current->mm->mmap_base;
3363
3364 if (flags & MAP_SHARED)
3365 addr = COLOUR_ALIGN(addr);
3366 diff -urNp linux-2.6.31.1/arch/sparc/kernel/sys_sparc_64.c linux-2.6.31.1/arch/sparc/kernel/sys_sparc_64.c
3367 --- linux-2.6.31.1/arch/sparc/kernel/sys_sparc_64.c 2009-09-24 11:45:25.000000000 -0400
3368 +++ linux-2.6.31.1/arch/sparc/kernel/sys_sparc_64.c 2009-10-01 20:12:42.000000000 -0400
3369 @@ -125,7 +125,7 @@ unsigned long arch_get_unmapped_area(str
3370 /* We do not accept a shared mapping if it would violate
3371 * cache aliasing constraints.
3372 */
3373 - if ((flags & MAP_SHARED) &&
3374 + if ((filp || (flags & MAP_SHARED)) &&
3375 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
3376 return -EINVAL;
3377 return addr;
3378 @@ -140,6 +140,10 @@ unsigned long arch_get_unmapped_area(str
3379 if (filp || (flags & MAP_SHARED))
3380 do_color_align = 1;
3381
3382 +#ifdef CONFIG_PAX_RANDMMAP
3383 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
3384 +#endif
3385 +
3386 if (addr) {
3387 if (do_color_align)
3388 addr = COLOUR_ALIGN(addr, pgoff);
3389 @@ -153,9 +157,9 @@ unsigned long arch_get_unmapped_area(str
3390 }
3391
3392 if (len > mm->cached_hole_size) {
3393 - start_addr = addr = mm->free_area_cache;
3394 + start_addr = addr = mm->free_area_cache;
3395 } else {
3396 - start_addr = addr = TASK_UNMAPPED_BASE;
3397 + start_addr = addr = mm->mmap_base;
3398 mm->cached_hole_size = 0;
3399 }
3400
3401 @@ -175,8 +179,8 @@ full_search:
3402 vma = find_vma(mm, VA_EXCLUDE_END);
3403 }
3404 if (unlikely(task_size < addr)) {
3405 - if (start_addr != TASK_UNMAPPED_BASE) {
3406 - start_addr = addr = TASK_UNMAPPED_BASE;
3407 + if (start_addr != mm->mmap_base) {
3408 + start_addr = addr = mm->mmap_base;
3409 mm->cached_hole_size = 0;
3410 goto full_search;
3411 }
3412 @@ -216,7 +220,7 @@ arch_get_unmapped_area_topdown(struct fi
3413 /* We do not accept a shared mapping if it would violate
3414 * cache aliasing constraints.
3415 */
3416 - if ((flags & MAP_SHARED) &&
3417 + if ((filp || (flags & MAP_SHARED)) &&
3418 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
3419 return -EINVAL;
3420 return addr;
3421 @@ -380,6 +384,12 @@ void arch_pick_mmap_layout(struct mm_str
3422 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
3423 sysctl_legacy_va_layout) {
3424 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
3425 +
3426 +#ifdef CONFIG_PAX_RANDMMAP
3427 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3428 + mm->mmap_base += mm->delta_mmap;
3429 +#endif
3430 +
3431 mm->get_unmapped_area = arch_get_unmapped_area;
3432 mm->unmap_area = arch_unmap_area;
3433 } else {
3434 @@ -394,6 +404,12 @@ void arch_pick_mmap_layout(struct mm_str
3435 gap = (task_size / 6 * 5);
3436
3437 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
3438 +
3439 +#ifdef CONFIG_PAX_RANDMMAP
3440 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3441 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3442 +#endif
3443 +
3444 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3445 mm->unmap_area = arch_unmap_area_topdown;
3446 }
3447 diff -urNp linux-2.6.31.1/arch/sparc/kernel/traps_64.c linux-2.6.31.1/arch/sparc/kernel/traps_64.c
3448 --- linux-2.6.31.1/arch/sparc/kernel/traps_64.c 2009-09-24 11:45:25.000000000 -0400
3449 +++ linux-2.6.31.1/arch/sparc/kernel/traps_64.c 2009-10-01 20:12:42.000000000 -0400
3450 @@ -93,6 +93,12 @@ void bad_trap(struct pt_regs *regs, long
3451
3452 lvl -= 0x100;
3453 if (regs->tstate & TSTATE_PRIV) {
3454 +
3455 +#ifdef CONFIG_PAX_REFCOUNT
3456 + if (lvl == 6)
3457 + pax_report_refcount_overflow(regs);
3458 +#endif
3459 +
3460 sprintf(buffer, "Kernel bad sw trap %lx", lvl);
3461 die_if_kernel(buffer, regs);
3462 }
3463 @@ -111,11 +117,16 @@ void bad_trap(struct pt_regs *regs, long
3464 void bad_trap_tl1(struct pt_regs *regs, long lvl)
3465 {
3466 char buffer[32];
3467 -
3468 +
3469 if (notify_die(DIE_TRAP_TL1, "bad trap tl1", regs,
3470 0, lvl, SIGTRAP) == NOTIFY_STOP)
3471 return;
3472
3473 +#ifdef CONFIG_PAX_REFCOUNT
3474 + if (lvl == 6)
3475 + pax_report_refcount_overflow(regs);
3476 +#endif
3477 +
3478 dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
3479
3480 sprintf (buffer, "Bad trap %lx at tl>0", lvl);
3481 diff -urNp linux-2.6.31.1/arch/sparc/lib/atomic32.c linux-2.6.31.1/arch/sparc/lib/atomic32.c
3482 --- linux-2.6.31.1/arch/sparc/lib/atomic32.c 2009-09-24 11:45:25.000000000 -0400
3483 +++ linux-2.6.31.1/arch/sparc/lib/atomic32.c 2009-10-01 20:12:42.000000000 -0400
3484 @@ -80,6 +80,12 @@ void atomic_set(atomic_t *v, int i)
3485 }
3486 EXPORT_SYMBOL(atomic_set);
3487
3488 +void atomic_set_unchecked(atomic_unchecked_t *v, int i)
3489 +{
3490 + atomic_set((atomic_t *)v, i);
3491 +}
3492 +EXPORT_SYMBOL(atomic_set_unchecked);
3493 +
3494 unsigned long ___set_bit(unsigned long *addr, unsigned long mask)
3495 {
3496 unsigned long old, flags;
3497 diff -urNp linux-2.6.31.1/arch/sparc/lib/atomic_64.S linux-2.6.31.1/arch/sparc/lib/atomic_64.S
3498 --- linux-2.6.31.1/arch/sparc/lib/atomic_64.S 2009-09-24 11:45:25.000000000 -0400
3499 +++ linux-2.6.31.1/arch/sparc/lib/atomic_64.S 2009-10-01 20:12:42.000000000 -0400
3500 @@ -18,7 +18,12 @@
3501 atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
3502 BACKOFF_SETUP(%o2)
3503 1: lduw [%o1], %g1
3504 - add %g1, %o0, %g7
3505 + addcc %g1, %o0, %g7
3506 +
3507 +#ifdef CONFIG_PAX_REFCOUNT
3508 + tvs %icc, 6
3509 +#endif
3510 +
3511 cas [%o1], %g1, %g7
3512 cmp %g1, %g7
3513 bne,pn %icc, 2f
3514 @@ -28,12 +33,32 @@ atomic_add: /* %o0 = increment, %o1 = at
3515 2: BACKOFF_SPIN(%o2, %o3, 1b)
3516 .size atomic_add, .-atomic_add
3517
3518 + .globl atomic_add_unchecked
3519 + .type atomic_add_unchecked,#function
3520 +atomic_add_unchecked: /* %o0 = increment, %o1 = atomic_ptr */
3521 + BACKOFF_SETUP(%o2)
3522 +1: lduw [%o1], %g1
3523 + add %g1, %o0, %g7
3524 + cas [%o1], %g1, %g7
3525 + cmp %g1, %g7
3526 + bne,pn %icc, 2f
3527 + nop
3528 + retl
3529 + nop
3530 +2: BACKOFF_SPIN(%o2, %o3, 1b)
3531 + .size atomic_add_unchecked, .-atomic_add_unchecked
3532 +
3533 .globl atomic_sub
3534 .type atomic_sub,#function
3535 atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
3536 BACKOFF_SETUP(%o2)
3537 1: lduw [%o1], %g1
3538 - sub %g1, %o0, %g7
3539 + subcc %g1, %o0, %g7
3540 +
3541 +#ifdef CONFIG_PAX_REFCOUNT
3542 + tvs %icc, 6
3543 +#endif
3544 +
3545 cas [%o1], %g1, %g7
3546 cmp %g1, %g7
3547 bne,pn %icc, 2f
3548 @@ -43,12 +68,32 @@ atomic_sub: /* %o0 = decrement, %o1 = at
3549 2: BACKOFF_SPIN(%o2, %o3, 1b)
3550 .size atomic_sub, .-atomic_sub
3551
3552 + .globl atomic_sub_unchecked
3553 + .type atomic_sub_unchecked,#function
3554 +atomic_sub_unchecked: /* %o0 = decrement, %o1 = atomic_ptr */
3555 + BACKOFF_SETUP(%o2)
3556 +1: lduw [%o1], %g1
3557 + sub %g1, %o0, %g7
3558 + cas [%o1], %g1, %g7
3559 + cmp %g1, %g7
3560 + bne,pn %icc, 2f
3561 + nop
3562 + retl
3563 + nop
3564 +2: BACKOFF_SPIN(%o2, %o3, 1b)
3565 + .size atomic_sub_unchecked, .-atomic_sub_unchecked
3566 +
3567 .globl atomic_add_ret
3568 .type atomic_add_ret,#function
3569 atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
3570 BACKOFF_SETUP(%o2)
3571 1: lduw [%o1], %g1
3572 - add %g1, %o0, %g7
3573 + addcc %g1, %o0, %g7
3574 +
3575 +#ifdef CONFIG_PAX_REFCOUNT
3576 + tvs %icc, 6
3577 +#endif
3578 +
3579 cas [%o1], %g1, %g7
3580 cmp %g1, %g7
3581 bne,pn %icc, 2f
3582 @@ -64,7 +109,12 @@ atomic_add_ret: /* %o0 = increment, %o1
3583 atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
3584 BACKOFF_SETUP(%o2)
3585 1: lduw [%o1], %g1
3586 - sub %g1, %o0, %g7
3587 + subcc %g1, %o0, %g7
3588 +
3589 +#ifdef CONFIG_PAX_REFCOUNT
3590 + tvs %icc, 6
3591 +#endif
3592 +
3593 cas [%o1], %g1, %g7
3594 cmp %g1, %g7
3595 bne,pn %icc, 2f
3596 @@ -80,7 +130,12 @@ atomic_sub_ret: /* %o0 = decrement, %o1
3597 atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
3598 BACKOFF_SETUP(%o2)
3599 1: ldx [%o1], %g1
3600 - add %g1, %o0, %g7
3601 + addcc %g1, %o0, %g7
3602 +
3603 +#ifdef CONFIG_PAX_REFCOUNT
3604 + tvs %xcc, 6
3605 +#endif
3606 +
3607 casx [%o1], %g1, %g7
3608 cmp %g1, %g7
3609 bne,pn %xcc, 2f
3610 @@ -95,7 +150,12 @@ atomic64_add: /* %o0 = increment, %o1 =
3611 atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
3612 BACKOFF_SETUP(%o2)
3613 1: ldx [%o1], %g1
3614 - sub %g1, %o0, %g7
3615 + subcc %g1, %o0, %g7
3616 +
3617 +#ifdef CONFIG_PAX_REFCOUNT
3618 + tvs %xcc, 6
3619 +#endif
3620 +
3621 casx [%o1], %g1, %g7
3622 cmp %g1, %g7
3623 bne,pn %xcc, 2f
3624 @@ -110,7 +170,12 @@ atomic64_sub: /* %o0 = decrement, %o1 =
3625 atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
3626 BACKOFF_SETUP(%o2)
3627 1: ldx [%o1], %g1
3628 - add %g1, %o0, %g7
3629 + addcc %g1, %o0, %g7
3630 +
3631 +#ifdef CONFIG_PAX_REFCOUNT
3632 + tvs %xcc, 6
3633 +#endif
3634 +
3635 casx [%o1], %g1, %g7
3636 cmp %g1, %g7
3637 bne,pn %xcc, 2f
3638 @@ -126,7 +191,12 @@ atomic64_add_ret: /* %o0 = increment, %o
3639 atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
3640 BACKOFF_SETUP(%o2)
3641 1: ldx [%o1], %g1
3642 - sub %g1, %o0, %g7
3643 + subcc %g1, %o0, %g7
3644 +
3645 +#ifdef CONFIG_PAX_REFCOUNT
3646 + tvs %xcc, 6
3647 +#endif
3648 +
3649 casx [%o1], %g1, %g7
3650 cmp %g1, %g7
3651 bne,pn %xcc, 2f
3652 diff -urNp linux-2.6.31.1/arch/sparc/lib/ksyms.c linux-2.6.31.1/arch/sparc/lib/ksyms.c
3653 --- linux-2.6.31.1/arch/sparc/lib/ksyms.c 2009-09-24 11:45:25.000000000 -0400
3654 +++ linux-2.6.31.1/arch/sparc/lib/ksyms.c 2009-10-01 20:12:42.000000000 -0400
3655 @@ -144,8 +144,10 @@ EXPORT_SYMBOL(__downgrade_write);
3656
3657 /* Atomic counter implementation. */
3658 EXPORT_SYMBOL(atomic_add);
3659 +EXPORT_SYMBOL(atomic_add_unchecked);
3660 EXPORT_SYMBOL(atomic_add_ret);
3661 EXPORT_SYMBOL(atomic_sub);
3662 +EXPORT_SYMBOL(atomic_sub_unchecked);
3663 EXPORT_SYMBOL(atomic_sub_ret);
3664 EXPORT_SYMBOL(atomic64_add);
3665 EXPORT_SYMBOL(atomic64_add_ret);
3666 diff -urNp linux-2.6.31.1/arch/sparc/lib/rwsem_64.S linux-2.6.31.1/arch/sparc/lib/rwsem_64.S
3667 --- linux-2.6.31.1/arch/sparc/lib/rwsem_64.S 2009-09-24 11:45:25.000000000 -0400
3668 +++ linux-2.6.31.1/arch/sparc/lib/rwsem_64.S 2009-10-01 20:12:42.000000000 -0400
3669 @@ -11,7 +11,12 @@
3670 .globl __down_read
3671 __down_read:
3672 1: lduw [%o0], %g1
3673 - add %g1, 1, %g7
3674 + addcc %g1, 1, %g7
3675 +
3676 +#ifdef CONFIG_PAX_REFCOUNT
3677 + tvs %icc, 6
3678 +#endif
3679 +
3680 cas [%o0], %g1, %g7
3681 cmp %g1, %g7
3682 bne,pn %icc, 1b
3683 @@ -33,7 +38,12 @@ __down_read:
3684 .globl __down_read_trylock
3685 __down_read_trylock:
3686 1: lduw [%o0], %g1
3687 - add %g1, 1, %g7
3688 + addcc %g1, 1, %g7
3689 +
3690 +#ifdef CONFIG_PAX_REFCOUNT
3691 + tvs %icc, 6
3692 +#endif
3693 +
3694 cmp %g7, 0
3695 bl,pn %icc, 2f
3696 mov 0, %o1
3697 @@ -51,7 +61,12 @@ __down_write:
3698 or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
3699 1:
3700 lduw [%o0], %g3
3701 - add %g3, %g1, %g7
3702 + addcc %g3, %g1, %g7
3703 +
3704 +#ifdef CONFIG_PAX_REFCOUNT
3705 + tvs %icc, 6
3706 +#endif
3707 +
3708 cas [%o0], %g3, %g7
3709 cmp %g3, %g7
3710 bne,pn %icc, 1b
3711 @@ -77,7 +92,12 @@ __down_write_trylock:
3712 cmp %g3, 0
3713 bne,pn %icc, 2f
3714 mov 0, %o1
3715 - add %g3, %g1, %g7
3716 + addcc %g3, %g1, %g7
3717 +
3718 +#ifdef CONFIG_PAX_REFCOUNT
3719 + tvs %icc, 6
3720 +#endif
3721 +
3722 cas [%o0], %g3, %g7
3723 cmp %g3, %g7
3724 bne,pn %icc, 1b
3725 @@ -90,7 +110,12 @@ __down_write_trylock:
3726 __up_read:
3727 1:
3728 lduw [%o0], %g1
3729 - sub %g1, 1, %g7
3730 + subcc %g1, 1, %g7
3731 +
3732 +#ifdef CONFIG_PAX_REFCOUNT
3733 + tvs %icc, 6
3734 +#endif
3735 +
3736 cas [%o0], %g1, %g7
3737 cmp %g1, %g7
3738 bne,pn %icc, 1b
3739 @@ -118,7 +143,12 @@ __up_write:
3740 or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
3741 1:
3742 lduw [%o0], %g3
3743 - sub %g3, %g1, %g7
3744 + subcc %g3, %g1, %g7
3745 +
3746 +#ifdef CONFIG_PAX_REFCOUNT
3747 + tvs %icc, 6
3748 +#endif
3749 +
3750 cas [%o0], %g3, %g7
3751 cmp %g3, %g7
3752 bne,pn %icc, 1b
3753 @@ -143,7 +173,12 @@ __downgrade_write:
3754 or %g1, %lo(RWSEM_WAITING_BIAS), %g1
3755 1:
3756 lduw [%o0], %g3
3757 - sub %g3, %g1, %g7
3758 + subcc %g3, %g1, %g7
3759 +
3760 +#ifdef CONFIG_PAX_REFCOUNT
3761 + tvs %icc, 6
3762 +#endif
3763 +
3764 cas [%o0], %g3, %g7
3765 cmp %g3, %g7
3766 bne,pn %icc, 1b
3767 diff -urNp linux-2.6.31.1/arch/sparc/Makefile linux-2.6.31.1/arch/sparc/Makefile
3768 --- linux-2.6.31.1/arch/sparc/Makefile 2009-09-24 11:45:25.000000000 -0400
3769 +++ linux-2.6.31.1/arch/sparc/Makefile 2009-10-01 20:12:42.000000000 -0400
3770 @@ -81,7 +81,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
3771 # Export what is needed by arch/sparc/boot/Makefile
3772 export VMLINUX_INIT VMLINUX_MAIN
3773 VMLINUX_INIT := $(head-y) $(init-y)
3774 -VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/
3775 +VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
3776 VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
3777 VMLINUX_MAIN += $(drivers-y) $(net-y)
3778
3779 diff -urNp linux-2.6.31.1/arch/sparc/mm/fault_32.c linux-2.6.31.1/arch/sparc/mm/fault_32.c
3780 --- linux-2.6.31.1/arch/sparc/mm/fault_32.c 2009-09-24 11:45:25.000000000 -0400
3781 +++ linux-2.6.31.1/arch/sparc/mm/fault_32.c 2009-10-01 20:12:42.000000000 -0400
3782 @@ -21,6 +21,9 @@
3783 #include <linux/interrupt.h>
3784 #include <linux/module.h>
3785 #include <linux/kdebug.h>
3786 +#include <linux/slab.h>
3787 +#include <linux/pagemap.h>
3788 +#include <linux/compiler.h>
3789
3790 #include <asm/system.h>
3791 #include <asm/page.h>
3792 @@ -167,6 +170,267 @@ static unsigned long compute_si_addr(str
3793 return safe_compute_effective_address(regs, insn);
3794 }
3795
3796 +#ifdef CONFIG_PAX_PAGEEXEC
3797 +#ifdef CONFIG_PAX_DLRESOLVE
3798 +void pax_emuplt_close(struct vm_area_struct *vma)
3799 +{
3800 + vma->vm_mm->call_dl_resolve = 0UL;
3801 +}
3802 +
3803 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
3804 +{
3805 + unsigned int *kaddr;
3806 +
3807 + vmf->page = alloc_page(GFP_HIGHUSER);
3808 + if (!vmf->page)
3809 + return VM_FAULT_OOM;
3810 +
3811 + kaddr = kmap(vmf->page);
3812 + memset(kaddr, 0, PAGE_SIZE);
3813 + kaddr[0] = 0x9DE3BFA8U; /* save */
3814 + flush_dcache_page(vmf->page);
3815 + kunmap(vmf->page);
3816 + return VM_FAULT_MAJOR;
3817 +}
3818 +
3819 +static const struct vm_operations_struct pax_vm_ops = {
3820 + .close = pax_emuplt_close,
3821 + .fault = pax_emuplt_fault
3822 +};
3823 +
3824 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3825 +{
3826 + int ret;
3827 +
3828 + vma->vm_mm = current->mm;
3829 + vma->vm_start = addr;
3830 + vma->vm_end = addr + PAGE_SIZE;
3831 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3832 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
3833 + vma->vm_ops = &pax_vm_ops;
3834 +
3835 + ret = insert_vm_struct(current->mm, vma);
3836 + if (ret)
3837 + return ret;
3838 +
3839 + ++current->mm->total_vm;
3840 + return 0;
3841 +}
3842 +#endif
3843 +
3844 +/*
3845 + * PaX: decide what to do with offenders (regs->pc = fault address)
3846 + *
3847 + * returns 1 when task should be killed
3848 + * 2 when patched PLT trampoline was detected
3849 + * 3 when unpatched PLT trampoline was detected
3850 + */
3851 +static int pax_handle_fetch_fault(struct pt_regs *regs)
3852 +{
3853 +
3854 +#ifdef CONFIG_PAX_EMUPLT
3855 + int err;
3856 +
3857 + do { /* PaX: patched PLT emulation #1 */
3858 + unsigned int sethi1, sethi2, jmpl;
3859 +
3860 + err = get_user(sethi1, (unsigned int *)regs->pc);
3861 + err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
3862 + err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
3863 +
3864 + if (err)
3865 + break;
3866 +
3867 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3868 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
3869 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
3870 + {
3871 + unsigned int addr;
3872 +
3873 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3874 + addr = regs->u_regs[UREG_G1];
3875 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3876 + regs->pc = addr;
3877 + regs->npc = addr+4;
3878 + return 2;
3879 + }
3880 + } while (0);
3881 +
3882 + { /* PaX: patched PLT emulation #2 */
3883 + unsigned int ba;
3884 +
3885 + err = get_user(ba, (unsigned int *)regs->pc);
3886 +
3887 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3888 + unsigned int addr;
3889 +
3890 + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
3891 + regs->pc = addr;
3892 + regs->npc = addr+4;
3893 + return 2;
3894 + }
3895 + }
3896 +
3897 + do { /* PaX: patched PLT emulation #3 */
3898 + unsigned int sethi, jmpl, nop;
3899 +
3900 + err = get_user(sethi, (unsigned int *)regs->pc);
3901 + err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
3902 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
3903 +
3904 + if (err)
3905 + break;
3906 +
3907 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
3908 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3909 + nop == 0x01000000U)
3910 + {
3911 + unsigned int addr;
3912 +
3913 + addr = (sethi & 0x003FFFFFU) << 10;
3914 + regs->u_regs[UREG_G1] = addr;
3915 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3916 + regs->pc = addr;
3917 + regs->npc = addr+4;
3918 + return 2;
3919 + }
3920 + } while (0);
3921 +
3922 + do { /* PaX: unpatched PLT emulation step 1 */
3923 + unsigned int sethi, ba, nop;
3924 +
3925 + err = get_user(sethi, (unsigned int *)regs->pc);
3926 + err |= get_user(ba, (unsigned int *)(regs->pc+4));
3927 + err |= get_user(nop, (unsigned int *)(regs->pc+8));
3928 +
3929 + if (err)
3930 + break;
3931 +
3932 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
3933 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
3934 + nop == 0x01000000U)
3935 + {
3936 + unsigned int addr, save, call;
3937 +
3938 + if ((ba & 0xFFC00000U) == 0x30800000U)
3939 + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
3940 + else
3941 + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
3942 +
3943 + err = get_user(save, (unsigned int *)addr);
3944 + err |= get_user(call, (unsigned int *)(addr+4));
3945 + err |= get_user(nop, (unsigned int *)(addr+8));
3946 + if (err)
3947 + break;
3948 +
3949 +#ifdef CONFIG_PAX_DLRESOLVE
3950 + if (save == 0x9DE3BFA8U &&
3951 + (call & 0xC0000000U) == 0x40000000U &&
3952 + nop == 0x01000000U)
3953 + {
3954 + struct vm_area_struct *vma;
3955 + unsigned long call_dl_resolve;
3956 +
3957 + down_read(&current->mm->mmap_sem);
3958 + call_dl_resolve = current->mm->call_dl_resolve;
3959 + up_read(&current->mm->mmap_sem);
3960 + if (likely(call_dl_resolve))
3961 + goto emulate;
3962 +
3963 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3964 +
3965 + down_write(&current->mm->mmap_sem);
3966 + if (current->mm->call_dl_resolve) {
3967 + call_dl_resolve = current->mm->call_dl_resolve;
3968 + up_write(&current->mm->mmap_sem);
3969 + if (vma)
3970 + kmem_cache_free(vm_area_cachep, vma);
3971 + goto emulate;
3972 + }
3973 +
3974 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3975 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
3976 + up_write(&current->mm->mmap_sem);
3977 + if (vma)
3978 + kmem_cache_free(vm_area_cachep, vma);
3979 + return 1;
3980 + }
3981 +
3982 + if (pax_insert_vma(vma, call_dl_resolve)) {
3983 + up_write(&current->mm->mmap_sem);
3984 + kmem_cache_free(vm_area_cachep, vma);
3985 + return 1;
3986 + }
3987 +
3988 + current->mm->call_dl_resolve = call_dl_resolve;
3989 + up_write(&current->mm->mmap_sem);
3990 +
3991 +emulate:
3992 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
3993 + regs->pc = call_dl_resolve;
3994 + regs->npc = addr+4;
3995 + return 3;
3996 + }
3997 +#endif
3998 +
3999 + /* PaX: glibc 2.4+ generates sethi/jmpl instead of save/call */
4000 + if ((save & 0xFFC00000U) == 0x05000000U &&
4001 + (call & 0xFFFFE000U) == 0x85C0A000U &&
4002 + nop == 0x01000000U)
4003 + {
4004 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4005 + regs->u_regs[UREG_G2] = addr + 4;
4006 + addr = (save & 0x003FFFFFU) << 10;
4007 + addr += (((call | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4008 + regs->pc = addr;
4009 + regs->npc = addr+4;
4010 + return 3;
4011 + }
4012 + }
4013 + } while (0);
4014 +
4015 + do { /* PaX: unpatched PLT emulation step 2 */
4016 + unsigned int save, call, nop;
4017 +
4018 + err = get_user(save, (unsigned int *)(regs->pc-4));
4019 + err |= get_user(call, (unsigned int *)regs->pc);
4020 + err |= get_user(nop, (unsigned int *)(regs->pc+4));
4021 + if (err)
4022 + break;
4023 +
4024 + if (save == 0x9DE3BFA8U &&
4025 + (call & 0xC0000000U) == 0x40000000U &&
4026 + nop == 0x01000000U)
4027 + {
4028 + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
4029 +
4030 + regs->u_regs[UREG_RETPC] = regs->pc;
4031 + regs->pc = dl_resolve;
4032 + regs->npc = dl_resolve+4;
4033 + return 3;
4034 + }
4035 + } while (0);
4036 +#endif
4037 +
4038 + return 1;
4039 +}
4040 +
4041 +void pax_report_insns(void *pc, void *sp)
4042 +{
4043 + unsigned long i;
4044 +
4045 + printk(KERN_ERR "PAX: bytes at PC: ");
4046 + for (i = 0; i < 5; i++) {
4047 + unsigned int c;
4048 + if (get_user(c, (unsigned int *)pc+i))
4049 + printk(KERN_CONT "???????? ");
4050 + else
4051 + printk(KERN_CONT "%08x ", c);
4052 + }
4053 + printk("\n");
4054 +}
4055 +#endif
4056 +
4057 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
4058 unsigned long address)
4059 {
4060 @@ -231,6 +495,24 @@ good_area:
4061 if(!(vma->vm_flags & VM_WRITE))
4062 goto bad_area;
4063 } else {
4064 +
4065 +#ifdef CONFIG_PAX_PAGEEXEC
4066 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
4067 + up_read(&mm->mmap_sem);
4068 + switch (pax_handle_fetch_fault(regs)) {
4069 +
4070 +#ifdef CONFIG_PAX_EMUPLT
4071 + case 2:
4072 + case 3:
4073 + return;
4074 +#endif
4075 +
4076 + }
4077 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
4078 + do_group_exit(SIGKILL);
4079 + }
4080 +#endif
4081 +
4082 /* Allow reads even for write-only mappings */
4083 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
4084 goto bad_area;
4085 diff -urNp linux-2.6.31.1/arch/sparc/mm/fault_64.c linux-2.6.31.1/arch/sparc/mm/fault_64.c
4086 --- linux-2.6.31.1/arch/sparc/mm/fault_64.c 2009-09-24 11:45:25.000000000 -0400
4087 +++ linux-2.6.31.1/arch/sparc/mm/fault_64.c 2009-10-01 20:12:42.000000000 -0400
4088 @@ -20,6 +20,9 @@
4089 #include <linux/kprobes.h>
4090 #include <linux/kdebug.h>
4091 #include <linux/percpu.h>
4092 +#include <linux/slab.h>
4093 +#include <linux/pagemap.h>
4094 +#include <linux/compiler.h>
4095
4096 #include <asm/page.h>
4097 #include <asm/pgtable.h>
4098 @@ -249,6 +252,416 @@ static void noinline bogus_32bit_fault_a
4099 show_regs(regs);
4100 }
4101
4102 +#ifdef CONFIG_PAX_PAGEEXEC
4103 +#ifdef CONFIG_PAX_DLRESOLVE
4104 +static void pax_emuplt_close(struct vm_area_struct *vma)
4105 +{
4106 + vma->vm_mm->call_dl_resolve = 0UL;
4107 +}
4108 +
4109 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
4110 +{
4111 + unsigned int *kaddr;
4112 +
4113 + vmf->page = alloc_page(GFP_HIGHUSER);
4114 + if (!vmf->page)
4115 + return VM_FAULT_OOM;
4116 +
4117 + kaddr = kmap(vmf->page);
4118 + memset(kaddr, 0, PAGE_SIZE);
4119 + kaddr[0] = 0x9DE3BFA8U; /* save */
4120 + flush_dcache_page(vmf->page);
4121 + kunmap(vmf->page);
4122 + return VM_FAULT_MAJOR;
4123 +}
4124 +
4125 +static const struct vm_operations_struct pax_vm_ops = {
4126 + .close = pax_emuplt_close,
4127 + .fault = pax_emuplt_fault
4128 +};
4129 +
4130 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4131 +{
4132 + int ret;
4133 +
4134 + vma->vm_mm = current->mm;
4135 + vma->vm_start = addr;
4136 + vma->vm_end = addr + PAGE_SIZE;
4137 + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4138 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
4139 + vma->vm_ops = &pax_vm_ops;
4140 +
4141 + ret = insert_vm_struct(current->mm, vma);
4142 + if (ret)
4143 + return ret;
4144 +
4145 + ++current->mm->total_vm;
4146 + return 0;
4147 +}
4148 +#endif
4149 +
4150 +/*
4151 + * PaX: decide what to do with offenders (regs->tpc = fault address)
4152 + *
4153 + * returns 1 when task should be killed
4154 + * 2 when patched PLT trampoline was detected
4155 + * 3 when unpatched PLT trampoline was detected
4156 + */
4157 +static int pax_handle_fetch_fault(struct pt_regs *regs)
4158 +{
4159 +
4160 +#ifdef CONFIG_PAX_EMUPLT
4161 + int err;
4162 +
4163 + do { /* PaX: patched PLT emulation #1 */
4164 + unsigned int sethi1, sethi2, jmpl;
4165 +
4166 + err = get_user(sethi1, (unsigned int *)regs->tpc);
4167 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
4168 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
4169 +
4170 + if (err)
4171 + break;
4172 +
4173 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4174 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
4175 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
4176 + {
4177 + unsigned long addr;
4178 +
4179 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4180 + addr = regs->u_regs[UREG_G1];
4181 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4182 +
4183 + if (test_thread_flag(TIF_32BIT))
4184 + addr &= 0xFFFFFFFFUL;
4185 +
4186 + regs->tpc = addr;
4187 + regs->tnpc = addr+4;
4188 + return 2;
4189 + }
4190 + } while (0);
4191 +
4192 + { /* PaX: patched PLT emulation #2 */
4193 + unsigned int ba;
4194 +
4195 + err = get_user(ba, (unsigned int *)regs->tpc);
4196 +
4197 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4198 + unsigned long addr;
4199 +
4200 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4201 +
4202 + if (test_thread_flag(TIF_32BIT))
4203 + addr &= 0xFFFFFFFFUL;
4204 +
4205 + regs->tpc = addr;
4206 + regs->tnpc = addr+4;
4207 + return 2;
4208 + }
4209 + }
4210 +
4211 + do { /* PaX: patched PLT emulation #3 */
4212 + unsigned int sethi, jmpl, nop;
4213 +
4214 + err = get_user(sethi, (unsigned int *)regs->tpc);
4215 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
4216 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
4217 +
4218 + if (err)
4219 + break;
4220 +
4221 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
4222 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4223 + nop == 0x01000000U)
4224 + {
4225 + unsigned long addr;
4226 +
4227 + addr = (sethi & 0x003FFFFFU) << 10;
4228 + regs->u_regs[UREG_G1] = addr;
4229 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4230 +
4231 + if (test_thread_flag(TIF_32BIT))
4232 + addr &= 0xFFFFFFFFUL;
4233 +
4234 + regs->tpc = addr;
4235 + regs->tnpc = addr+4;
4236 + return 2;
4237 + }
4238 + } while (0);
4239 +
4240 + do { /* PaX: patched PLT emulation #4 */
4241 + unsigned int mov1, call, mov2;
4242 +
4243 + err = get_user(mov1, (unsigned int *)regs->tpc);
4244 + err |= get_user(call, (unsigned int *)(regs->tpc+4));
4245 + err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
4246 +
4247 + if (err)
4248 + break;
4249 +
4250 + if (mov1 == 0x8210000FU &&
4251 + (call & 0xC0000000U) == 0x40000000U &&
4252 + mov2 == 0x9E100001U)
4253 + {
4254 + unsigned long addr;
4255 +
4256 + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
4257 + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4258 +
4259 + if (test_thread_flag(TIF_32BIT))
4260 + addr &= 0xFFFFFFFFUL;
4261 +
4262 + regs->tpc = addr;
4263 + regs->tnpc = addr+4;
4264 + return 2;
4265 + }
4266 + } while (0);
4267 +
4268 + do { /* PaX: patched PLT emulation #5 */
4269 + unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
4270 +
4271 + err = get_user(sethi1, (unsigned int *)regs->tpc);
4272 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
4273 + err |= get_user(or1, (unsigned int *)(regs->tpc+8));
4274 + err |= get_user(or2, (unsigned int *)(regs->tpc+12));
4275 + err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
4276 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
4277 + err |= get_user(nop, (unsigned int *)(regs->tpc+24));
4278 +
4279 + if (err)
4280 + break;
4281 +
4282 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4283 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4284 + (or1 & 0xFFFFE000U) == 0x82106000U &&
4285 + (or2 & 0xFFFFE000U) == 0x8A116000U &&
4286 + sllx == 0x83287020 &&
4287 + jmpl == 0x81C04005U &&
4288 + nop == 0x01000000U)
4289 + {
4290 + unsigned long addr;
4291 +
4292 + regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
4293 + regs->u_regs[UREG_G1] <<= 32;
4294 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
4295 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4296 + regs->tpc = addr;
4297 + regs->tnpc = addr+4;
4298 + return 2;
4299 + }
4300 + } while (0);
4301 +
4302 + do { /* PaX: patched PLT emulation #6 */
4303 + unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
4304 +
4305 + err = get_user(sethi1, (unsigned int *)regs->tpc);
4306 + err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
4307 + err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
4308 + err |= get_user(or, (unsigned int *)(regs->tpc+12));
4309 + err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
4310 + err |= get_user(nop, (unsigned int *)(regs->tpc+20));
4311 +
4312 + if (err)
4313 + break;
4314 +
4315 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4316 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4317 + sllx == 0x83287020 &&
4318 + (or & 0xFFFFE000U) == 0x8A116000U &&
4319 + jmpl == 0x81C04005U &&
4320 + nop == 0x01000000U)
4321 + {
4322 + unsigned long addr;
4323 +
4324 + regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
4325 + regs->u_regs[UREG_G1] <<= 32;
4326 + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
4327 + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4328 + regs->tpc = addr;
4329 + regs->tnpc = addr+4;
4330 + return 2;
4331 + }
4332 + } while (0);
4333 +
4334 + do { /* PaX: unpatched PLT emulation step 1 */
4335 + unsigned int sethi, ba, nop;
4336 +
4337 + err = get_user(sethi, (unsigned int *)regs->tpc);
4338 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
4339 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
4340 +
4341 + if (err)
4342 + break;
4343 +
4344 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
4345 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4346 + nop == 0x01000000U)
4347 + {
4348 + unsigned long addr;
4349 + unsigned int save, call;
4350 +
4351 + if ((ba & 0xFFC00000U) == 0x30800000U)
4352 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4353 + else
4354 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4355 +
4356 + if (test_thread_flag(TIF_32BIT))
4357 + addr &= 0xFFFFFFFFUL;
4358 +
4359 + err = get_user(save, (unsigned int *)addr);
4360 + err |= get_user(call, (unsigned int *)(addr+4));
4361 + err |= get_user(nop, (unsigned int *)(addr+8));
4362 + if (err)
4363 + break;
4364 +
4365 +#ifdef CONFIG_PAX_DLRESOLVE
4366 + if (save == 0x9DE3BFA8U &&
4367 + (call & 0xC0000000U) == 0x40000000U &&
4368 + nop == 0x01000000U)
4369 + {
4370 + struct vm_area_struct *vma;
4371 + unsigned long call_dl_resolve;
4372 +
4373 + down_read(&current->mm->mmap_sem);
4374 + call_dl_resolve = current->mm->call_dl_resolve;
4375 + up_read(&current->mm->mmap_sem);
4376 + if (likely(call_dl_resolve))
4377 + goto emulate;
4378 +
4379 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
4380 +
4381 + down_write(&current->mm->mmap_sem);
4382 + if (current->mm->call_dl_resolve) {
4383 + call_dl_resolve = current->mm->call_dl_resolve;
4384 + up_write(&current->mm->mmap_sem);
4385 + if (vma)
4386 + kmem_cache_free(vm_area_cachep, vma);
4387 + goto emulate;
4388 + }
4389 +
4390 + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4391 + if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4392 + up_write(&current->mm->mmap_sem);
4393 + if (vma)
4394 + kmem_cache_free(vm_area_cachep, vma);
4395 + return 1;
4396 + }
4397 +
4398 + if (pax_insert_vma(vma, call_dl_resolve)) {
4399 + up_write(&current->mm->mmap_sem);
4400 + kmem_cache_free(vm_area_cachep, vma);
4401 + return 1;
4402 + }
4403 +
4404 + current->mm->call_dl_resolve = call_dl_resolve;
4405 + up_write(&current->mm->mmap_sem);
4406 +
4407 +emulate:
4408 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4409 + regs->tpc = call_dl_resolve;
4410 + regs->tnpc = addr+4;
4411 + return 3;
4412 + }
4413 +#endif
4414 +
4415 + /* PaX: glibc 2.4+ generates sethi/jmpl instead of save/call */
4416 + if ((save & 0xFFC00000U) == 0x05000000U &&
4417 + (call & 0xFFFFE000U) == 0x85C0A000U &&
4418 + nop == 0x01000000U)
4419 + {
4420 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4421 + regs->u_regs[UREG_G2] = addr + 4;
4422 + addr = (save & 0x003FFFFFU) << 10;
4423 + addr += (((call | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4424 +
4425 + if (test_thread_flag(TIF_32BIT))
4426 + addr &= 0xFFFFFFFFUL;
4427 +
4428 + regs->tpc = addr;
4429 + regs->tnpc = addr+4;
4430 + return 3;
4431 + }
4432 + }
4433 + } while (0);
4434 +
4435 +#ifdef CONFIG_PAX_DLRESOLVE
4436 + do { /* PaX: unpatched PLT emulation step 2 */
4437 + unsigned int save, call, nop;
4438 +
4439 + err = get_user(save, (unsigned int *)(regs->tpc-4));
4440 + err |= get_user(call, (unsigned int *)regs->tpc);
4441 + err |= get_user(nop, (unsigned int *)(regs->tpc+4));
4442 + if (err)
4443 + break;
4444 +
4445 + if (save == 0x9DE3BFA8U &&
4446 + (call & 0xC0000000U) == 0x40000000U &&
4447 + nop == 0x01000000U)
4448 + {
4449 + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4450 +
4451 + if (test_thread_flag(TIF_32BIT))
4452 + dl_resolve &= 0xFFFFFFFFUL;
4453 +
4454 + regs->u_regs[UREG_RETPC] = regs->tpc;
4455 + regs->tpc = dl_resolve;
4456 + regs->tnpc = dl_resolve+4;
4457 + return 3;
4458 + }
4459 + } while (0);
4460 +#endif
4461 +
4462 + do { /* PaX: patched PLT emulation #7, must be AFTER the unpatched PLT emulation */
4463 + unsigned int sethi, ba, nop;
4464 +
4465 + err = get_user(sethi, (unsigned int *)regs->tpc);
4466 + err |= get_user(ba, (unsigned int *)(regs->tpc+4));
4467 + err |= get_user(nop, (unsigned int *)(regs->tpc+8));
4468 +
4469 + if (err)
4470 + break;
4471 +
4472 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
4473 + (ba & 0xFFF00000U) == 0x30600000U &&
4474 + nop == 0x01000000U)
4475 + {
4476 + unsigned long addr;
4477 +
4478 + addr = (sethi & 0x003FFFFFU) << 10;
4479 + regs->u_regs[UREG_G1] = addr;
4480 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4481 +
4482 + if (test_thread_flag(TIF_32BIT))
4483 + addr &= 0xFFFFFFFFUL;
4484 +
4485 + regs->tpc = addr;
4486 + regs->tnpc = addr+4;
4487 + return 2;
4488 + }
4489 + } while (0);
4490 +
4491 +#endif
4492 +
4493 + return 1;
4494 +}
4495 +
4496 +void pax_report_insns(void *pc, void *sp)
4497 +{
4498 + unsigned long i;
4499 +
4500 + printk(KERN_ERR "PAX: bytes at PC: ");
4501 + for (i = 0; i < 5; i++) {
4502 + unsigned int c;
4503 + if (get_user(c, (unsigned int *)pc+i))
4504 + printk(KERN_CONT "???????? ");
4505 + else
4506 + printk(KERN_CONT "%08x ", c);
4507 + }
4508 + printk("\n");
4509 +}
4510 +#endif
4511 +
4512 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
4513 {
4514 struct mm_struct *mm = current->mm;
4515 @@ -315,6 +728,29 @@ asmlinkage void __kprobes do_sparc64_fau
4516 if (!vma)
4517 goto bad_area;
4518
4519 +#ifdef CONFIG_PAX_PAGEEXEC
4520 + /* PaX: detect ITLB misses on non-exec pages */
4521 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
4522 + !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
4523 + {
4524 + if (address != regs->tpc)
4525 + goto good_area;
4526 +
4527 + up_read(&mm->mmap_sem);
4528 + switch (pax_handle_fetch_fault(regs)) {
4529 +
4530 +#ifdef CONFIG_PAX_EMUPLT
4531 + case 2:
4532 + case 3:
4533 + return;
4534 +#endif
4535 +
4536 + }
4537 + pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
4538 + do_group_exit(SIGKILL);
4539 + }
4540 +#endif
4541 +
4542 /* Pure DTLB misses do not tell us whether the fault causing
4543 * load/store/atomic was a write or not, it only says that there
4544 * was no match. So in such a case we (carefully) read the
4545 diff -urNp linux-2.6.31.1/arch/sparc/mm/init_32.c linux-2.6.31.1/arch/sparc/mm/init_32.c
4546 --- linux-2.6.31.1/arch/sparc/mm/init_32.c 2009-09-24 11:45:25.000000000 -0400
4547 +++ linux-2.6.31.1/arch/sparc/mm/init_32.c 2009-10-01 20:12:42.000000000 -0400
4548 @@ -316,6 +316,9 @@ extern void device_scan(void);
4549 pgprot_t PAGE_SHARED __read_mostly;
4550 EXPORT_SYMBOL(PAGE_SHARED);
4551
4552 +pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
4553 +EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
4554 +
4555 void __init paging_init(void)
4556 {
4557 switch(sparc_cpu_model) {
4558 @@ -341,17 +344,17 @@ void __init paging_init(void)
4559
4560 /* Initialize the protection map with non-constant, MMU dependent values. */
4561 protection_map[0] = PAGE_NONE;
4562 - protection_map[1] = PAGE_READONLY;
4563 - protection_map[2] = PAGE_COPY;
4564 - protection_map[3] = PAGE_COPY;
4565 + protection_map[1] = PAGE_READONLY_NOEXEC;
4566 + protection_map[2] = PAGE_COPY_NOEXEC;
4567 + protection_map[3] = PAGE_COPY_NOEXEC;
4568 protection_map[4] = PAGE_READONLY;
4569 protection_map[5] = PAGE_READONLY;
4570 protection_map[6] = PAGE_COPY;
4571 protection_map[7] = PAGE_COPY;
4572 protection_map[8] = PAGE_NONE;
4573 - protection_map[9] = PAGE_READONLY;
4574 - protection_map[10] = PAGE_SHARED;
4575 - protection_map[11] = PAGE_SHARED;
4576 + protection_map[9] = PAGE_READONLY_NOEXEC;
4577 + protection_map[10] = PAGE_SHARED_NOEXEC;
4578 + protection_map[11] = PAGE_SHARED_NOEXEC;
4579 protection_map[12] = PAGE_READONLY;
4580 protection_map[13] = PAGE_READONLY;
4581 protection_map[14] = PAGE_SHARED;
4582 diff -urNp linux-2.6.31.1/arch/sparc/mm/Makefile linux-2.6.31.1/arch/sparc/mm/Makefile
4583 --- linux-2.6.31.1/arch/sparc/mm/Makefile 2009-09-24 11:45:25.000000000 -0400
4584 +++ linux-2.6.31.1/arch/sparc/mm/Makefile 2009-10-01 20:12:42.000000000 -0400
4585 @@ -2,7 +2,7 @@
4586 #
4587
4588 asflags-y := -ansi
4589 -ccflags-y := -Werror
4590 +#ccflags-y := -Werror
4591
4592 obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o
4593 obj-y += fault_$(BITS).o
4594 diff -urNp linux-2.6.31.1/arch/sparc/mm/srmmu.c linux-2.6.31.1/arch/sparc/mm/srmmu.c
4595 --- linux-2.6.31.1/arch/sparc/mm/srmmu.c 2009-09-24 11:45:25.000000000 -0400
4596 +++ linux-2.6.31.1/arch/sparc/mm/srmmu.c 2009-10-01 20:12:42.000000000 -0400
4597 @@ -2149,6 +2149,13 @@ void __init ld_mmu_srmmu(void)
4598 PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
4599 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
4600 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
4601 +
4602 +#ifdef CONFIG_PAX_PAGEEXEC
4603 + PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
4604 + BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
4605 + BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
4606 +#endif
4607 +
4608 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
4609 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
4610
4611 diff -urNp linux-2.6.31.1/arch/um/include/asm/kmap_types.h linux-2.6.31.1/arch/um/include/asm/kmap_types.h
4612 --- linux-2.6.31.1/arch/um/include/asm/kmap_types.h 2009-09-24 11:45:25.000000000 -0400
4613 +++ linux-2.6.31.1/arch/um/include/asm/kmap_types.h 2009-10-01 20:12:42.000000000 -0400
4614 @@ -23,6 +23,7 @@ enum km_type {
4615 KM_IRQ1,
4616 KM_SOFTIRQ0,
4617 KM_SOFTIRQ1,
4618 + KM_CLEARPAGE,
4619 KM_TYPE_NR
4620 };
4621
4622 diff -urNp linux-2.6.31.1/arch/um/include/asm/page.h linux-2.6.31.1/arch/um/include/asm/page.h
4623 --- linux-2.6.31.1/arch/um/include/asm/page.h 2009-09-24 11:45:25.000000000 -0400
4624 +++ linux-2.6.31.1/arch/um/include/asm/page.h 2009-10-01 20:12:42.000000000 -0400
4625 @@ -14,6 +14,9 @@
4626 #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
4627 #define PAGE_MASK (~(PAGE_SIZE-1))
4628
4629 +#define ktla_ktva(addr) (addr)
4630 +#define ktva_ktla(addr) (addr)
4631 +
4632 #ifndef __ASSEMBLY__
4633
4634 struct page;
4635 diff -urNp linux-2.6.31.1/arch/um/sys-i386/syscalls.c linux-2.6.31.1/arch/um/sys-i386/syscalls.c
4636 --- linux-2.6.31.1/arch/um/sys-i386/syscalls.c 2009-09-24 11:45:25.000000000 -0400
4637 +++ linux-2.6.31.1/arch/um/sys-i386/syscalls.c 2009-10-01 20:12:42.000000000 -0400
4638 @@ -11,6 +11,21 @@
4639 #include "asm/uaccess.h"
4640 #include "asm/unistd.h"
4641
4642 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
4643 +{
4644 + unsigned long pax_task_size = TASK_SIZE;
4645 +
4646 +#ifdef CONFIG_PAX_SEGMEXEC
4647 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
4648 + pax_task_size = SEGMEXEC_TASK_SIZE;
4649 +#endif
4650 +
4651 + if (len > pax_task_size || addr > pax_task_size - len)
4652 + return -EINVAL;
4653 +
4654 + return 0;
4655 +}
4656 +
4657 /*
4658 * Perform the select(nd, in, out, ex, tv) and mmap() system
4659 * calls. Linux/i386 didn't use to be able to handle more than
4660 diff -urNp linux-2.6.31.1/arch/x86/boot/bitops.h linux-2.6.31.1/arch/x86/boot/bitops.h
4661 --- linux-2.6.31.1/arch/x86/boot/bitops.h 2009-09-24 11:45:25.000000000 -0400
4662 +++ linux-2.6.31.1/arch/x86/boot/bitops.h 2009-10-01 20:12:42.000000000 -0400
4663 @@ -26,7 +26,7 @@ static inline int variable_test_bit(int
4664 u8 v;
4665 const u32 *p = (const u32 *)addr;
4666
4667 - asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
4668 + asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
4669 return v;
4670 }
4671
4672 @@ -37,7 +37,7 @@ static inline int variable_test_bit(int
4673
4674 static inline void set_bit(int nr, void *addr)
4675 {
4676 - asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
4677 + asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
4678 }
4679
4680 #endif /* BOOT_BITOPS_H */
4681 diff -urNp linux-2.6.31.1/arch/x86/boot/boot.h linux-2.6.31.1/arch/x86/boot/boot.h
4682 --- linux-2.6.31.1/arch/x86/boot/boot.h 2009-09-24 11:45:25.000000000 -0400
4683 +++ linux-2.6.31.1/arch/x86/boot/boot.h 2009-10-01 20:12:42.000000000 -0400
4684 @@ -82,7 +82,7 @@ static inline void io_delay(void)
4685 static inline u16 ds(void)
4686 {
4687 u16 seg;
4688 - asm("movw %%ds,%0" : "=rm" (seg));
4689 + asm volatile("movw %%ds,%0" : "=rm" (seg));
4690 return seg;
4691 }
4692
4693 @@ -178,7 +178,7 @@ static inline void wrgs32(u32 v, addr_t
4694 static inline int memcmp(const void *s1, const void *s2, size_t len)
4695 {
4696 u8 diff;
4697 - asm("repe; cmpsb; setnz %0"
4698 + asm volatile("repe; cmpsb; setnz %0"
4699 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
4700 return diff;
4701 }
4702 diff -urNp linux-2.6.31.1/arch/x86/boot/compressed/head_32.S linux-2.6.31.1/arch/x86/boot/compressed/head_32.S
4703 --- linux-2.6.31.1/arch/x86/boot/compressed/head_32.S 2009-09-24 11:45:25.000000000 -0400
4704 +++ linux-2.6.31.1/arch/x86/boot/compressed/head_32.S 2009-10-01 20:12:42.000000000 -0400
4705 @@ -75,7 +75,7 @@ ENTRY(startup_32)
4706 notl %eax
4707 andl %eax, %ebx
4708 #else
4709 - movl $LOAD_PHYSICAL_ADDR, %ebx
4710 + movl $____LOAD_PHYSICAL_ADDR, %ebx
4711 #endif
4712
4713 /* Target address to relocate to for decompression */
4714 @@ -148,7 +148,7 @@ relocated:
4715 * and where it was actually loaded.
4716 */
4717 movl %ebp, %ebx
4718 - subl $LOAD_PHYSICAL_ADDR, %ebx
4719 + subl $____LOAD_PHYSICAL_ADDR, %ebx
4720 jz 2f /* Nothing to be done if loaded at compiled addr. */
4721 /*
4722 * Process relocations.
4723 @@ -156,8 +156,7 @@ relocated:
4724
4725 1: subl $4, %edi
4726 movl (%edi), %ecx
4727 - testl %ecx, %ecx
4728 - jz 2f
4729 + jecxz 2f
4730 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
4731 jmp 1b
4732 2:
4733 diff -urNp linux-2.6.31.1/arch/x86/boot/compressed/head_64.S linux-2.6.31.1/arch/x86/boot/compressed/head_64.S
4734 --- linux-2.6.31.1/arch/x86/boot/compressed/head_64.S 2009-09-24 11:45:25.000000000 -0400
4735 +++ linux-2.6.31.1/arch/x86/boot/compressed/head_64.S 2009-10-01 20:12:42.000000000 -0400
4736 @@ -90,7 +90,7 @@ ENTRY(startup_32)
4737 notl %eax
4738 andl %eax, %ebx
4739 #else
4740 - movl $LOAD_PHYSICAL_ADDR, %ebx
4741 + movl $____LOAD_PHYSICAL_ADDR, %ebx
4742 #endif
4743
4744 /* Target address to relocate to for decompression */
4745 @@ -233,7 +233,7 @@ ENTRY(startup_64)
4746 notq %rax
4747 andq %rax, %rbp
4748 #else
4749 - movq $LOAD_PHYSICAL_ADDR, %rbp
4750 + movq $____LOAD_PHYSICAL_ADDR, %rbp
4751 #endif
4752
4753 /* Target address to relocate to for decompression */
4754 diff -urNp linux-2.6.31.1/arch/x86/boot/compressed/misc.c linux-2.6.31.1/arch/x86/boot/compressed/misc.c
4755 --- linux-2.6.31.1/arch/x86/boot/compressed/misc.c 2009-09-24 11:45:25.000000000 -0400
4756 +++ linux-2.6.31.1/arch/x86/boot/compressed/misc.c 2009-10-01 20:12:42.000000000 -0400
4757 @@ -288,7 +288,7 @@ static void parse_elf(void *output)
4758 case PT_LOAD:
4759 #ifdef CONFIG_RELOCATABLE
4760 dest = output;
4761 - dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
4762 + dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
4763 #else
4764 dest = (void *)(phdr->p_paddr);
4765 #endif
4766 @@ -335,7 +335,7 @@ asmlinkage void decompress_kernel(void *
4767 error("Destination address too large");
4768 #endif
4769 #ifndef CONFIG_RELOCATABLE
4770 - if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
4771 + if ((unsigned long)output != ____LOAD_PHYSICAL_ADDR)
4772 error("Wrong destination address");
4773 #endif
4774
4775 diff -urNp linux-2.6.31.1/arch/x86/boot/compressed/mkpiggy.c linux-2.6.31.1/arch/x86/boot/compressed/mkpiggy.c
4776 --- linux-2.6.31.1/arch/x86/boot/compressed/mkpiggy.c 2009-09-24 11:45:25.000000000 -0400
4777 +++ linux-2.6.31.1/arch/x86/boot/compressed/mkpiggy.c 2009-10-01 20:12:42.000000000 -0400
4778 @@ -74,7 +74,7 @@ int main(int argc, char *argv[])
4779
4780 offs = (olen > ilen) ? olen - ilen : 0;
4781 offs += olen >> 12; /* Add 8 bytes for each 32K block */
4782 - offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */
4783 + offs += 64*1024; /* Add 64K bytes slack */
4784 offs = (offs+4095) & ~4095; /* Round to a 4K boundary */
4785
4786 printf(".section \".rodata.compressed\",\"a\",@progbits\n");
4787 diff -urNp linux-2.6.31.1/arch/x86/boot/compressed/relocs.c linux-2.6.31.1/arch/x86/boot/compressed/relocs.c
4788 --- linux-2.6.31.1/arch/x86/boot/compressed/relocs.c 2009-09-24 11:45:25.000000000 -0400
4789 +++ linux-2.6.31.1/arch/x86/boot/compressed/relocs.c 2009-10-01 20:12:42.000000000 -0400
4790 @@ -10,8 +10,11 @@
4791 #define USE_BSD
4792 #include <endian.h>
4793
4794 +#include "../../../../include/linux/autoconf.h"
4795 +
4796 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
4797 static Elf32_Ehdr ehdr;
4798 +static Elf32_Phdr *phdr;
4799 static unsigned long reloc_count, reloc_idx;
4800 static unsigned long *relocs;
4801
4802 @@ -37,7 +40,7 @@ static const char* safe_abs_relocs[] = {
4803
4804 static int is_safe_abs_reloc(const char* sym_name)
4805 {
4806 - int i;
4807 + unsigned int i;
4808
4809 for (i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) {
4810 if (!strcmp(sym_name, safe_abs_relocs[i]))
4811 @@ -245,9 +248,39 @@ static void read_ehdr(FILE *fp)
4812 }
4813 }
4814
4815 +static void read_phdrs(FILE *fp)
4816 +{
4817 + unsigned int i;
4818 +
4819 + phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
4820 + if (!phdr) {
4821 + die("Unable to allocate %d program headers\n",
4822 + ehdr.e_phnum);
4823 + }
4824 + if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
4825 + die("Seek to %d failed: %s\n",
4826 + ehdr.e_phoff, strerror(errno));
4827 + }
4828 + if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
4829 + die("Cannot read ELF program headers: %s\n",
4830 + strerror(errno));
4831 + }
4832 + for(i = 0; i < ehdr.e_phnum; i++) {
4833 + phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
4834 + phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
4835 + phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
4836 + phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
4837 + phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
4838 + phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
4839 + phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
4840 + phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
4841 + }
4842 +
4843 +}
4844 +
4845 static void read_shdrs(FILE *fp)
4846 {
4847 - int i;
4848 + unsigned int i;
4849 Elf32_Shdr shdr;
4850
4851 secs = calloc(ehdr.e_shnum, sizeof(struct section));
4852 @@ -282,7 +315,7 @@ static void read_shdrs(FILE *fp)
4853
4854 static void read_strtabs(FILE *fp)
4855 {
4856 - int i;
4857 + unsigned int i;
4858 for (i = 0; i < ehdr.e_shnum; i++) {
4859 struct section *sec = &secs[i];
4860 if (sec->shdr.sh_type != SHT_STRTAB) {
4861 @@ -307,7 +340,7 @@ static void read_strtabs(FILE *fp)
4862
4863 static void read_symtabs(FILE *fp)
4864 {
4865 - int i,j;
4866 + unsigned int i,j;
4867 for (i = 0; i < ehdr.e_shnum; i++) {
4868 struct section *sec = &secs[i];
4869 if (sec->shdr.sh_type != SHT_SYMTAB) {
4870 @@ -340,7 +373,9 @@ static void read_symtabs(FILE *fp)
4871
4872 static void read_relocs(FILE *fp)
4873 {
4874 - int i,j;
4875 + unsigned int i,j;
4876 + uint32_t base;
4877 +
4878 for (i = 0; i < ehdr.e_shnum; i++) {
4879 struct section *sec = &secs[i];
4880 if (sec->shdr.sh_type != SHT_REL) {
4881 @@ -360,9 +395,18 @@ static void read_relocs(FILE *fp)
4882 die("Cannot read symbol table: %s\n",
4883 strerror(errno));
4884 }
4885 + base = 0;
4886 + for (j = 0; j < ehdr.e_phnum; j++) {
4887 + if (phdr[j].p_type != PT_LOAD )
4888 + continue;
4889 + if (secs[sec->shdr.sh_info].shdr.sh_offset < phdr[j].p_offset || secs[sec->shdr.sh_info].shdr.sh_offset >= phdr[j].p_offset + phdr[j].p_filesz)
4890 + continue;
4891 + base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
4892 + break;
4893 + }
4894 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
4895 Elf32_Rel *rel = &sec->reltab[j];
4896 - rel->r_offset = elf32_to_cpu(rel->r_offset);
4897 + rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
4898 rel->r_info = elf32_to_cpu(rel->r_info);
4899 }
4900 }
4901 @@ -371,14 +415,14 @@ static void read_relocs(FILE *fp)
4902
4903 static void print_absolute_symbols(void)
4904 {
4905 - int i;
4906 + unsigned int i;
4907 printf("Absolute symbols\n");
4908 printf(" Num: Value Size Type Bind Visibility Name\n");
4909 for (i = 0; i < ehdr.e_shnum; i++) {
4910 struct section *sec = &secs[i];
4911 char *sym_strtab;
4912 Elf32_Sym *sh_symtab;
4913 - int j;
4914 + unsigned int j;
4915
4916 if (sec->shdr.sh_type != SHT_SYMTAB) {
4917 continue;
4918 @@ -406,14 +450,14 @@ static void print_absolute_symbols(void)
4919
4920 static void print_absolute_relocs(void)
4921 {
4922 - int i, printed = 0;
4923 + unsigned int i, printed = 0;
4924
4925 for (i = 0; i < ehdr.e_shnum; i++) {
4926 struct section *sec = &secs[i];
4927 struct section *sec_applies, *sec_symtab;
4928 char *sym_strtab;
4929 Elf32_Sym *sh_symtab;
4930 - int j;
4931 + unsigned int j;
4932 if (sec->shdr.sh_type != SHT_REL) {
4933 continue;
4934 }
4935 @@ -474,13 +518,13 @@ static void print_absolute_relocs(void)
4936
4937 static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym))
4938 {
4939 - int i;
4940 + unsigned int i;
4941 /* Walk through the relocations */
4942 for (i = 0; i < ehdr.e_shnum; i++) {
4943 char *sym_strtab;
4944 Elf32_Sym *sh_symtab;
4945 struct section *sec_applies, *sec_symtab;
4946 - int j;
4947 + unsigned int j;
4948 struct section *sec = &secs[i];
4949
4950 if (sec->shdr.sh_type != SHT_REL) {
4951 @@ -504,6 +548,19 @@ static void walk_relocs(void (*visit)(El
4952 if (sym->st_shndx == SHN_ABS) {
4953 continue;
4954 }
4955 + /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
4956 + if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strcmp(sym_name(sym_strtab, sym), "__per_cpu_load"))
4957 + continue;
4958 +
4959 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
4960 + /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
4961 + if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
4962 + continue;
4963 + if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
4964 + continue;
4965 + if (!strcmp(sec_name(sym->st_shndx), ".text") && strcmp(sym_name(sym_strtab, sym), "__LOAD_PHYSICAL_ADDR"))
4966 + continue;
4967 +#endif
4968 if (r_type == R_386_NONE || r_type == R_386_PC32) {
4969 /*
4970 * NONE can be ignored and and PC relative
4971 @@ -541,7 +598,7 @@ static int cmp_relocs(const void *va, co
4972
4973 static void emit_relocs(int as_text)
4974 {
4975 - int i;
4976 + unsigned int i;
4977 /* Count how many relocations I have and allocate space for them. */
4978 reloc_count = 0;
4979 walk_relocs(count_reloc);
4980 @@ -634,6 +691,7 @@ int main(int argc, char **argv)
4981 fname, strerror(errno));
4982 }
4983 read_ehdr(fp);
4984 + read_phdrs(fp);
4985 read_shdrs(fp);
4986 read_strtabs(fp);
4987 read_symtabs(fp);
4988 diff -urNp linux-2.6.31.1/arch/x86/boot/cpucheck.c linux-2.6.31.1/arch/x86/boot/cpucheck.c
4989 --- linux-2.6.31.1/arch/x86/boot/cpucheck.c 2009-09-24 11:45:25.000000000 -0400
4990 +++ linux-2.6.31.1/arch/x86/boot/cpucheck.c 2009-10-01 20:12:42.000000000 -0400
4991 @@ -74,7 +74,7 @@ static int has_fpu(void)
4992 u16 fcw = -1, fsw = -1;
4993 u32 cr0;
4994
4995 - asm("movl %%cr0,%0" : "=r" (cr0));
4996 + asm volatile("movl %%cr0,%0" : "=r" (cr0));
4997 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
4998 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
4999 asm volatile("movl %0,%%cr0" : : "r" (cr0));
5000 @@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
5001 {
5002 u32 f0, f1;
5003
5004 - asm("pushfl ; "
5005 + asm volatile("pushfl ; "
5006 "pushfl ; "
5007 "popl %0 ; "
5008 "movl %0,%1 ; "
5009 @@ -115,7 +115,7 @@ static void get_flags(void)
5010 set_bit(X86_FEATURE_FPU, cpu.flags);
5011
5012 if (has_eflag(X86_EFLAGS_ID)) {
5013 - asm("cpuid"
5014 + asm volatile("cpuid"
5015 : "=a" (max_intel_level),
5016 "=b" (cpu_vendor[0]),
5017 "=d" (cpu_vendor[1]),
5018 @@ -124,7 +124,7 @@ static void get_flags(void)
5019
5020 if (max_intel_level >= 0x00000001 &&
5021 max_intel_level <= 0x0000ffff) {
5022 - asm("cpuid"
5023 + asm volatile("cpuid"
5024 : "=a" (tfms),
5025 "=c" (cpu.flags[4]),
5026 "=d" (cpu.flags[0])
5027 @@ -136,7 +136,7 @@ static void get_flags(void)
5028 cpu.model += ((tfms >> 16) & 0xf) << 4;
5029 }
5030
5031 - asm("cpuid"
5032 + asm volatile("cpuid"
5033 : "=a" (max_amd_level)
5034 : "a" (0x80000000)
5035 : "ebx", "ecx", "edx");
5036 @@ -144,7 +144,7 @@ static void get_flags(void)
5037 if (max_amd_level >= 0x80000001 &&
5038 max_amd_level <= 0x8000ffff) {
5039 u32 eax = 0x80000001;
5040 - asm("cpuid"
5041 + asm volatile("cpuid"
5042 : "+a" (eax),
5043 "=c" (cpu.flags[6]),
5044 "=d" (cpu.flags[1])
5045 @@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
5046 u32 ecx = MSR_K7_HWCR;
5047 u32 eax, edx;
5048
5049 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5050 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5051 eax &= ~(1 << 15);
5052 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5053 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5054
5055 get_flags(); /* Make sure it really did something */
5056 err = check_flags();
5057 @@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
5058 u32 ecx = MSR_VIA_FCR;
5059 u32 eax, edx;
5060
5061 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5062 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5063 eax |= (1<<1)|(1<<7);
5064 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5065 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5066
5067 set_bit(X86_FEATURE_CX8, cpu.flags);
5068 err = check_flags();
5069 @@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
5070 u32 eax, edx;
5071 u32 level = 1;
5072
5073 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5074 - asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
5075 - asm("cpuid"
5076 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5077 + asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
5078 + asm volatile("cpuid"
5079 : "+a" (level), "=d" (cpu.flags[0])
5080 : : "ecx", "ebx");
5081 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5082 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5083
5084 err = check_flags();
5085 }
5086 diff -urNp linux-2.6.31.1/arch/x86/boot/header.S linux-2.6.31.1/arch/x86/boot/header.S
5087 --- linux-2.6.31.1/arch/x86/boot/header.S 2009-09-24 11:45:25.000000000 -0400
5088 +++ linux-2.6.31.1/arch/x86/boot/header.S 2009-10-01 20:12:42.000000000 -0400
5089 @@ -224,7 +224,7 @@ setup_data: .quad 0 # 64-bit physical
5090 # single linked list of
5091 # struct setup_data
5092
5093 -pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
5094 +pref_address: .quad ____LOAD_PHYSICAL_ADDR # preferred load addr
5095
5096 #define ZO_INIT_SIZE (ZO__end - ZO_startup_32 + ZO_z_extract_offset)
5097 #define VO_INIT_SIZE (VO__end - VO__text)
5098 diff -urNp linux-2.6.31.1/arch/x86/boot/video-vesa.c linux-2.6.31.1/arch/x86/boot/video-vesa.c
5099 --- linux-2.6.31.1/arch/x86/boot/video-vesa.c 2009-09-24 11:45:25.000000000 -0400
5100 +++ linux-2.6.31.1/arch/x86/boot/video-vesa.c 2009-10-01 20:12:42.000000000 -0400
5101 @@ -205,6 +205,7 @@ static void vesa_store_pm_info(void)
5102
5103 boot_params.screen_info.vesapm_seg = oreg.es;
5104 boot_params.screen_info.vesapm_off = oreg.di;
5105 + boot_params.screen_info.vesapm_size = oreg.cx;
5106 }
5107
5108 /*
5109 diff -urNp linux-2.6.31.1/arch/x86/ia32/ia32_signal.c linux-2.6.31.1/arch/x86/ia32/ia32_signal.c
5110 --- linux-2.6.31.1/arch/x86/ia32/ia32_signal.c 2009-09-24 11:45:25.000000000 -0400
5111 +++ linux-2.6.31.1/arch/x86/ia32/ia32_signal.c 2009-10-01 20:12:42.000000000 -0400
5112 @@ -403,7 +403,7 @@ static void __user *get_sigframe(struct
5113 sp -= frame_size;
5114 /* Align the stack pointer according to the i386 ABI,
5115 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
5116 - sp = ((sp + 4) & -16ul) - 4;
5117 + sp = ((sp - 12) & -16ul) - 4;
5118 return (void __user *) sp;
5119 }
5120
5121 @@ -503,7 +503,7 @@ int ia32_setup_rt_frame(int sig, struct
5122 0xb8,
5123 __NR_ia32_rt_sigreturn,
5124 0x80cd,
5125 - 0,
5126 + 0
5127 };
5128
5129 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
5130 diff -urNp linux-2.6.31.1/arch/x86/include/asm/alternative.h linux-2.6.31.1/arch/x86/include/asm/alternative.h
5131 --- linux-2.6.31.1/arch/x86/include/asm/alternative.h 2009-09-24 11:45:25.000000000 -0400
5132 +++ linux-2.6.31.1/arch/x86/include/asm/alternative.h 2009-10-01 20:12:42.000000000 -0400
5133 @@ -87,7 +87,7 @@ const unsigned char *const *find_nop_tab
5134 " .byte 662b-661b\n" /* sourcelen */ \
5135 " .byte 664f-663f\n" /* replacementlen */ \
5136 ".previous\n" \
5137 - ".section .altinstr_replacement, \"ax\"\n" \
5138 + ".section .altinstr_replacement, \"a\"\n" \
5139 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
5140 ".previous"
5141
5142 diff -urNp linux-2.6.31.1/arch/x86/include/asm/apm.h linux-2.6.31.1/arch/x86/include/asm/apm.h
5143 --- linux-2.6.31.1/arch/x86/include/asm/apm.h 2009-09-24 11:45:25.000000000 -0400
5144 +++ linux-2.6.31.1/arch/x86/include/asm/apm.h 2009-10-01 20:12:42.000000000 -0400
5145 @@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
5146 __asm__ __volatile__(APM_DO_ZERO_SEGS
5147 "pushl %%edi\n\t"
5148 "pushl %%ebp\n\t"
5149 - "lcall *%%cs:apm_bios_entry\n\t"
5150 + "lcall *%%ss:apm_bios_entry\n\t"
5151 "setc %%al\n\t"
5152 "popl %%ebp\n\t"
5153 "popl %%edi\n\t"
5154 @@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
5155 __asm__ __volatile__(APM_DO_ZERO_SEGS
5156 "pushl %%edi\n\t"
5157 "pushl %%ebp\n\t"
5158 - "lcall *%%cs:apm_bios_entry\n\t"
5159 + "lcall *%%ss:apm_bios_entry\n\t"
5160 "setc %%bl\n\t"
5161 "popl %%ebp\n\t"
5162 "popl %%edi\n\t"
5163 diff -urNp linux-2.6.31.1/arch/x86/include/asm/atomic_32.h linux-2.6.31.1/arch/x86/include/asm/atomic_32.h
5164 --- linux-2.6.31.1/arch/x86/include/asm/atomic_32.h 2009-09-24 11:45:25.000000000 -0400
5165 +++ linux-2.6.31.1/arch/x86/include/asm/atomic_32.h 2009-10-01 20:12:42.000000000 -0400
5166 @@ -25,6 +25,17 @@ static inline int atomic_read(const atom
5167 }
5168
5169 /**
5170 + * atomic_read_unchecked - read atomic variable
5171 + * @v: pointer of type atomic_unchecked_t
5172 + *
5173 + * Atomically reads the value of @v.
5174 + */
5175 +static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
5176 +{
5177 + return v->counter;
5178 +}
5179 +
5180 +/**
5181 * atomic_set - set atomic variable
5182 * @v: pointer of type atomic_t
5183 * @i: required value
5184 @@ -37,6 +48,18 @@ static inline void atomic_set(atomic_t *
5185 }
5186
5187 /**
5188 + * atomic_set_unchecked - set atomic variable
5189 + * @v: pointer of type atomic_unchecked_t
5190 + * @i: required value
5191 + *
5192 + * Atomically sets the value of @v to @i.
5193 + */
5194 +static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
5195 +{
5196 + v->counter = i;
5197 +}
5198 +
5199 +/**
5200 * atomic_add - add integer to atomic variable
5201 * @i: integer value to add
5202 * @v: pointer of type atomic_t
5203 @@ -45,7 +68,29 @@ static inline void atomic_set(atomic_t *
5204 */
5205 static inline void atomic_add(int i, atomic_t *v)
5206 {
5207 - asm volatile(LOCK_PREFIX "addl %1,%0"
5208 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
5209 +
5210 +#ifdef CONFIG_PAX_REFCOUNT
5211 + "jno 0f\n"
5212 + LOCK_PREFIX "subl %1,%0\n"
5213 + "into\n0:\n"
5214 + _ASM_EXTABLE(0b, 0b)
5215 +#endif
5216 +
5217 + : "+m" (v->counter)
5218 + : "ir" (i));
5219 +}
5220 +
5221 +/**
5222 + * atomic_add_unchecked - add integer to atomic variable
5223 + * @i: integer value to add
5224 + * @v: pointer of type atomic_unchecked_t
5225 + *
5226 + * Atomically adds @i to @v.
5227 + */
5228 +static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
5229 +{
5230 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
5231 : "+m" (v->counter)
5232 : "ir" (i));
5233 }
5234 @@ -59,7 +104,29 @@ static inline void atomic_add(int i, ato
5235 */
5236 static inline void atomic_sub(int i, atomic_t *v)
5237 {
5238 - asm volatile(LOCK_PREFIX "subl %1,%0"
5239 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
5240 +
5241 +#ifdef CONFIG_PAX_REFCOUNT
5242 + "jno 0f\n"
5243 + LOCK_PREFIX "addl %1,%0\n"
5244 + "into\n0:\n"
5245 + _ASM_EXTABLE(0b, 0b)
5246 +#endif
5247 +
5248 + : "+m" (v->counter)
5249 + : "ir" (i));
5250 +}
5251 +
5252 +/**
5253 + * atomic_sub_unchecked - subtract integer from atomic variable
5254 + * @i: integer value to subtract
5255 + * @v: pointer of type atomic_t
5256 + *
5257 + * Atomically subtracts @i from @v.
5258 + */
5259 +static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
5260 +{
5261 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
5262 : "+m" (v->counter)
5263 : "ir" (i));
5264 }
5265 @@ -77,7 +144,16 @@ static inline int atomic_sub_and_test(in
5266 {
5267 unsigned char c;
5268
5269 - asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
5270 + asm volatile(LOCK_PREFIX "subl %2,%0\n"
5271 +
5272 +#ifdef CONFIG_PAX_REFCOUNT
5273 + "jno 0f\n"
5274 + LOCK_PREFIX "addl %2,%0\n"
5275 + "into\n0:\n"
5276 + _ASM_EXTABLE(0b, 0b)
5277 +#endif
5278 +
5279 + "sete %1\n"
5280 : "+m" (v->counter), "=qm" (c)
5281 : "ir" (i) : "memory");
5282 return c;
5283 @@ -91,7 +167,30 @@ static inline int atomic_sub_and_test(in
5284 */
5285 static inline void atomic_inc(atomic_t *v)
5286 {
5287 - asm volatile(LOCK_PREFIX "incl %0"
5288 + asm volatile(LOCK_PREFIX "incl %0\n"
5289 +
5290 +#ifdef CONFIG_PAX_REFCOUNT
5291 + "into\n0:\n"
5292 + ".pushsection .fixup,\"ax\"\n"
5293 + "1:\n"
5294 + LOCK_PREFIX "decl %0\n"
5295 + "jmp 0b\n"
5296 + ".popsection\n"
5297 + _ASM_EXTABLE(0b, 1b)
5298 +#endif
5299 +
5300 + : "+m" (v->counter));
5301 +}
5302 +
5303 +/**
5304 + * atomic_inc_unchecked - increment atomic variable
5305 + * @v: pointer of type atomic_unchecked_t
5306 + *
5307 + * Atomically increments @v by 1.
5308 + */
5309 +static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
5310 +{
5311 + asm volatile(LOCK_PREFIX "incl %0\n"
5312 : "+m" (v->counter));
5313 }
5314
5315 @@ -103,7 +202,18 @@ static inline void atomic_inc(atomic_t *
5316 */
5317 static inline void atomic_dec(atomic_t *v)
5318 {
5319 - asm volatile(LOCK_PREFIX "decl %0"
5320 + asm volatile(LOCK_PREFIX "decl %0\n"
5321 +
5322 +#ifdef CONFIG_PAX_REFCOUNT
5323 + "into\n0:\n"
5324 + ".pushsection .fixup,\"ax\"\n"
5325 + "1: \n"
5326 + LOCK_PREFIX "incl %0\n"
5327 + "jmp 0b\n"
5328 + ".popsection\n"
5329 + _ASM_EXTABLE(0b, 1b)
5330 +#endif
5331 +
5332 : "+m" (v->counter));
5333 }
5334
5335 @@ -119,7 +229,19 @@ static inline int atomic_dec_and_test(at
5336 {
5337 unsigned char c;
5338
5339 - asm volatile(LOCK_PREFIX "decl %0; sete %1"
5340 + asm volatile(LOCK_PREFIX "decl %0\n"
5341 +
5342 +#ifdef CONFIG_PAX_REFCOUNT
5343 + "into\n0:\n"
5344 + ".pushsection .fixup,\"ax\"\n"
5345 + "1: \n"
5346 + LOCK_PREFIX "incl %0\n"
5347 + "jmp 0b\n"
5348 + ".popsection\n"
5349 + _ASM_EXTABLE(0b, 1b)
5350 +#endif
5351 +
5352 + "sete %1\n"
5353 : "+m" (v->counter), "=qm" (c)
5354 : : "memory");
5355 return c != 0;
5356 @@ -137,7 +259,19 @@ static inline int atomic_inc_and_test(at
5357 {
5358 unsigned char c;
5359
5360 - asm volatile(LOCK_PREFIX "incl %0; sete %1"
5361 + asm volatile(LOCK_PREFIX "incl %0\n"
5362 +
5363 +#ifdef CONFIG_PAX_REFCOUNT
5364 + "into\n0:\n"
5365 + ".pushsection .fixup,\"ax\"\n"
5366 + "1: \n"
5367 + LOCK_PREFIX "decl %0\n"
5368 + "jmp 0b\n"
5369 + ".popsection\n"
5370 + _ASM_EXTABLE(0b, 1b)
5371 +#endif
5372 +
5373 + "sete %1\n"
5374 : "+m" (v->counter), "=qm" (c)
5375 : : "memory");
5376 return c != 0;
5377 @@ -156,7 +290,16 @@ static inline int atomic_add_negative(in
5378 {
5379 unsigned char c;
5380
5381 - asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
5382 + asm volatile(LOCK_PREFIX "addl %2,%0\n"
5383 +
5384 +#ifdef CONFIG_PAX_REFCOUNT
5385 + "jno 0f\n"
5386 + LOCK_PREFIX "subl %2,%0\n"
5387 + "into\n0:\n"
5388 + _ASM_EXTABLE(0b, 0b)
5389 +#endif
5390 +
5391 + "sets %1\n"
5392 : "+m" (v->counter), "=qm" (c)
5393 : "ir" (i) : "memory");
5394 return c;
5395 @@ -179,7 +322,15 @@ static inline int atomic_add_return(int
5396 #endif
5397 /* Modern 486+ processor */
5398 __i = i;
5399 - asm volatile(LOCK_PREFIX "xaddl %0, %1"
5400 + asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
5401 +
5402 +#ifdef CONFIG_PAX_REFCOUNT
5403 + "jno 0f\n"
5404 + "movl %0, %1\n"
5405 + "into\n0:\n"
5406 + _ASM_EXTABLE(0b, 0b)
5407 +#endif
5408 +
5409 : "+r" (i), "+m" (v->counter)
5410 : : "memory");
5411 return i + __i;
5412 @@ -227,17 +378,28 @@ static inline int atomic_xchg(atomic_t *
5413 */
5414 static inline int atomic_add_unless(atomic_t *v, int a, int u)
5415 {
5416 - int c, old;
5417 + int c, old, new;
5418 c = atomic_read(v);
5419 for (;;) {
5420 - if (unlikely(c == (u)))
5421 + if (unlikely(c == u))
5422 break;
5423 - old = atomic_cmpxchg((v), c, c + (a));
5424 +
5425 + asm volatile("addl %2,%0\n"
5426 +
5427 +#ifdef CONFIG_PAX_REFCOUNT
5428 + "into\n0:\n"
5429 + _ASM_EXTABLE(0b, 0b)
5430 +#endif
5431 +
5432 + : "=r" (new)
5433 + : "0" (c), "ir" (a));
5434 +
5435 + old = atomic_cmpxchg(v, c, new);
5436 if (likely(old == c))
5437 break;
5438 c = old;
5439 }
5440 - return c != (u);
5441 + return c != u;
5442 }
5443
5444 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
5445 diff -urNp linux-2.6.31.1/arch/x86/include/asm/atomic_64.h linux-2.6.31.1/arch/x86/include/asm/atomic_64.h
5446 --- linux-2.6.31.1/arch/x86/include/asm/atomic_64.h 2009-09-24 11:45:25.000000000 -0400
5447 +++ linux-2.6.31.1/arch/x86/include/asm/atomic_64.h 2009-10-01 20:12:42.000000000 -0400
5448 @@ -24,6 +24,17 @@ static inline int atomic_read(const atom
5449 }
5450
5451 /**
5452 + * atomic_read_unchecked - read atomic variable
5453 + * @v: pointer of type atomic_unchecked_t
5454 + *
5455 + * Atomically reads the value of @v.
5456 + */
5457 +static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
5458 +{
5459 + return v->counter;
5460 +}
5461 +
5462 +/**
5463 * atomic_set - set atomic variable
5464 * @v: pointer of type atomic_t
5465 * @i: required value
5466 @@ -36,6 +47,18 @@ static inline void atomic_set(atomic_t *
5467 }
5468
5469 /**
5470 + * atomic_set_unchecked - set atomic variable
5471 + * @v: pointer of type atomic_unchecked_t
5472 + * @i: required value
5473 + *
5474 + * Atomically sets the value of @v to @i.
5475 + */
5476 +static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
5477 +{
5478 + v->counter = i;
5479 +}
5480 +
5481 +/**
5482 * atomic_add - add integer to atomic variable
5483 * @i: integer value to add
5484 * @v: pointer of type atomic_t
5485 @@ -44,7 +67,29 @@ static inline void atomic_set(atomic_t *
5486 */
5487 static inline void atomic_add(int i, atomic_t *v)
5488 {
5489 - asm volatile(LOCK_PREFIX "addl %1,%0"
5490 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
5491 +
5492 +#ifdef CONFIG_PAX_REFCOUNT
5493 + "jno 0f\n"
5494 + LOCK_PREFIX "subl %1,%0\n"
5495 + "int $4\n0:\n"
5496 + _ASM_EXTABLE(0b, 0b)
5497 +#endif
5498 +
5499 + : "=m" (v->counter)
5500 + : "ir" (i), "m" (v->counter));
5501 +}
5502 +
5503 +/**
5504 + * atomic_add_unchecked - add integer to atomic variable
5505 + * @i: integer value to add
5506 + * @v: pointer of type atomic_unchecked_t
5507 + *
5508 + * Atomically adds @i to @v.
5509 + */
5510 +static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
5511 +{
5512 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
5513 : "=m" (v->counter)
5514 : "ir" (i), "m" (v->counter));
5515 }
5516 @@ -58,7 +103,29 @@ static inline void atomic_add(int i, ato
5517 */
5518 static inline void atomic_sub(int i, atomic_t *v)
5519 {
5520 - asm volatile(LOCK_PREFIX "subl %1,%0"
5521 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
5522 +
5523 +#ifdef CONFIG_PAX_REFCOUNT
5524 + "jno 0f\n"
5525 + LOCK_PREFIX "addl %1,%0\n"
5526 + "int $4\n0:\n"
5527 + _ASM_EXTABLE(0b, 0b)
5528 +#endif
5529 +
5530 + : "=m" (v->counter)
5531 + : "ir" (i), "m" (v->counter));
5532 +}
5533 +
5534 +/**
5535 + * atomic_sub_unchecked - subtract the atomic variable
5536 + * @i: integer value to subtract
5537 + * @v: pointer of type atomic_unchecked_t
5538 + *
5539 + * Atomically subtracts @i from @v.
5540 + */
5541 +static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
5542 +{
5543 + asm volatile(LOCK_PREFIX "subl %1,%0\n"
5544 : "=m" (v->counter)
5545 : "ir" (i), "m" (v->counter));
5546 }
5547 @@ -76,7 +143,16 @@ static inline int atomic_sub_and_test(in
5548 {
5549 unsigned char c;
5550
5551 - asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
5552 + asm volatile(LOCK_PREFIX "subl %2,%0\n"
5553 +
5554 +#ifdef CONFIG_PAX_REFCOUNT
5555 + "jno 0f\n"
5556 + LOCK_PREFIX "addl %2,%0\n"
5557 + "int $4\n0:\n"
5558 + _ASM_EXTABLE(0b, 0b)
5559 +#endif
5560 +
5561 + "sete %1\n"
5562 : "=m" (v->counter), "=qm" (c)
5563 : "ir" (i), "m" (v->counter) : "memory");
5564 return c;
5565 @@ -90,7 +166,32 @@ static inline int atomic_sub_and_test(in
5566 */
5567 static inline void atomic_inc(atomic_t *v)
5568 {
5569 - asm volatile(LOCK_PREFIX "incl %0"
5570 + asm volatile(LOCK_PREFIX "incl %0\n"
5571 +
5572 +#ifdef CONFIG_PAX_REFCOUNT
5573 + "jno 0f\n"
5574 + "int $4\n0:\n"
5575 + ".pushsection .fixup,\"ax\"\n"
5576 + "1:\n"
5577 + LOCK_PREFIX "decl %0\n"
5578 + "jmp 0b\n"
5579 + ".popsection\n"
5580 + _ASM_EXTABLE(0b, 1b)
5581 +#endif
5582 +
5583 + : "=m" (v->counter)
5584 + : "m" (v->counter));
5585 +}
5586 +
5587 +/**
5588 + * atomic_inc_unchecked - increment atomic variable
5589 + * @v: pointer of type atomic_unchecked_t
5590 + *
5591 + * Atomically increments @v by 1.
5592 + */
5593 +static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
5594 +{
5595 + asm volatile(LOCK_PREFIX "incl %0\n"
5596 : "=m" (v->counter)
5597 : "m" (v->counter));
5598 }
5599 @@ -103,7 +204,19 @@ static inline void atomic_inc(atomic_t *
5600 */
5601 static inline void atomic_dec(atomic_t *v)
5602 {
5603 - asm volatile(LOCK_PREFIX "decl %0"
5604 + asm volatile(LOCK_PREFIX "decl %0\n"
5605 +
5606 +#ifdef CONFIG_PAX_REFCOUNT
5607 + "jno 0f\n"
5608 + "int $4\n0:\n"
5609 + ".pushsection .fixup,\"ax\"\n"
5610 + "1: \n"
5611 + LOCK_PREFIX "incl %0\n"
5612 + "jmp 0b\n"
5613 + ".popsection\n"
5614 + _ASM_EXTABLE(0b, 1b)
5615 +#endif
5616 +
5617 : "=m" (v->counter)
5618 : "m" (v->counter));
5619 }
5620 @@ -120,7 +233,20 @@ static inline int atomic_dec_and_test(at
5621 {
5622 unsigned char c;
5623
5624 - asm volatile(LOCK_PREFIX "decl %0; sete %1"
5625 + asm volatile(LOCK_PREFIX "decl %0\n"
5626 +
5627 +#ifdef CONFIG_PAX_REFCOUNT
5628 + "jno 0f\n"
5629 + "int $4\n0:\n"
5630 + ".pushsection .fixup,\"ax\"\n"
5631 + "1: \n"
5632 + LOCK_PREFIX "incl %0\n"
5633 + "jmp 0b\n"
5634 + ".popsection\n"
5635 + _ASM_EXTABLE(0b, 1b)
5636 +#endif
5637 +
5638 + "sete %1\n"
5639 : "=m" (v->counter), "=qm" (c)
5640 : "m" (v->counter) : "memory");
5641 return c != 0;
5642 @@ -138,7 +264,20 @@ static inline int atomic_inc_and_test(at
5643 {
5644 unsigned char c;
5645
5646 - asm volatile(LOCK_PREFIX "incl %0; sete %1"
5647 + asm volatile(LOCK_PREFIX "incl %0\n"
5648 +
5649 +#ifdef CONFIG_PAX_REFCOUNT
5650 + "jno 0f\n"
5651 + "int $4\n0:\n"
5652 + ".pushsection .fixup,\"ax\"\n"
5653 + "1: \n"
5654 + LOCK_PREFIX "decl %0\n"
5655 + "jmp 0b\n"
5656 + ".popsection\n"
5657 + _ASM_EXTABLE(0b, 1b)
5658 +#endif
5659 +
5660 + "sete %1\n"
5661 : "=m" (v->counter), "=qm" (c)
5662 : "m" (v->counter) : "memory");
5663 return c != 0;
5664 @@ -157,7 +296,16 @@ static inline int atomic_add_negative(in
5665 {
5666 unsigned char c;
5667
5668 - asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
5669 + asm volatile(LOCK_PREFIX "addl %2,%0\n"
5670 +
5671 +#ifdef CONFIG_PAX_REFCOUNT
5672 + "jno 0f\n"
5673 + LOCK_PREFIX "subl %2,%0\n"
5674 + "int $4\n0:\n"
5675 + _ASM_EXTABLE(0b, 0b)
5676 +#endif
5677 +
5678 + "sets %1\n"
5679 : "=m" (v->counter), "=qm" (c)
5680 : "ir" (i), "m" (v->counter) : "memory");
5681 return c;
5682 @@ -173,7 +321,15 @@ static inline int atomic_add_negative(in
5683 static inline int atomic_add_return(int i, atomic_t *v)
5684 {
5685 int __i = i;
5686 - asm volatile(LOCK_PREFIX "xaddl %0, %1"
5687 + asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
5688 +
5689 +#ifdef CONFIG_PAX_REFCOUNT
5690 + "jno 0f\n"
5691 + "movl %0, %1\n"
5692 + "int $4\n0:\n"
5693 + _ASM_EXTABLE(0b, 0b)
5694 +#endif
5695 +
5696 : "+r" (i), "+m" (v->counter)
5697 : : "memory");
5698 return i + __i;
5699 @@ -224,7 +380,15 @@ static inline void atomic64_set(atomic64
5700 */
5701 static inline void atomic64_add(long i, atomic64_t *v)
5702 {
5703 - asm volatile(LOCK_PREFIX "addq %1,%0"
5704 + asm volatile(LOCK_PREFIX "addq %1,%0\n"
5705 +
5706 +#ifdef CONFIG_PAX_REFCOUNT
5707 + "jno 0f\n"
5708 + LOCK_PREFIX "subq %1,%0\n"
5709 + "int $4\n0:\n"
5710 + _ASM_EXTABLE(0b, 0b)
5711 +#endif
5712 +
5713 : "=m" (v->counter)
5714 : "er" (i), "m" (v->counter));
5715 }
5716 @@ -238,7 +402,15 @@ static inline void atomic64_add(long i,
5717 */
5718 static inline void atomic64_sub(long i, atomic64_t *v)
5719 {
5720 - asm volatile(LOCK_PREFIX "subq %1,%0"
5721 + asm volatile(LOCK_PREFIX "subq %1,%0\n"
5722 +
5723 +#ifdef CONFIG_PAX_REFCOUNT
5724 + "jno 0f\n"
5725 + LOCK_PREFIX "addq %1,%0\n"
5726 + "int $4\n0:\n"
5727 + _ASM_EXTABLE(0b, 0b)
5728 +#endif
5729 +
5730 : "=m" (v->counter)
5731 : "er" (i), "m" (v->counter));
5732 }
5733 @@ -256,7 +428,16 @@ static inline int atomic64_sub_and_test(
5734 {
5735 unsigned char c;
5736
5737 - asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
5738 + asm volatile(LOCK_PREFIX "subq %2,%0\n"
5739 +
5740 +#ifdef CONFIG_PAX_REFCOUNT
5741 + "jno 0f\n"
5742 + LOCK_PREFIX "addq %2,%0\n"
5743 + "int $4\n0:\n"
5744 + _ASM_EXTABLE(0b, 0b)
5745 +#endif
5746 +
5747 + "sete %1\n"
5748 : "=m" (v->counter), "=qm" (c)
5749 : "er" (i), "m" (v->counter) : "memory");
5750 return c;
5751 @@ -270,7 +451,19 @@ static inline int atomic64_sub_and_test(
5752 */
5753 static inline void atomic64_inc(atomic64_t *v)
5754 {
5755 - asm volatile(LOCK_PREFIX "incq %0"
5756 + asm volatile(LOCK_PREFIX "incq %0\n"
5757 +
5758 +#ifdef CONFIG_PAX_REFCOUNT
5759 + "jno 0f\n"
5760 + "int $4\n0:\n"
5761 + ".pushsection .fixup,\"ax\"\n"
5762 + "1:\n"
5763 + LOCK_PREFIX "decq %0\n"
5764 + "jmp 0b\n"
5765 + ".popsection\n"
5766 + _ASM_EXTABLE(0b, 1b)
5767 +#endif
5768 +
5769 : "=m" (v->counter)
5770 : "m" (v->counter));
5771 }
5772 @@ -283,7 +476,19 @@ static inline void atomic64_inc(atomic64
5773 */
5774 static inline void atomic64_dec(atomic64_t *v)
5775 {
5776 - asm volatile(LOCK_PREFIX "decq %0"
5777 + asm volatile(LOCK_PREFIX "decq %0\n"
5778 +
5779 +#ifdef CONFIG_PAX_REFCOUNT
5780 + "jno 0f\n"
5781 + "int $4\n0:\n"
5782 + ".pushsection .fixup,\"ax\"\n"
5783 + "1: \n"
5784 + LOCK_PREFIX "incq %0\n"
5785 + "jmp 0b\n"
5786 + ".popsection\n"
5787 + _ASM_EXTABLE(0b, 1b)
5788 +#endif
5789 +
5790 : "=m" (v->counter)
5791 : "m" (v->counter));
5792 }
5793 @@ -300,7 +505,20 @@ static inline int atomic64_dec_and_test(
5794 {
5795 unsigned char c;
5796
5797 - asm volatile(LOCK_PREFIX "decq %0; sete %1"
5798 + asm volatile(LOCK_PREFIX "decq %0\n"
5799 +
5800 +#ifdef CONFIG_PAX_REFCOUNT
5801 + "jno 0f\n"
5802 + "int $4\n0:\n"
5803 + ".pushsection .fixup,\"ax\"\n"
5804 + "1: \n"
5805 + LOCK_PREFIX "incq %0\n"
5806 + "jmp 0b\n"
5807 + ".popsection\n"
5808 + _ASM_EXTABLE(0b, 1b)
5809 +#endif
5810 +
5811 + "sete %1\n"
5812 : "=m" (v->counter), "=qm" (c)
5813 : "m" (v->counter) : "memory");
5814 return c != 0;
5815 @@ -318,7 +536,20 @@ static inline int atomic64_inc_and_test(
5816 {
5817 unsigned char c;
5818
5819 - asm volatile(LOCK_PREFIX "incq %0; sete %1"
5820 + asm volatile(LOCK_PREFIX "incq %0\n"
5821 +
5822 +#ifdef CONFIG_PAX_REFCOUNT
5823 + "jno 0f\n"
5824 + "int $4\n0:\n"
5825 + ".pushsection .fixup,\"ax\"\n"
5826 + "1: \n"
5827 + LOCK_PREFIX "decq %0\n"
5828 + "jmp 0b\n"
5829 + ".popsection\n"
5830 + _ASM_EXTABLE(0b, 1b)
5831 +#endif
5832 +
5833 + "sete %1\n"
5834 : "=m" (v->counter), "=qm" (c)
5835 : "m" (v->counter) : "memory");
5836 return c != 0;
5837 @@ -337,7 +568,16 @@ static inline int atomic64_add_negative(
5838 {
5839 unsigned char c;
5840
5841 - asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
5842 + asm volatile(LOCK_PREFIX "addq %2,%0\n"
5843 +
5844 +#ifdef CONFIG_PAX_REFCOUNT
5845 + "jno 0f\n"
5846 + LOCK_PREFIX "subq %2,%0\n"
5847 + "int $4\n0:\n"
5848 + _ASM_EXTABLE(0b, 0b)
5849 +#endif
5850 +
5851 + "sets %1\n"
5852 : "=m" (v->counter), "=qm" (c)
5853 : "er" (i), "m" (v->counter) : "memory");
5854 return c;
5855 @@ -353,7 +593,15 @@ static inline int atomic64_add_negative(
5856 static inline long atomic64_add_return(long i, atomic64_t *v)
5857 {
5858 long __i = i;
5859 - asm volatile(LOCK_PREFIX "xaddq %0, %1;"
5860 + asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
5861 +
5862 +#ifdef CONFIG_PAX_REFCOUNT
5863 + "jno 0f\n"
5864 + "movq %0, %1\n"
5865 + "int $4\n0:\n"
5866 + _ASM_EXTABLE(0b, 0b)
5867 +#endif
5868 +
5869 : "+r" (i), "+m" (v->counter)
5870 : : "memory");
5871 return i + __i;
5872 @@ -398,17 +646,29 @@ static inline long atomic_xchg(atomic_t
5873 */
5874 static inline int atomic_add_unless(atomic_t *v, int a, int u)
5875 {
5876 - int c, old;
5877 + int c, old, new;
5878 c = atomic_read(v);
5879 for (;;) {
5880 - if (unlikely(c == (u)))
5881 + if (unlikely(c == u))
5882 break;
5883 - old = atomic_cmpxchg((v), c, c + (a));
5884 +
5885 + asm volatile("addl %2,%0\n"
5886 +
5887 +#ifdef CONFIG_PAX_REFCOUNT
5888 + "jno 0f\n"
5889 + "int $4\n0:\n"
5890 + _ASM_EXTABLE(0b, 0b)
5891 +#endif
5892 +
5893 + : "=r" (new)
5894 + : "0" (c), "ir" (a));
5895 +
5896 + old = atomic_cmpxchg(v, c, new);
5897 if (likely(old == c))
5898 break;
5899 c = old;
5900 }
5901 - return c != (u);
5902 + return c != u;
5903 }
5904
5905 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
5906 @@ -424,17 +684,29 @@ static inline int atomic_add_unless(atom
5907 */
5908 static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
5909 {
5910 - long c, old;
5911 + long c, old, new;
5912 c = atomic64_read(v);
5913 for (;;) {
5914 - if (unlikely(c == (u)))
5915 + if (unlikely(c == u))
5916 break;
5917 - old = atomic64_cmpxchg((v), c, c + (a));
5918 +
5919 + asm volatile("addq %2,%0\n"
5920 +
5921 +#ifdef CONFIG_PAX_REFCOUNT
5922 + "jno 0f\n"
5923 + "int $4\n0:\n"
5924 + _ASM_EXTABLE(0b, 0b)
5925 +#endif
5926 +
5927 + : "=r" (new)
5928 + : "0" (c), "er" (a));
5929 +
5930 + old = atomic64_cmpxchg((v), c, new);
5931 if (likely(old == c))
5932 break;
5933 c = old;
5934 }
5935 - return c != (u);
5936 + return c != u;
5937 }
5938
5939 /**
5940 diff -urNp linux-2.6.31.1/arch/x86/include/asm/boot.h linux-2.6.31.1/arch/x86/include/asm/boot.h
5941 --- linux-2.6.31.1/arch/x86/include/asm/boot.h 2009-09-24 11:45:25.000000000 -0400
5942 +++ linux-2.6.31.1/arch/x86/include/asm/boot.h 2009-10-01 20:12:42.000000000 -0400
5943 @@ -11,10 +11,15 @@
5944 #include <asm/pgtable_types.h>
5945
5946 /* Physical address where kernel should be loaded. */
5947 -#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
5948 +#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
5949 + (CONFIG_PHYSICAL_ALIGN - 1)) \
5950 & ~(CONFIG_PHYSICAL_ALIGN - 1))
5951
5952 +#ifndef __ASSEMBLY__
5953 +extern unsigned char __LOAD_PHYSICAL_ADDR[];
5954 +#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
5955 +#endif
5956 +
5957 /* Minimum kernel alignment, as a power of two */
5958 #ifdef CONFIG_X86_64
5959 #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT
5960 diff -urNp linux-2.6.31.1/arch/x86/include/asm/cache.h linux-2.6.31.1/arch/x86/include/asm/cache.h
5961 --- linux-2.6.31.1/arch/x86/include/asm/cache.h 2009-09-24 11:45:25.000000000 -0400
5962 +++ linux-2.6.31.1/arch/x86/include/asm/cache.h 2009-10-01 20:12:42.000000000 -0400
5963 @@ -6,6 +6,7 @@
5964 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
5965
5966 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
5967 +#define __read_only __attribute__((__section__(".data.read_only")))
5968
5969 #ifdef CONFIG_X86_VSMP
5970 /* vSMP Internode cacheline shift */
5971 diff -urNp linux-2.6.31.1/arch/x86/include/asm/checksum_32.h linux-2.6.31.1/arch/x86/include/asm/checksum_32.h
5972 --- linux-2.6.31.1/arch/x86/include/asm/checksum_32.h 2009-09-24 11:45:25.000000000 -0400
5973 +++ linux-2.6.31.1/arch/x86/include/asm/checksum_32.h 2009-10-01 20:12:42.000000000 -0400
5974 @@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
5975 int len, __wsum sum,
5976 int *src_err_ptr, int *dst_err_ptr);
5977
5978 +asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
5979 + int len, __wsum sum,
5980 + int *src_err_ptr, int *dst_err_ptr);
5981 +
5982 +asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
5983 + int len, __wsum sum,
5984 + int *src_err_ptr, int *dst_err_ptr);
5985 +
5986 /*
5987 * Note: when you get a NULL pointer exception here this means someone
5988 * passed in an incorrect kernel address to one of these functions.
5989 @@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
5990 int *err_ptr)
5991 {
5992 might_sleep();
5993 - return csum_partial_copy_generic((__force void *)src, dst,
5994 + return csum_partial_copy_generic_from_user((__force void *)src, dst,
5995 len, sum, err_ptr, NULL);
5996 }
5997
5998 @@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
5999 {
6000 might_sleep();
6001 if (access_ok(VERIFY_WRITE, dst, len))
6002 - return csum_partial_copy_generic(src, (__force void *)dst,
6003 + return csum_partial_copy_generic_to_user(src, (__force void *)dst,
6004 len, sum, NULL, err_ptr);
6005
6006 if (len)
6007 diff -urNp linux-2.6.31.1/arch/x86/include/asm/desc.h linux-2.6.31.1/arch/x86/include/asm/desc.h
6008 --- linux-2.6.31.1/arch/x86/include/asm/desc.h 2009-09-24 11:45:25.000000000 -0400
6009 +++ linux-2.6.31.1/arch/x86/include/asm/desc.h 2009-10-01 20:12:42.000000000 -0400
6010 @@ -15,6 +15,7 @@ static inline void fill_ldt(struct desc_
6011 desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
6012 desc->type = (info->read_exec_only ^ 1) << 1;
6013 desc->type |= info->contents << 2;
6014 + desc->type |= info->seg_not_present ^ 1;
6015 desc->s = 1;
6016 desc->dpl = 0x3;
6017 desc->p = info->seg_not_present ^ 1;
6018 @@ -31,16 +32,12 @@ static inline void fill_ldt(struct desc_
6019 }
6020
6021 extern struct desc_ptr idt_descr;
6022 -extern gate_desc idt_table[];
6023 -
6024 -struct gdt_page {
6025 - struct desc_struct gdt[GDT_ENTRIES];
6026 -} __attribute__((aligned(PAGE_SIZE)));
6027 -DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
6028 +extern gate_desc idt_table[256];
6029
6030 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
6031 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
6032 {
6033 - return per_cpu(gdt_page, cpu).gdt;
6034 + return cpu_gdt_table[cpu];
6035 }
6036
6037 #ifdef CONFIG_X86_64
6038 @@ -115,19 +112,48 @@ static inline void paravirt_free_ldt(str
6039 static inline void native_write_idt_entry(gate_desc *idt, int entry,
6040 const gate_desc *gate)
6041 {
6042 +
6043 +#ifdef CONFIG_PAX_KERNEXEC
6044 + unsigned long cr0;
6045 +
6046 + pax_open_kernel(cr0);
6047 +#endif
6048 +
6049 memcpy(&idt[entry], gate, sizeof(*gate));
6050 +
6051 +#ifdef CONFIG_PAX_KERNEXEC
6052 + pax_close_kernel(cr0);
6053 +#endif
6054 +
6055 }
6056
6057 static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
6058 const void *desc)
6059 {
6060 +
6061 +#ifdef CONFIG_PAX_KERNEXEC
6062 + unsigned long cr0;
6063 +
6064 + pax_open_kernel(cr0);
6065 +#endif
6066 +
6067 memcpy(&ldt[entry], desc, 8);
6068 +
6069 +#ifdef CONFIG_PAX_KERNEXEC
6070 + pax_close_kernel(cr0);
6071 +#endif
6072 +
6073 }
6074
6075 static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
6076 const void *desc, int type)
6077 {
6078 unsigned int size;
6079 +
6080 +#ifdef CONFIG_PAX_KERNEXEC
6081 + unsigned long cr0;
6082 +#endif
6083 +
6084 switch (type) {
6085 case DESC_TSS:
6086 size = sizeof(tss_desc);
6087 @@ -139,7 +165,17 @@ static inline void native_write_gdt_entr
6088 size = sizeof(struct desc_struct);
6089 break;
6090 }
6091 +
6092 +#ifdef CONFIG_PAX_KERNEXEC
6093 + pax_open_kernel(cr0);
6094 +#endif
6095 +
6096 memcpy(&gdt[entry], desc, size);
6097 +
6098 +#ifdef CONFIG_PAX_KERNEXEC
6099 + pax_close_kernel(cr0);
6100 +#endif
6101 +
6102 }
6103
6104 static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
6105 @@ -211,7 +247,19 @@ static inline void native_set_ldt(const
6106
6107 static inline void native_load_tr_desc(void)
6108 {
6109 +
6110 +#ifdef CONFIG_PAX_KERNEXEC
6111 + unsigned long cr0;
6112 +
6113 + pax_open_kernel(cr0);
6114 +#endif
6115 +
6116 asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
6117 +
6118 +#ifdef CONFIG_PAX_KERNEXEC
6119 + pax_close_kernel(cr0);
6120 +#endif
6121 +
6122 }
6123
6124 static inline void native_load_gdt(const struct desc_ptr *dtr)
6125 @@ -246,8 +294,19 @@ static inline void native_load_tls(struc
6126 unsigned int i;
6127 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
6128
6129 +#ifdef CONFIG_PAX_KERNEXEC
6130 + unsigned long cr0;
6131 +
6132 + pax_open_kernel(cr0);
6133 +#endif
6134 +
6135 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
6136 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
6137 +
6138 +#ifdef CONFIG_PAX_KERNEXEC
6139 + pax_close_kernel(cr0);
6140 +#endif
6141 +
6142 }
6143
6144 #define _LDT_empty(info) \
6145 @@ -379,4 +438,16 @@ static inline void set_system_intr_gate_
6146 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
6147 }
6148
6149 +#ifdef CONFIG_X86_32
6150 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
6151 +{
6152 + struct desc_struct d;
6153 +
6154 + if (likely(limit))
6155 + limit = (limit - 1UL) >> PAGE_SHIFT;
6156 + pack_descriptor(&d, base, limit, 0xFB, 0xC);
6157 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
6158 +}
6159 +#endif
6160 +
6161 #endif /* _ASM_X86_DESC_H */
6162 diff -urNp linux-2.6.31.1/arch/x86/include/asm/e820.h linux-2.6.31.1/arch/x86/include/asm/e820.h
6163 --- linux-2.6.31.1/arch/x86/include/asm/e820.h 2009-09-24 11:45:25.000000000 -0400
6164 +++ linux-2.6.31.1/arch/x86/include/asm/e820.h 2009-10-01 20:12:42.000000000 -0400
6165 @@ -135,7 +135,7 @@ extern char *memory_setup(void);
6166 #define ISA_END_ADDRESS 0x100000
6167 #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
6168
6169 -#define BIOS_BEGIN 0x000a0000
6170 +#define BIOS_BEGIN 0x000c0000
6171 #define BIOS_END 0x00100000
6172
6173 #ifdef __KERNEL__
6174 diff -urNp linux-2.6.31.1/arch/x86/include/asm/elf.h linux-2.6.31.1/arch/x86/include/asm/elf.h
6175 --- linux-2.6.31.1/arch/x86/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400
6176 +++ linux-2.6.31.1/arch/x86/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400
6177 @@ -263,7 +263,25 @@ extern int force_personality32;
6178 the loader. We need to make sure that it is out of the way of the program
6179 that it will "exec", and that there is sufficient room for the brk. */
6180
6181 +#ifdef CONFIG_PAX_SEGMEXEC
6182 +#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
6183 +#else
6184 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
6185 +#endif
6186 +
6187 +#ifdef CONFIG_PAX_ASLR
6188 +#ifdef CONFIG_X86_32
6189 +#define PAX_ELF_ET_DYN_BASE 0x10000000UL
6190 +
6191 +#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
6192 +#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
6193 +#else
6194 +#define PAX_ELF_ET_DYN_BASE 0x400000UL
6195 +
6196 +#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
6197 +#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
6198 +#endif
6199 +#endif
6200
6201 /* This yields a mask that user programs can use to figure out what
6202 instruction set this CPU supports. This could be done in user space,
6203 @@ -315,8 +333,7 @@ do { \
6204 #define ARCH_DLINFO \
6205 do { \
6206 if (vdso_enabled) \
6207 - NEW_AUX_ENT(AT_SYSINFO_EHDR, \
6208 - (unsigned long)current->mm->context.vdso); \
6209 + NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
6210 } while (0)
6211
6212 #define AT_SYSINFO 32
6213 @@ -327,7 +344,7 @@ do { \
6214
6215 #endif /* !CONFIG_X86_32 */
6216
6217 -#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
6218 +#define VDSO_CURRENT_BASE (current->mm->context.vdso)
6219
6220 #define VDSO_ENTRY \
6221 ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
6222 @@ -341,7 +358,4 @@ extern int arch_setup_additional_pages(s
6223 extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
6224 #define compat_arch_setup_additional_pages syscall32_setup_pages
6225
6226 -extern unsigned long arch_randomize_brk(struct mm_struct *mm);
6227 -#define arch_randomize_brk arch_randomize_brk
6228 -
6229 #endif /* _ASM_X86_ELF_H */
6230 diff -urNp linux-2.6.31.1/arch/x86/include/asm/futex.h linux-2.6.31.1/arch/x86/include/asm/futex.h
6231 --- linux-2.6.31.1/arch/x86/include/asm/futex.h 2009-09-24 11:45:25.000000000 -0400
6232 +++ linux-2.6.31.1/arch/x86/include/asm/futex.h 2009-10-01 20:12:42.000000000 -0400
6233 @@ -11,6 +11,40 @@
6234 #include <asm/processor.h>
6235 #include <asm/system.h>
6236
6237 +#ifdef CONFIG_X86_32
6238 +#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
6239 + asm volatile( \
6240 + "movw\t%w6, %%ds\n" \
6241 + "1:\t" insn "\n" \
6242 + "2:\tpushl\t%%ss\n" \
6243 + "\tpopl\t%%ds\n" \
6244 + "\t.section .fixup,\"ax\"\n" \
6245 + "3:\tmov\t%3, %1\n" \
6246 + "\tjmp\t2b\n" \
6247 + "\t.previous\n" \
6248 + _ASM_EXTABLE(1b, 3b) \
6249 + : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
6250 + : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
6251 +
6252 +#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
6253 + asm volatile("movw\t%w7, %%es\n" \
6254 + "1:\tmovl\t%%es:%2, %0\n" \
6255 + "\tmovl\t%0, %3\n" \
6256 + "\t" insn "\n" \
6257 + "2:\t" LOCK_PREFIX "cmpxchgl %3, %%es:%2\n"\
6258 + "\tjnz\t1b\n" \
6259 + "3:\tpushl\t%%ss\n" \
6260 + "\tpopl\t%%es\n" \
6261 + "\t.section .fixup,\"ax\"\n" \
6262 + "4:\tmov\t%5, %1\n" \
6263 + "\tjmp\t3b\n" \
6264 + "\t.previous\n" \
6265 + _ASM_EXTABLE(1b, 4b) \
6266 + _ASM_EXTABLE(2b, 4b) \
6267 + : "=&a" (oldval), "=&r" (ret), \
6268 + "+m" (*uaddr), "=&r" (tem) \
6269 + : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
6270 +#else
6271 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
6272 asm volatile("1:\t" insn "\n" \
6273 "2:\t.section .fixup,\"ax\"\n" \
6274 @@ -36,8 +70,9 @@
6275 : "=&a" (oldval), "=&r" (ret), \
6276 "+m" (*uaddr), "=&r" (tem) \
6277 : "r" (oparg), "i" (-EFAULT), "1" (0))
6278 +#endif
6279
6280 -static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
6281 +static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
6282 {
6283 int op = (encoded_op >> 28) & 7;
6284 int cmp = (encoded_op >> 24) & 15;
6285 @@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
6286
6287 switch (op) {
6288 case FUTEX_OP_SET:
6289 +#ifdef CONFIG_X86_32
6290 + __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
6291 +#else
6292 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
6293 +#endif
6294 break;
6295 case FUTEX_OP_ADD:
6296 +#ifdef CONFIG_X86_32
6297 + __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret, oldval,
6298 + uaddr, oparg);
6299 +#else
6300 __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
6301 uaddr, oparg);
6302 +#endif
6303 break;
6304 case FUTEX_OP_OR:
6305 __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
6306 @@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
6307 return ret;
6308 }
6309
6310 -static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
6311 +static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
6312 int newval)
6313 {
6314
6315 @@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
6316 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
6317 return -EFAULT;
6318
6319 - asm volatile("1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
6320 + asm volatile(
6321 +#ifdef CONFIG_X86_32
6322 + "\tmovw %w5, %%ds\n"
6323 + "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
6324 + "2:\tpushl %%ss\n"
6325 + "\tpopl %%ds\n"
6326 + "\t.section .fixup, \"ax\"\n"
6327 +#else
6328 + "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
6329 "2:\t.section .fixup, \"ax\"\n"
6330 +#endif
6331 "3:\tmov %2, %0\n"
6332 "\tjmp 2b\n"
6333 "\t.previous\n"
6334 _ASM_EXTABLE(1b, 3b)
6335 : "=a" (oldval), "+m" (*uaddr)
6336 +#ifdef CONFIG_X86_32
6337 + : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
6338 +#else
6339 : "i" (-EFAULT), "r" (newval), "0" (oldval)
6340 +#endif
6341 : "memory"
6342 );
6343
6344 diff -urNp linux-2.6.31.1/arch/x86/include/asm/i387.h linux-2.6.31.1/arch/x86/include/asm/i387.h
6345 --- linux-2.6.31.1/arch/x86/include/asm/i387.h 2009-09-24 11:45:25.000000000 -0400
6346 +++ linux-2.6.31.1/arch/x86/include/asm/i387.h 2009-10-01 20:12:42.000000000 -0400
6347 @@ -194,13 +194,8 @@ static inline int fxrstor_checking(struc
6348 }
6349
6350 /* We need a safe address that is cheap to find and that is already
6351 - in L1 during context switch. The best choices are unfortunately
6352 - different for UP and SMP */
6353 -#ifdef CONFIG_SMP
6354 -#define safe_address (__per_cpu_offset[0])
6355 -#else
6356 -#define safe_address (kstat_cpu(0).cpustat.user)
6357 -#endif
6358 + in L1 during context switch. */
6359 +#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
6360
6361 /*
6362 * These must be called with preempt disabled
6363 diff -urNp linux-2.6.31.1/arch/x86/include/asm/io_64.h linux-2.6.31.1/arch/x86/include/asm/io_64.h
6364 --- linux-2.6.31.1/arch/x86/include/asm/io_64.h 2009-09-24 11:45:25.000000000 -0400
6365 +++ linux-2.6.31.1/arch/x86/include/asm/io_64.h 2009-10-01 20:12:42.000000000 -0400
6366 @@ -140,6 +140,17 @@ __OUTS(l)
6367
6368 #include <linux/vmalloc.h>
6369
6370 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
6371 +static inline int valid_phys_addr_range (unsigned long addr, size_t count)
6372 +{
6373 + return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
6374 +}
6375 +
6376 +static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
6377 +{
6378 + return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
6379 +}
6380 +
6381 #include <asm-generic/iomap.h>
6382
6383 void __memcpy_fromio(void *, unsigned long, unsigned);
6384 diff -urNp linux-2.6.31.1/arch/x86/include/asm/irqflags.h linux-2.6.31.1/arch/x86/include/asm/irqflags.h
6385 --- linux-2.6.31.1/arch/x86/include/asm/irqflags.h 2009-09-24 11:45:25.000000000 -0400
6386 +++ linux-2.6.31.1/arch/x86/include/asm/irqflags.h 2009-10-01 20:12:42.000000000 -0400
6387 @@ -147,6 +147,8 @@ static inline unsigned long __raw_local_
6388 #define INTERRUPT_RETURN iret
6389 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
6390 #define GET_CR0_INTO_EAX movl %cr0, %eax
6391 +#define GET_CR0_INTO_EDX movl %cr0, %edx
6392 +#define SET_CR0_FROM_EDX movl %edx, %cr0
6393 #endif
6394
6395
6396 diff -urNp linux-2.6.31.1/arch/x86/include/asm/kvm_host.h linux-2.6.31.1/arch/x86/include/asm/kvm_host.h
6397 --- linux-2.6.31.1/arch/x86/include/asm/kvm_host.h 2009-09-24 11:45:25.000000000 -0400
6398 +++ linux-2.6.31.1/arch/x86/include/asm/kvm_host.h 2009-10-01 20:12:42.000000000 -0400
6399 @@ -528,7 +528,7 @@ struct kvm_x86_ops {
6400 u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
6401 };
6402
6403 -extern struct kvm_x86_ops *kvm_x86_ops;
6404 +extern const struct kvm_x86_ops *kvm_x86_ops;
6405
6406 int kvm_mmu_module_init(void);
6407 void kvm_mmu_module_exit(void);
6408 diff -urNp linux-2.6.31.1/arch/x86/include/asm/local.h linux-2.6.31.1/arch/x86/include/asm/local.h
6409 --- linux-2.6.31.1/arch/x86/include/asm/local.h 2009-09-24 11:45:25.000000000 -0400
6410 +++ linux-2.6.31.1/arch/x86/include/asm/local.h 2009-10-01 20:12:42.000000000 -0400
6411 @@ -18,26 +18,90 @@ typedef struct {
6412
6413 static inline void local_inc(local_t *l)
6414 {
6415 - asm volatile(_ASM_INC "%0"
6416 + asm volatile(_ASM_INC "%0\n"
6417 +
6418 +#ifdef CONFIG_PAX_REFCOUNT
6419 +#ifdef CONFIG_X86_32
6420 + "into\n0:\n"
6421 +#else
6422 + "jno 0f\n"
6423 + "int $4\n0:\n"
6424 +#endif
6425 + ".pushsection .fixup,\"ax\"\n"
6426 + "1:\n"
6427 + _ASM_DEC "%0\n"
6428 + "jmp 0b\n"
6429 + ".popsection\n"
6430 + _ASM_EXTABLE(0b, 1b)
6431 +#endif
6432 +
6433 : "+m" (l->a.counter));
6434 }
6435
6436 static inline void local_dec(local_t *l)
6437 {
6438 - asm volatile(_ASM_DEC "%0"
6439 + asm volatile(_ASM_DEC "%0\n"
6440 +
6441 +#ifdef CONFIG_PAX_REFCOUNT
6442 +#ifdef CONFIG_X86_32
6443 + "into\n0:\n"
6444 +#else
6445 + "jno 0f\n"
6446 + "int $4\n0:\n"
6447 +#endif
6448 + ".pushsection .fixup,\"ax\"\n"
6449 + "1:\n"
6450 + _ASM_INC "%0\n"
6451 + "jmp 0b\n"
6452 + ".popsection\n"
6453 + _ASM_EXTABLE(0b, 1b)
6454 +#endif
6455 +
6456 : "+m" (l->a.counter));
6457 }
6458
6459 static inline void local_add(long i, local_t *l)
6460 {
6461 - asm volatile(_ASM_ADD "%1,%0"
6462 + asm volatile(_ASM_ADD "%1,%0\n"
6463 +
6464 +#ifdef CONFIG_PAX_REFCOUNT
6465 +#ifdef CONFIG_X86_32
6466 + "into\n0:\n"
6467 +#else
6468 + "jno 0f\n"
6469 + "int $4\n0:\n"
6470 +#endif
6471 + ".pushsection .fixup,\"ax\"\n"
6472 + "1:\n"
6473 + _ASM_SUB "%1,%0\n"
6474 + "jmp 0b\n"
6475 + ".popsection\n"
6476 + _ASM_EXTABLE(0b, 1b)
6477 +#endif
6478 +
6479 : "+m" (l->a.counter)
6480 : "ir" (i));
6481 }
6482
6483 static inline void local_sub(long i, local_t *l)
6484 {
6485 - asm volatile(_ASM_SUB "%1,%0"
6486 + asm volatile(_ASM_SUB "%1,%0\n"
6487 +
6488 +#ifdef CONFIG_PAX_REFCOUNT
6489 +#ifdef CONFIG_X86_32
6490 + "into\n0:\n"
6491 +#else
6492 + "jno 0f\n"
6493 + "int $4\n0:\n"
6494 +#endif
6495 + ".pushsection .fixup,\"ax\"\n"
6496 + "1:\n"
6497 + _ASM_ADD "%1,%0\n"
6498 + "jmp 0b\n"
6499 + ".popsection\n"
6500 + _ASM_EXTABLE(0b, 1b)
6501 +#endif
6502 +
6503 : "+m" (l->a.counter)
6504 : "ir" (i));
6505 }
6506 @@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
6507 {
6508 unsigned char c;
6509
6510 - asm volatile(_ASM_SUB "%2,%0; sete %1"
6511 + asm volatile(_ASM_SUB "%2,%0\n"
6512 +
6513 +#ifdef CONFIG_PAX_REFCOUNT
6514 +#ifdef CONFIG_X86_32
6515 + "into\n0:\n"
6516 +#else
6517 + "jno 0f\n"
6518 + "int $4\n0:\n"
6519 +#endif
6520 + ".pushsection .fixup,\"ax\"\n"
6521 + "1:\n"
6522 + _ASM_ADD "%2,%0\n"
6523 + "jmp 0b\n"
6524 + ".popsection\n"
6525 + _ASM_EXTABLE(0b, 1b)
6526 +#endif
6527 +
6528 + "sete %1\n"
6529 : "+m" (l->a.counter), "=qm" (c)
6530 : "ir" (i) : "memory");
6531 return c;
6532 @@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
6533 {
6534 unsigned char c;
6535
6536 - asm volatile(_ASM_DEC "%0; sete %1"
6537 + asm volatile(_ASM_DEC "%0\n"
6538 +
6539 +#ifdef CONFIG_PAX_REFCOUNT
6540 +#ifdef CONFIG_X86_32
6541 + "into\n0:\n"
6542 +#else
6543 + "jno 0f\n"
6544 + "int $4\n0:\n"
6545 +#endif
6546 + ".pushsection .fixup,\"ax\"\n"
6547 + "1:\n"
6548 + _ASM_INC "%0\n"
6549 + "jmp 0b\n"
6550 + ".popsection\n"
6551 + _ASM_EXTABLE(0b, 1b)
6552 +#endif
6553 +
6554 + "sete %1\n"
6555 : "+m" (l->a.counter), "=qm" (c)
6556 : : "memory");
6557 return c != 0;
6558 @@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
6559 {
6560 unsigned char c;
6561
6562 - asm volatile(_ASM_INC "%0; sete %1"
6563 + asm volatile(_ASM_INC "%0\n"
6564 +
6565 +#ifdef CONFIG_PAX_REFCOUNT
6566 +#ifdef CONFIG_X86_32
6567 + "into\n0:\n"
6568 +#else
6569 + "jno 0f\n"
6570 + "int $4\n0:\n"
6571 +#endif
6572 + ".pushsection .fixup,\"ax\"\n"
6573 + "1:\n"
6574 + _ASM_DEC "%0\n"
6575 + "jmp 0b\n"
6576 + ".popsection\n"
6577 + _ASM_EXTABLE(0b, 1b)
6578 +#endif
6579 +
6580 + "sete %1\n"
6581 : "+m" (l->a.counter), "=qm" (c)
6582 : : "memory");
6583 return c != 0;
6584 @@ -110,7 +225,24 @@ static inline int local_add_negative(lon
6585 {
6586 unsigned char c;
6587
6588 - asm volatile(_ASM_ADD "%2,%0; sets %1"
6589 + asm volatile(_ASM_ADD "%2,%0\n"
6590 +
6591 +#ifdef CONFIG_PAX_REFCOUNT
6592 +#ifdef CONFIG_X86_32
6593 + "into\n0:\n"
6594 +#else
6595 + "jno 0f\n"
6596 + "int $4\n0:\n"
6597 +#endif
6598 + ".pushsection .fixup,\"ax\"\n"
6599 + "1:\n"
6600 + _ASM_SUB "%2,%0\n"
6601 + "jmp 0b\n"
6602 + ".popsection\n"
6603 + _ASM_EXTABLE(0b, 1b)
6604 +#endif
6605 +
6606 + "sets %1\n"
6607 : "+m" (l->a.counter), "=qm" (c)
6608 : "ir" (i) : "memory");
6609 return c;
6610 @@ -133,7 +265,23 @@ static inline long local_add_return(long
6611 #endif
6612 /* Modern 486+ processor */
6613 __i = i;
6614 - asm volatile(_ASM_XADD "%0, %1;"
6615 + asm volatile(_ASM_XADD "%0, %1\n"
6616 +
6617 +#ifdef CONFIG_PAX_REFCOUNT
6618 +#ifdef CONFIG_X86_32
6619 + "into\n0:\n"
6620 +#else
6621 + "jno 0f\n"
6622 + "int $4\n0:\n"
6623 +#endif
6624 + ".pushsection .fixup,\"ax\"\n"
6625 + "1:\n"
6626 + _ASM_MOV "%0,%1\n"
6627 + "jmp 0b\n"
6628 + ".popsection\n"
6629 + _ASM_EXTABLE(0b, 1b)
6630 +#endif
6631 +
6632 : "+r" (i), "+m" (l->a.counter)
6633 : : "memory");
6634 return i + __i;
6635 diff -urNp linux-2.6.31.1/arch/x86/include/asm/mman.h linux-2.6.31.1/arch/x86/include/asm/mman.h
6636 --- linux-2.6.31.1/arch/x86/include/asm/mman.h 2009-09-24 11:45:25.000000000 -0400
6637 +++ linux-2.6.31.1/arch/x86/include/asm/mman.h 2009-10-01 20:12:42.000000000 -0400
6638 @@ -17,4 +17,14 @@
6639 #define MCL_CURRENT 1 /* lock all current mappings */
6640 #define MCL_FUTURE 2 /* lock all future mappings */
6641
6642 +#ifdef __KERNEL__
6643 +#ifndef __ASSEMBLY__
6644 +#ifdef CONFIG_X86_32
6645 +#define arch_mmap_check i386_mmap_check
6646 +int i386_mmap_check(unsigned long addr, unsigned long len,
6647 + unsigned long flags);
6648 +#endif
6649 +#endif
6650 +#endif
6651 +
6652 #endif /* _ASM_X86_MMAN_H */
6653 diff -urNp linux-2.6.31.1/arch/x86/include/asm/mmu_context.h linux-2.6.31.1/arch/x86/include/asm/mmu_context.h
6654 --- linux-2.6.31.1/arch/x86/include/asm/mmu_context.h 2009-09-24 11:45:25.000000000 -0400
6655 +++ linux-2.6.31.1/arch/x86/include/asm/mmu_context.h 2009-10-01 20:12:42.000000000 -0400
6656 @@ -34,11 +34,17 @@ static inline void switch_mm(struct mm_s
6657 struct task_struct *tsk)
6658 {
6659 unsigned cpu = smp_processor_id();
6660 +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
6661 + int tlbstate = TLBSTATE_OK;
6662 +#endif
6663
6664 if (likely(prev != next)) {
6665 /* stop flush ipis for the previous mm */
6666 cpu_clear(cpu, prev->cpu_vm_mask);
6667 #ifdef CONFIG_SMP
6668 +#ifdef CONFIG_X86_32
6669 + tlbstate = percpu_read(cpu_tlbstate.state);
6670 +#endif
6671 percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
6672 percpu_write(cpu_tlbstate.active_mm, next);
6673 #endif
6674 @@ -52,6 +58,26 @@ static inline void switch_mm(struct mm_s
6675 */
6676 if (unlikely(prev->context.ldt != next->context.ldt))
6677 load_LDT_nolock(&next->context);
6678 +
6679 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
6680 + if (!nx_enabled) {
6681 + smp_mb__before_clear_bit();
6682 + cpu_clear(cpu, prev->context.cpu_user_cs_mask);
6683 + smp_mb__after_clear_bit();
6684 + cpu_set(cpu, next->context.cpu_user_cs_mask);
6685 + }
6686 +#endif
6687 +
6688 +#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC))
6689 + if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
6690 + prev->context.user_cs_limit != next->context.user_cs_limit
6691 +#ifdef CONFIG_SMP
6692 + || tlbstate != TLBSTATE_OK
6693 +#endif
6694 + ))
6695 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
6696 +#endif
6697 +
6698 }
6699 #ifdef CONFIG_SMP
6700 else {
6701 @@ -65,6 +91,19 @@ static inline void switch_mm(struct mm_s
6702 */
6703 load_cr3(next->pgd);
6704 load_LDT_nolock(&next->context);
6705 +
6706 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
6707 + if (!nx_enabled)
6708 + cpu_set(cpu, next->context.cpu_user_cs_mask);
6709 +#endif
6710 +
6711 +#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC))
6712 +#ifdef CONFIG_PAX_PAGEEXEC
6713 + if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
6714 +#endif
6715 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
6716 +#endif
6717 +
6718 }
6719 }
6720 #endif
6721 diff -urNp linux-2.6.31.1/arch/x86/include/asm/mmu.h linux-2.6.31.1/arch/x86/include/asm/mmu.h
6722 --- linux-2.6.31.1/arch/x86/include/asm/mmu.h 2009-09-24 11:45:25.000000000 -0400
6723 +++ linux-2.6.31.1/arch/x86/include/asm/mmu.h 2009-10-01 20:12:42.000000000 -0400
6724 @@ -9,10 +9,23 @@
6725 * we put the segment information here.
6726 */
6727 typedef struct {
6728 - void *ldt;
6729 + struct desc_struct *ldt;
6730 int size;
6731 struct mutex lock;
6732 - void *vdso;
6733 + unsigned long vdso;
6734 +
6735 +#ifdef CONFIG_X86_32
6736 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6737 + unsigned long user_cs_base;
6738 + unsigned long user_cs_limit;
6739 +
6740 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
6741 + cpumask_t cpu_user_cs_mask;
6742 +#endif
6743 +
6744 +#endif
6745 +#endif
6746 +
6747 } mm_context_t;
6748
6749 #ifdef CONFIG_SMP
6750 diff -urNp linux-2.6.31.1/arch/x86/include/asm/module.h linux-2.6.31.1/arch/x86/include/asm/module.h
6751 --- linux-2.6.31.1/arch/x86/include/asm/module.h 2009-09-24 11:45:25.000000000 -0400
6752 +++ linux-2.6.31.1/arch/x86/include/asm/module.h 2009-10-01 20:12:42.000000000 -0400
6753 @@ -74,7 +74,12 @@ struct mod_arch_specific {};
6754 # else
6755 # define MODULE_STACKSIZE ""
6756 # endif
6757 -# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
6758 +# ifdef CONFIG_GRKERNSEC
6759 +# define MODULE_GRSEC "GRSECURITY "
6760 +# else
6761 +# define MODULE_GRSEC ""
6762 +# endif
6763 +# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
6764 #endif
6765
6766 #endif /* _ASM_X86_MODULE_H */
6767 diff -urNp linux-2.6.31.1/arch/x86/include/asm/page_32_types.h linux-2.6.31.1/arch/x86/include/asm/page_32_types.h
6768 --- linux-2.6.31.1/arch/x86/include/asm/page_32_types.h 2009-09-24 11:45:25.000000000 -0400
6769 +++ linux-2.6.31.1/arch/x86/include/asm/page_32_types.h 2009-10-01 20:12:42.000000000 -0400
6770 @@ -15,6 +15,10 @@
6771 */
6772 #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
6773
6774 +#ifdef CONFIG_PAX_PAGEEXEC
6775 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
6776 +#endif
6777 +
6778 #ifdef CONFIG_4KSTACKS
6779 #define THREAD_ORDER 0
6780 #else
6781 diff -urNp linux-2.6.31.1/arch/x86/include/asm/page_64_types.h linux-2.6.31.1/arch/x86/include/asm/page_64_types.h
6782 --- linux-2.6.31.1/arch/x86/include/asm/page_64_types.h 2009-09-24 11:45:25.000000000 -0400
6783 +++ linux-2.6.31.1/arch/x86/include/asm/page_64_types.h 2009-10-01 20:12:42.000000000 -0400
6784 @@ -39,6 +39,9 @@
6785 #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
6786 #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
6787
6788 +#define ktla_ktva(addr) (addr)
6789 +#define ktva_ktla(addr) (addr)
6790 +
6791 /* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */
6792 #define __PHYSICAL_MASK_SHIFT 46
6793 #define __VIRTUAL_MASK_SHIFT 47
6794 diff -urNp linux-2.6.31.1/arch/x86/include/asm/paravirt.h linux-2.6.31.1/arch/x86/include/asm/paravirt.h
6795 --- linux-2.6.31.1/arch/x86/include/asm/paravirt.h 2009-09-24 11:45:25.000000000 -0400
6796 +++ linux-2.6.31.1/arch/x86/include/asm/paravirt.h 2009-10-01 20:12:42.000000000 -0400
6797 @@ -1688,7 +1688,7 @@ static inline unsigned long __raw_local_
6798
6799 #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
6800 #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
6801 -#define PARA_INDIRECT(addr) *%cs:addr
6802 +#define PARA_INDIRECT(addr) *%ss:addr
6803 #endif
6804
6805 #define INTERRUPT_RETURN \
6806 @@ -1718,6 +1718,18 @@ static inline unsigned long __raw_local_
6807 call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \
6808 pop %edx; pop %ecx
6809
6810 +#define GET_CR0_INTO_EDX \
6811 + push %eax; push %ecx; \
6812 + call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \
6813 + mov %eax, %edx; \
6814 + pop %ecx; pop %eax
6815 +
6816 +#define SET_CR0_FROM_EDX \
6817 + push %eax; push %ecx; \
6818 + mov %edx, %eax; \
6819 + call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0);\
6820 + pop %ecx; pop %eax
6821 +
6822 #define ENABLE_INTERRUPTS_SYSEXIT \
6823 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \
6824 CLBR_NONE, \
6825 diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgalloc.h linux-2.6.31.1/arch/x86/include/asm/pgalloc.h
6826 --- linux-2.6.31.1/arch/x86/include/asm/pgalloc.h 2009-09-24 11:45:25.000000000 -0400
6827 +++ linux-2.6.31.1/arch/x86/include/asm/pgalloc.h 2009-10-01 20:12:42.000000000 -0400
6828 @@ -58,6 +58,13 @@ static inline void pmd_populate_kernel(s
6829 pmd_t *pmd, pte_t *pte)
6830 {
6831 paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
6832 + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
6833 +}
6834 +
6835 +static inline void pmd_populate_user(struct mm_struct *mm,
6836 + pmd_t *pmd, pte_t *pte)
6837 +{
6838 + paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
6839 set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
6840 }
6841
6842 diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable-2level.h linux-2.6.31.1/arch/x86/include/asm/pgtable-2level.h
6843 --- linux-2.6.31.1/arch/x86/include/asm/pgtable-2level.h 2009-09-24 11:45:25.000000000 -0400
6844 +++ linux-2.6.31.1/arch/x86/include/asm/pgtable-2level.h 2009-10-01 20:12:42.000000000 -0400
6845 @@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
6846
6847 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
6848 {
6849 +
6850 +#ifdef CONFIG_PAX_KERNEXEC
6851 + unsigned long cr0;
6852 +
6853 + pax_open_kernel(cr0);
6854 +#endif
6855 +
6856 *pmdp = pmd;
6857 +
6858 +#ifdef CONFIG_PAX_KERNEXEC
6859 + pax_close_kernel(cr0);
6860 +#endif
6861 +
6862 }
6863
6864 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
6865 diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable_32.h linux-2.6.31.1/arch/x86/include/asm/pgtable_32.h
6866 --- linux-2.6.31.1/arch/x86/include/asm/pgtable_32.h 2009-09-24 11:45:25.000000000 -0400
6867 +++ linux-2.6.31.1/arch/x86/include/asm/pgtable_32.h 2009-10-01 20:12:42.000000000 -0400
6868 @@ -26,8 +26,6 @@
6869 struct mm_struct;
6870 struct vm_area_struct;
6871
6872 -extern pgd_t swapper_pg_dir[1024];
6873 -
6874 static inline void pgtable_cache_init(void) { }
6875 static inline void check_pgt_cache(void) { }
6876 void paging_init(void);
6877 @@ -48,6 +46,11 @@ extern void set_pmd_pfn(unsigned long, u
6878 # include <asm/pgtable-2level.h>
6879 #endif
6880
6881 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
6882 +#ifdef CONFIG_X86_PAE
6883 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
6884 +#endif
6885 +
6886 #if defined(CONFIG_HIGHPTE)
6887 #define __KM_PTE \
6888 (in_nmi() ? KM_NMI_PTE : \
6889 @@ -84,6 +87,9 @@ do { \
6890
6891 #endif /* !__ASSEMBLY__ */
6892
6893 +#define HAVE_ARCH_UNMAPPED_AREA
6894 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
6895 +
6896 /*
6897 * kern_addr_valid() is (1) for FLATMEM and (0) for
6898 * SPARSEMEM and DISCONTIGMEM
6899 diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable_32_types.h linux-2.6.31.1/arch/x86/include/asm/pgtable_32_types.h
6900 --- linux-2.6.31.1/arch/x86/include/asm/pgtable_32_types.h 2009-09-24 11:45:25.000000000 -0400
6901 +++ linux-2.6.31.1/arch/x86/include/asm/pgtable_32_types.h 2009-10-01 20:12:42.000000000 -0400
6902 @@ -8,7 +8,7 @@
6903 */
6904 #ifdef CONFIG_X86_PAE
6905 # include <asm/pgtable-3level_types.h>
6906 -# define PMD_SIZE (1UL << PMD_SHIFT)
6907 +# define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
6908 # define PMD_MASK (~(PMD_SIZE - 1))
6909 #else
6910 # include <asm/pgtable-2level_types.h>
6911 @@ -46,6 +46,19 @@ extern bool __vmalloc_start_set; /* set
6912 # define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE)
6913 #endif
6914
6915 +#ifdef CONFIG_PAX_KERNEXEC
6916 +#ifndef __ASSEMBLY__
6917 +extern unsigned char MODULES_EXEC_VADDR[];
6918 +extern unsigned char MODULES_EXEC_END[];
6919 +#endif
6920 +#include <asm/boot.h>
6921 +#define ktla_ktva(addr) (addr + LOAD_PHYSICAL_ADDR + PAGE_OFFSET)
6922 +#define ktva_ktla(addr) (addr - LOAD_PHYSICAL_ADDR - PAGE_OFFSET)
6923 +#else
6924 +#define ktla_ktva(addr) (addr)
6925 +#define ktva_ktla(addr) (addr)
6926 +#endif
6927 +
6928 #define MODULES_VADDR VMALLOC_START
6929 #define MODULES_END VMALLOC_END
6930 #define MODULES_LEN (MODULES_VADDR - MODULES_END)
6931 diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable-3level.h linux-2.6.31.1/arch/x86/include/asm/pgtable-3level.h
6932 --- linux-2.6.31.1/arch/x86/include/asm/pgtable-3level.h 2009-09-24 11:45:25.000000000 -0400
6933 +++ linux-2.6.31.1/arch/x86/include/asm/pgtable-3level.h 2009-10-01 20:12:42.000000000 -0400
6934 @@ -38,12 +38,36 @@ static inline void native_set_pte_atomic
6935
6936 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
6937 {
6938 +
6939 +#ifdef CONFIG_PAX_KERNEXEC
6940 + unsigned long cr0;
6941 +
6942 + pax_open_kernel(cr0);
6943 +#endif
6944 +
6945 set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
6946 +
6947 +#ifdef CONFIG_PAX_KERNEXEC
6948 + pax_close_kernel(cr0);
6949 +#endif
6950 +
6951 }
6952
6953 static inline void native_set_pud(pud_t *pudp, pud_t pud)
6954 {
6955 +
6956 +#ifdef CONFIG_PAX_KERNEXEC
6957 + unsigned long cr0;
6958 +
6959 + pax_open_kernel(cr0);
6960 +#endif
6961 +
6962 set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
6963 +
6964 +#ifdef CONFIG_PAX_KERNEXEC
6965 + pax_close_kernel(cr0);
6966 +#endif
6967 +
6968 }
6969
6970 /*
6971 diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable_64.h linux-2.6.31.1/arch/x86/include/asm/pgtable_64.h
6972 --- linux-2.6.31.1/arch/x86/include/asm/pgtable_64.h 2009-09-24 11:45:25.000000000 -0400
6973 +++ linux-2.6.31.1/arch/x86/include/asm/pgtable_64.h 2009-10-01 20:12:42.000000000 -0400
6974 @@ -16,9 +16,12 @@
6975
6976 extern pud_t level3_kernel_pgt[512];
6977 extern pud_t level3_ident_pgt[512];
6978 +extern pud_t level3_vmalloc_pgt[512];
6979 +extern pud_t level3_vmemmap_pgt[512];
6980 +extern pud_t level2_vmemmap_pgt[512];
6981 extern pmd_t level2_kernel_pgt[512];
6982 extern pmd_t level2_fixmap_pgt[512];
6983 -extern pmd_t level2_ident_pgt[512];
6984 +extern pmd_t level2_ident_pgt[512*4];
6985 extern pgd_t init_level4_pgt[];
6986
6987 #define swapper_pg_dir init_level4_pgt
6988 @@ -74,7 +77,19 @@ static inline pte_t native_ptep_get_and_
6989
6990 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
6991 {
6992 +
6993 +#ifdef CONFIG_PAX_KERNEXEC
6994 + unsigned long cr0;
6995 +
6996 + pax_open_kernel(cr0);
6997 +#endif
6998 +
6999 *pmdp = pmd;
7000 +
7001 +#ifdef CONFIG_PAX_KERNEXEC
7002 + pax_close_kernel(cr0);
7003 +#endif
7004 +
7005 }
7006
7007 static inline void native_pmd_clear(pmd_t *pmd)
7008 diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable.h linux-2.6.31.1/arch/x86/include/asm/pgtable.h
7009 --- linux-2.6.31.1/arch/x86/include/asm/pgtable.h 2009-09-24 11:45:25.000000000 -0400
7010 +++ linux-2.6.31.1/arch/x86/include/asm/pgtable.h 2009-10-01 20:12:42.000000000 -0400
7011 @@ -90,6 +90,11 @@ static inline void __init paravirt_paget
7012 * The following only work if pte_present() is true.
7013 * Undefined behaviour if not..
7014 */
7015 +static inline int pte_user(pte_t pte)
7016 +{
7017 + return pte_val(pte) & _PAGE_USER;
7018 +}
7019 +
7020 static inline int pte_dirty(pte_t pte)
7021 {
7022 return pte_flags(pte) & _PAGE_DIRTY;
7023 @@ -172,9 +177,29 @@ static inline pte_t pte_wrprotect(pte_t
7024 return pte_clear_flags(pte, _PAGE_RW);
7025 }
7026
7027 +static inline pte_t pte_mkread(pte_t pte)
7028 +{
7029 + return __pte(pte_val(pte) | _PAGE_USER);
7030 +}
7031 +
7032 static inline pte_t pte_mkexec(pte_t pte)
7033 {
7034 - return pte_clear_flags(pte, _PAGE_NX);
7035 +#ifdef CONFIG_X86_PAE
7036 + if (__supported_pte_mask & _PAGE_NX)
7037 + return pte_clear_flags(pte, _PAGE_NX);
7038 + else
7039 +#endif
7040 + return pte_set_flags(pte, _PAGE_USER);
7041 +}
7042 +
7043 +static inline pte_t pte_exprotect(pte_t pte)
7044 +{
7045 +#ifdef CONFIG_X86_PAE
7046 + if (__supported_pte_mask & _PAGE_NX)
7047 + return pte_set_flags(pte, _PAGE_NX);
7048 + else
7049 +#endif
7050 + return pte_clear_flags(pte, _PAGE_USER);
7051 }
7052
7053 static inline pte_t pte_mkdirty(pte_t pte)
7054 @@ -482,7 +507,7 @@ static inline pud_t *pud_offset(pgd_t *p
7055
7056 static inline int pgd_bad(pgd_t pgd)
7057 {
7058 - return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
7059 + return (pgd_flags(pgd) & ~(_PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
7060 }
7061
7062 static inline int pgd_none(pgd_t pgd)
7063 @@ -623,7 +648,19 @@ static inline void ptep_set_wrprotect(st
7064 */
7065 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
7066 {
7067 - memcpy(dst, src, count * sizeof(pgd_t));
7068 +
7069 +#ifdef CONFIG_PAX_KERNEXEC
7070 + unsigned long cr0;
7071 +
7072 + pax_open_kernel(cr0);
7073 +#endif
7074 +
7075 + memcpy(dst, src, count * sizeof(pgd_t));
7076 +
7077 +#ifdef CONFIG_PAX_KERNEXEC
7078 + pax_close_kernel(cr0);
7079 +#endif
7080 +
7081 }
7082
7083
7084 diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable_types.h linux-2.6.31.1/arch/x86/include/asm/pgtable_types.h
7085 --- linux-2.6.31.1/arch/x86/include/asm/pgtable_types.h 2009-09-24 11:45:25.000000000 -0400
7086 +++ linux-2.6.31.1/arch/x86/include/asm/pgtable_types.h 2009-10-01 20:12:42.000000000 -0400
7087 @@ -16,12 +16,11 @@
7088 #define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
7089 #define _PAGE_BIT_PAT 7 /* on 4KB pages */
7090 #define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
7091 -#define _PAGE_BIT_UNUSED1 9 /* available for programmer */
7092 +#define _PAGE_BIT_SPECIAL 9 /* special mappings, no associated struct page */
7093 #define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */
7094 #define _PAGE_BIT_HIDDEN 11 /* hidden by kmemcheck */
7095 #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
7096 -#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1
7097 -#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1
7098 +#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SPECIAL
7099 #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
7100
7101 /* If _PAGE_BIT_PRESENT is clear, we use these: */
7102 @@ -39,7 +38,6 @@
7103 #define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
7104 #define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
7105 #define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
7106 -#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
7107 #define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
7108 #define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
7109 #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
7110 @@ -55,8 +53,10 @@
7111
7112 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
7113 #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
7114 -#else
7115 +#elif defined(CONFIG_KMEMCHECK)
7116 #define _PAGE_NX (_AT(pteval_t, 0))
7117 +#else
7118 +#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN)
7119 #endif
7120
7121 #define _PAGE_FILE (_AT(pteval_t, 1) << _PAGE_BIT_FILE)
7122 @@ -93,6 +93,9 @@
7123 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
7124 _PAGE_ACCESSED)
7125
7126 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
7127 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
7128 +
7129 #define __PAGE_KERNEL_EXEC \
7130 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
7131 #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
7132 @@ -103,8 +106,8 @@
7133 #define __PAGE_KERNEL_WC (__PAGE_KERNEL | _PAGE_CACHE_WC)
7134 #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
7135 #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
7136 -#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
7137 -#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
7138 +#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RO | _PAGE_USER)
7139 +#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
7140 #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
7141 #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
7142 #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
7143 @@ -163,8 +166,8 @@
7144 * bits are combined, this will alow user to access the high address mapped
7145 * VDSO in the presence of CONFIG_COMPAT_VDSO
7146 */
7147 -#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
7148 -#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
7149 +#define PTE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
7150 +#define PDE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
7151 #define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
7152 #endif
7153
7154 @@ -277,7 +280,15 @@ static inline pteval_t pte_flags(pte_t p
7155 typedef struct page *pgtable_t;
7156
7157 extern pteval_t __supported_pte_mask;
7158 +#ifdef CONFIG_X86_32
7159 +#ifdef CONFIG_X86_PAE
7160 extern int nx_enabled;
7161 +#else
7162 +#define nx_enabled (0)
7163 +#endif
7164 +#else
7165 +#define nx_enabled (1)
7166 +#endif
7167
7168 #define pgprot_writecombine pgprot_writecombine
7169 extern pgprot_t pgprot_writecombine(pgprot_t prot);
7170 diff -urNp linux-2.6.31.1/arch/x86/include/asm/processor.h linux-2.6.31.1/arch/x86/include/asm/processor.h
7171 --- linux-2.6.31.1/arch/x86/include/asm/processor.h 2009-09-24 11:45:25.000000000 -0400
7172 +++ linux-2.6.31.1/arch/x86/include/asm/processor.h 2009-10-01 20:12:42.000000000 -0400
7173 @@ -271,7 +271,7 @@ struct tss_struct {
7174
7175 } ____cacheline_aligned;
7176
7177 -DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss);
7178 +extern struct tss_struct init_tss[NR_CPUS];
7179
7180 /*
7181 * Save the original ist values for checking stack pointers during debugging
7182 @@ -900,8 +900,17 @@ static inline void spin_lock_prefetch(co
7183 */
7184 #define TASK_SIZE PAGE_OFFSET
7185 #define TASK_SIZE_MAX TASK_SIZE
7186 +
7187 +#ifdef CONFIG_PAX_SEGMEXEC
7188 +#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
7189 +#endif
7190 +
7191 +#ifdef CONFIG_PAX_SEGMEXEC
7192 +#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
7193 +#else
7194 #define STACK_TOP TASK_SIZE
7195 -#define STACK_TOP_MAX STACK_TOP
7196 +#endif
7197 +#define STACK_TOP_MAX TASK_SIZE
7198
7199 #define INIT_THREAD { \
7200 .sp0 = sizeof(init_stack) + (long)&init_stack, \
7201 @@ -918,7 +927,7 @@ static inline void spin_lock_prefetch(co
7202 */
7203 #define INIT_TSS { \
7204 .x86_tss = { \
7205 - .sp0 = sizeof(init_stack) + (long)&init_stack, \
7206 + .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
7207 .ss0 = __KERNEL_DS, \
7208 .ss1 = __KERNEL_CS, \
7209 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
7210 @@ -929,11 +938,7 @@ static inline void spin_lock_prefetch(co
7211 extern unsigned long thread_saved_pc(struct task_struct *tsk);
7212
7213 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
7214 -#define KSTK_TOP(info) \
7215 -({ \
7216 - unsigned long *__ptr = (unsigned long *)(info); \
7217 - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
7218 -})
7219 +#define KSTK_TOP(info) ((info)->task.thread.sp0)
7220
7221 /*
7222 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
7223 @@ -948,7 +953,7 @@ extern unsigned long thread_saved_pc(str
7224 #define task_pt_regs(task) \
7225 ({ \
7226 struct pt_regs *__regs__; \
7227 - __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
7228 + __regs__ = (struct pt_regs *)((task)->thread.sp0); \
7229 __regs__ - 1; \
7230 })
7231
7232 @@ -964,7 +969,7 @@ extern unsigned long thread_saved_pc(str
7233 * space during mmap's.
7234 */
7235 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
7236 - 0xc0000000 : 0xFFFFe000)
7237 + 0xc0000000 : 0xFFFFf000)
7238
7239 #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
7240 IA32_PAGE_OFFSET : TASK_SIZE_MAX)
7241 @@ -1001,6 +1006,10 @@ extern void start_thread(struct pt_regs
7242 */
7243 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
7244
7245 +#ifdef CONFIG_PAX_SEGMEXEC
7246 +#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
7247 +#endif
7248 +
7249 #define KSTK_EIP(task) (task_pt_regs(task)->ip)
7250
7251 /* Get/set a process' ability to use the timestamp counter instruction */
7252 diff -urNp linux-2.6.31.1/arch/x86/include/asm/ptrace.h linux-2.6.31.1/arch/x86/include/asm/ptrace.h
7253 --- linux-2.6.31.1/arch/x86/include/asm/ptrace.h 2009-09-24 11:45:25.000000000 -0400
7254 +++ linux-2.6.31.1/arch/x86/include/asm/ptrace.h 2009-10-01 20:12:42.000000000 -0400
7255 @@ -151,28 +151,29 @@ static inline unsigned long regs_return_
7256 }
7257
7258 /*
7259 - * user_mode_vm(regs) determines whether a register set came from user mode.
7260 + * user_mode(regs) determines whether a register set came from user mode.
7261 * This is true if V8086 mode was enabled OR if the register set was from
7262 * protected mode with RPL-3 CS value. This tricky test checks that with
7263 * one comparison. Many places in the kernel can bypass this full check
7264 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
7265 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
7266 + * be used.
7267 */
7268 -static inline int user_mode(struct pt_regs *regs)
7269 +static inline int user_mode_novm(struct pt_regs *regs)
7270 {
7271 #ifdef CONFIG_X86_32
7272 return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
7273 #else
7274 - return !!(regs->cs & 3);
7275 + return !!(regs->cs & SEGMENT_RPL_MASK);
7276 #endif
7277 }
7278
7279 -static inline int user_mode_vm(struct pt_regs *regs)
7280 +static inline int user_mode(struct pt_regs *regs)
7281 {
7282 #ifdef CONFIG_X86_32
7283 return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
7284 USER_RPL;
7285 #else
7286 - return user_mode(regs);
7287 + return user_mode_novm(regs);
7288 #endif
7289 }
7290
7291 diff -urNp linux-2.6.31.1/arch/x86/include/asm/reboot.h linux-2.6.31.1/arch/x86/include/asm/reboot.h
7292 --- linux-2.6.31.1/arch/x86/include/asm/reboot.h 2009-09-24 11:45:25.000000000 -0400
7293 +++ linux-2.6.31.1/arch/x86/include/asm/reboot.h 2009-10-01 20:12:42.000000000 -0400
7294 @@ -18,7 +18,7 @@ extern struct machine_ops machine_ops;
7295
7296 void native_machine_crash_shutdown(struct pt_regs *regs);
7297 void native_machine_shutdown(void);
7298 -void machine_real_restart(const unsigned char *code, int length);
7299 +void machine_real_restart(const unsigned char *code, unsigned int length);
7300
7301 typedef void (*nmi_shootdown_cb)(int, struct die_args*);
7302 void nmi_shootdown_cpus(nmi_shootdown_cb callback);
7303 diff -urNp linux-2.6.31.1/arch/x86/include/asm/rwsem.h linux-2.6.31.1/arch/x86/include/asm/rwsem.h
7304 --- linux-2.6.31.1/arch/x86/include/asm/rwsem.h 2009-09-24 11:45:25.000000000 -0400
7305 +++ linux-2.6.31.1/arch/x86/include/asm/rwsem.h 2009-10-01 20:12:42.000000000 -0400
7306 @@ -106,10 +106,26 @@ static inline void __down_read(struct rw
7307 {
7308 asm volatile("# beginning down_read\n\t"
7309 LOCK_PREFIX " incl (%%eax)\n\t"
7310 +
7311 +#ifdef CONFIG_PAX_REFCOUNT
7312 +#ifdef CONFIG_X86_32
7313 + "into\n0:\n"
7314 +#else
7315 + "jno 0f\n"
7316 + "int $4\n0:\n"
7317 +#endif
7318 + ".pushsection .fixup,\"ax\"\n"
7319 + "1:\n"
7320 + LOCK_PREFIX "decl (%%eax)\n"
7321 + "jmp 0b\n"
7322 + ".popsection\n"
7323 + _ASM_EXTABLE(0b, 1b)
7324 +#endif
7325 +
7326 /* adds 0x00000001, returns the old value */
7327 - " jns 1f\n"
7328 + " jns 2f\n"
7329 " call call_rwsem_down_read_failed\n"
7330 - "1:\n\t"
7331 + "2:\n\t"
7332 "# ending down_read\n\t"
7333 : "+m" (sem->count)
7334 : "a" (sem)
7335 @@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
7336 __s32 result, tmp;
7337 asm volatile("# beginning __down_read_trylock\n\t"
7338 " movl %0,%1\n\t"
7339 - "1:\n\t"
7340 + "2:\n\t"
7341 " movl %1,%2\n\t"
7342 " addl %3,%2\n\t"
7343 - " jle 2f\n\t"
7344 +
7345 +#ifdef CONFIG_PAX_REFCOUNT
7346 +#ifdef CONFIG_X86_32
7347 + "into\n0:\n"
7348 +#else
7349 + "jno 0f\n"
7350 + "int $4\n0:\n"
7351 +#endif
7352 + ".pushsection .fixup,\"ax\"\n"
7353 + "1:\n"
7354 + "subl %3,%2\n"
7355 + "jmp 0b\n"
7356 + ".popsection\n"
7357 + _ASM_EXTABLE(0b, 1b)
7358 +#endif
7359 +
7360 + " jle 3f\n\t"
7361 LOCK_PREFIX " cmpxchgl %2,%0\n\t"
7362 - " jnz 1b\n\t"
7363 - "2:\n\t"
7364 + " jnz 2b\n\t"
7365 + "3:\n\t"
7366 "# ending __down_read_trylock\n\t"
7367 : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
7368 : "i" (RWSEM_ACTIVE_READ_BIAS)
7369 @@ -148,12 +180,28 @@ static inline void __down_write_nested(s
7370 tmp = RWSEM_ACTIVE_WRITE_BIAS;
7371 asm volatile("# beginning down_write\n\t"
7372 LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
7373 +
7374 +#ifdef CONFIG_PAX_REFCOUNT
7375 +#ifdef CONFIG_X86_32
7376 + "into\n0:\n"
7377 +#else
7378 + "jno 0f\n"
7379 + "int $4\n0:\n"
7380 +#endif
7381 + ".pushsection .fixup,\"ax\"\n"
7382 + "1:\n"
7383 + "movl %%edx,(%%eax)\n"
7384 + "jmp 0b\n"
7385 + ".popsection\n"
7386 + _ASM_EXTABLE(0b, 1b)
7387 +#endif
7388 +
7389 /* subtract 0x0000ffff, returns the old value */
7390 " testl %%edx,%%edx\n\t"
7391 /* was the count 0 before? */
7392 - " jz 1f\n"
7393 + " jz 2f\n"
7394 " call call_rwsem_down_write_failed\n"
7395 - "1:\n"
7396 + "2:\n"
7397 "# ending down_write"
7398 : "+m" (sem->count), "=d" (tmp)
7399 : "a" (sem), "1" (tmp)
7400 @@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
7401 __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
7402 asm volatile("# beginning __up_read\n\t"
7403 LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
7404 +
7405 +#ifdef CONFIG_PAX_REFCOUNT
7406 +#ifdef CONFIG_X86_32
7407 + "into\n0:\n"
7408 +#else
7409 + "jno 0f\n"
7410 + "int $4\n0:\n"
7411 +#endif
7412 + ".pushsection .fixup,\"ax\"\n"
7413 + "1:\n"
7414 + "movl %%edx,(%%eax)\n"
7415 + "jmp 0b\n"
7416 + ".popsection\n"
7417 + _ASM_EXTABLE(0b, 1b)
7418 +#endif
7419 +
7420 /* subtracts 1, returns the old value */
7421 - " jns 1f\n\t"
7422 + " jns 2f\n\t"
7423 " call call_rwsem_wake\n"
7424 - "1:\n"
7425 + "2:\n"
7426 "# ending __up_read\n"
7427 : "+m" (sem->count), "=d" (tmp)
7428 : "a" (sem), "1" (tmp)
7429 @@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
7430 asm volatile("# beginning __up_write\n\t"
7431 " movl %2,%%edx\n\t"
7432 LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t"
7433 +
7434 +#ifdef CONFIG_PAX_REFCOUNT
7435 +#ifdef CONFIG_X86_32
7436 + "into\n0:\n"
7437 +#else
7438 + "jno 0f\n"
7439 + "int $4\n0:\n"
7440 +#endif
7441 + ".pushsection .fixup,\"ax\"\n"
7442 + "1:\n"
7443 + "movl %%edx,(%%eax)\n"
7444 + "jmp 0b\n"
7445 + ".popsection\n"
7446 + _ASM_EXTABLE(0b, 1b)
7447 +#endif
7448 +
7449 /* tries to transition
7450 0xffff0001 -> 0x00000000 */
7451 - " jz 1f\n"
7452 + " jz 2f\n"
7453 " call call_rwsem_wake\n"
7454 - "1:\n\t"
7455 + "2:\n\t"
7456 "# ending __up_write\n"
7457 : "+m" (sem->count)
7458 : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
7459 @@ -222,10 +302,26 @@ static inline void __downgrade_write(str
7460 {
7461 asm volatile("# beginning __downgrade_write\n\t"
7462 LOCK_PREFIX " addl %2,(%%eax)\n\t"
7463 +
7464 +#ifdef CONFIG_PAX_REFCOUNT
7465 +#ifdef CONFIG_X86_32
7466 + "into\n0:\n"
7467 +#else
7468 + "jno 0f\n"
7469 + "int $4\n0:\n"
7470 +#endif
7471 + ".pushsection .fixup,\"ax\"\n"
7472 + "1:\n"
7473 + LOCK_PREFIX "subl %2,(%%eax)\n"
7474 + "jmp 0b\n"
7475 + ".popsection\n"
7476 + _ASM_EXTABLE(0b, 1b)
7477 +#endif
7478 +
7479 /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
7480 - " jns 1f\n\t"
7481 + " jns 2f\n\t"
7482 " call call_rwsem_downgrade_wake\n"
7483 - "1:\n\t"
7484 + "2:\n\t"
7485 "# ending __downgrade_write\n"
7486 : "+m" (sem->count)
7487 : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
7488 @@ -237,7 +333,23 @@ static inline void __downgrade_write(str
7489 */
7490 static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
7491 {
7492 - asm volatile(LOCK_PREFIX "addl %1,%0"
7493 + asm volatile(LOCK_PREFIX "addl %1,%0\n"
7494 +
7495 +#ifdef CONFIG_PAX_REFCOUNT
7496 +#ifdef CONFIG_X86_32
7497 + "into\n0:\n"
7498 +#else
7499 + "jno 0f\n"
7500 + "int $4\n0:\n"
7501 +#endif
7502 + ".pushsection .fixup,\"ax\"\n"
7503 + "1:\n"
7504 + LOCK_PREFIX "subl %1,%0\n"
7505 + "jmp 0b\n"
7506 + ".popsection\n"
7507 + _ASM_EXTABLE(0b, 1b)
7508 +#endif
7509 +
7510 : "+m" (sem->count)
7511 : "ir" (delta));
7512 }
7513 @@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
7514 {
7515 int tmp = delta;
7516
7517 - asm volatile(LOCK_PREFIX "xadd %0,%1"
7518 + asm volatile(LOCK_PREFIX "xadd %0,%1\n"
7519 +
7520 +#ifdef CONFIG_PAX_REFCOUNT
7521 +#ifdef CONFIG_X86_32
7522 + "into\n0:\n"
7523 +#else
7524 + "jno 0f\n"
7525 + "int $4\n0:\n"
7526 +#endif
7527 + ".pushsection .fixup,\"ax\"\n"
7528 + "1:\n"
7529 + "movl %0,%1\n"
7530 + "jmp 0b\n"
7531 + ".popsection\n"
7532 + _ASM_EXTABLE(0b, 1b)
7533 +#endif
7534 +
7535 : "+r" (tmp), "+m" (sem->count)
7536 : : "memory");
7537
7538 diff -urNp linux-2.6.31.1/arch/x86/include/asm/segment.h linux-2.6.31.1/arch/x86/include/asm/segment.h
7539 --- linux-2.6.31.1/arch/x86/include/asm/segment.h 2009-09-24 11:45:25.000000000 -0400
7540 +++ linux-2.6.31.1/arch/x86/include/asm/segment.h 2009-10-01 20:12:42.000000000 -0400
7541 @@ -88,7 +88,7 @@
7542 #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
7543 #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
7544
7545 -#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
7546 +#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
7547 #ifdef CONFIG_SMP
7548 #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
7549 #else
7550 @@ -102,6 +102,12 @@
7551 #define __KERNEL_STACK_CANARY 0
7552 #endif
7553
7554 +#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 17)
7555 +#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
7556 +
7557 +#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 18)
7558 +#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
7559 +
7560 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
7561
7562 /*
7563 @@ -139,7 +145,7 @@
7564 */
7565
7566 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
7567 -#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
7568 +#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
7569
7570
7571 #else
7572 diff -urNp linux-2.6.31.1/arch/x86/include/asm/spinlock.h linux-2.6.31.1/arch/x86/include/asm/spinlock.h
7573 --- linux-2.6.31.1/arch/x86/include/asm/spinlock.h 2009-09-24 11:45:25.000000000 -0400
7574 +++ linux-2.6.31.1/arch/x86/include/asm/spinlock.h 2009-10-01 20:12:42.000000000 -0400
7575 @@ -249,18 +249,50 @@ static inline int __raw_write_can_lock(r
7576 static inline void __raw_read_lock(raw_rwlock_t *rw)
7577 {
7578 asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
7579 - "jns 1f\n"
7580 - "call __read_lock_failed\n\t"
7581 +
7582 +#ifdef CONFIG_PAX_REFCOUNT
7583 +#ifdef CONFIG_X86_32
7584 + "into\n0:\n"
7585 +#else
7586 + "jno 0f\n"
7587 + "int $4\n0:\n"
7588 +#endif
7589 + ".pushsection .fixup,\"ax\"\n"
7590 "1:\n"
7591 + LOCK_PREFIX " addl $1,(%0)\n"
7592 + "jmp 0b\n"
7593 + ".popsection\n"
7594 + _ASM_EXTABLE(0b, 1b)
7595 +#endif
7596 +
7597 + "jns 2f\n"
7598 + "call __read_lock_failed\n\t"
7599 + "2:\n"
7600 ::LOCK_PTR_REG (rw) : "memory");
7601 }
7602
7603 static inline void __raw_write_lock(raw_rwlock_t *rw)
7604 {
7605 asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
7606 - "jz 1f\n"
7607 - "call __write_lock_failed\n\t"
7608 +
7609 +#ifdef CONFIG_PAX_REFCOUNT
7610 +#ifdef CONFIG_X86_32
7611 + "into\n0:\n"
7612 +#else
7613 + "jno 0f\n"
7614 + "int $4\n0:\n"
7615 +#endif
7616 + ".pushsection .fixup,\"ax\"\n"
7617 "1:\n"
7618 + LOCK_PREFIX " addl %1,(%0)\n"
7619 + "jmp 0b\n"
7620 + ".popsection\n"
7621 + _ASM_EXTABLE(0b, 1b)
7622 +#endif
7623 +
7624 + "jz 2f\n"
7625 + "call __write_lock_failed\n\t"
7626 + "2:\n"
7627 ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
7628 }
7629
7630 @@ -286,12 +318,45 @@ static inline int __raw_write_trylock(ra
7631
7632 static inline void __raw_read_unlock(raw_rwlock_t *rw)
7633 {
7634 - asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
7635 + asm volatile(LOCK_PREFIX "incl %0\n"
7636 +
7637 +#ifdef CONFIG_PAX_REFCOUNT
7638 +#ifdef CONFIG_X86_32
7639 + "into\n0:\n"
7640 +#else
7641 + "jno 0f\n"
7642 + "int $4\n0:\n"
7643 +#endif
7644 + ".pushsection .fixup,\"ax\"\n"
7645 + "1:\n"
7646 + LOCK_PREFIX "decl %0\n"
7647 + "jmp 0b\n"
7648 + ".popsection\n"
7649 + _ASM_EXTABLE(0b, 1b)
7650 +#endif
7651 +
7652 + :"+m" (rw->lock) : : "memory");
7653 }
7654
7655 static inline void __raw_write_unlock(raw_rwlock_t *rw)
7656 {
7657 - asm volatile(LOCK_PREFIX "addl %1, %0"
7658 + asm volatile(LOCK_PREFIX "addl %1, %0\n"
7659 +
7660 +#ifdef CONFIG_PAX_REFCOUNT
7661 +#ifdef CONFIG_X86_32
7662 + "into\n0:\n"
7663 +#else
7664 + "jno 0f\n"
7665 + "int $4\n0:\n"
7666 +#endif
7667 + ".pushsection .fixup,\"ax\"\n"
7668 + "1:\n"
7669 + LOCK_PREFIX "subl %1,%0\n"
7670 + "jmp 0b\n"
7671 + ".popsection\n"
7672 + _ASM_EXTABLE(0b, 1b)
7673 +#endif
7674 +
7675 : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
7676 }
7677
7678 diff -urNp linux-2.6.31.1/arch/x86/include/asm/system.h linux-2.6.31.1/arch/x86/include/asm/system.h
7679 --- linux-2.6.31.1/arch/x86/include/asm/system.h 2009-09-24 11:45:25.000000000 -0400
7680 +++ linux-2.6.31.1/arch/x86/include/asm/system.h 2009-10-01 20:12:42.000000000 -0400
7681 @@ -227,7 +227,7 @@ static inline unsigned long get_limit(un
7682 {
7683 unsigned long __limit;
7684 asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
7685 - return __limit + 1;
7686 + return __limit;
7687 }
7688
7689 static inline void native_clts(void)
7690 @@ -353,6 +353,23 @@ static inline void native_wbinvd(void)
7691
7692 #define stts() write_cr0(read_cr0() | X86_CR0_TS)
7693
7694 +#define pax_open_kernel(cr0) \
7695 +do { \
7696 + typecheck(unsigned long, cr0); \
7697 + preempt_disable(); \
7698 + barrier(); \
7699 + cr0 = read_cr0(); \
7700 + write_cr0(cr0 & ~X86_CR0_WP); \
7701 +} while (0)
7702 +
7703 +#define pax_close_kernel(cr0) \
7704 +do { \
7705 + typecheck(unsigned long, cr0); \
7706 + write_cr0(cr0); \
7707 + barrier(); \
7708 + preempt_enable_no_resched(); \
7709 +} while (0)
7710 +
7711 #endif /* __KERNEL__ */
7712
7713 static inline void clflush(volatile void *__p)
7714 @@ -367,7 +384,7 @@ void enable_hlt(void);
7715
7716 void cpu_idle_wait(void);
7717
7718 -extern unsigned long arch_align_stack(unsigned long sp);
7719 +#define arch_align_stack(x) ((x) & ~0xfUL)
7720 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
7721
7722 void default_idle(void);
7723 diff -urNp linux-2.6.31.1/arch/x86/include/asm/uaccess_32.h linux-2.6.31.1/arch/x86/include/asm/uaccess_32.h
7724 --- linux-2.6.31.1/arch/x86/include/asm/uaccess_32.h 2009-09-24 11:45:25.000000000 -0400
7725 +++ linux-2.6.31.1/arch/x86/include/asm/uaccess_32.h 2009-10-01 20:12:42.000000000 -0400
7726 @@ -44,6 +44,9 @@ unsigned long __must_check __copy_from_u
7727 static __always_inline unsigned long __must_check
7728 __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
7729 {
7730 + if ((long)n < 0)
7731 + return n;
7732 +
7733 if (__builtin_constant_p(n)) {
7734 unsigned long ret;
7735
7736 @@ -62,6 +65,8 @@ __copy_to_user_inatomic(void __user *to,
7737 return ret;
7738 }
7739 }
7740 + if (!__builtin_constant_p(n))
7741 + check_object_size(from, n, true);
7742 return __copy_to_user_ll(to, from, n);
7743 }
7744
7745 @@ -89,6 +94,9 @@ __copy_to_user(void __user *to, const vo
7746 static __always_inline unsigned long
7747 __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
7748 {
7749 + if ((long)n < 0)
7750 + return n;
7751 +
7752 /* Avoid zeroing the tail if the copy fails..
7753 * If 'n' is constant and 1, 2, or 4, we do still zero on a failure,
7754 * but as the zeroing behaviour is only significant when n is not
7755 @@ -138,6 +146,10 @@ static __always_inline unsigned long
7756 __copy_from_user(void *to, const void __user *from, unsigned long n)
7757 {
7758 might_fault();
7759 +
7760 + if ((long)n < 0)
7761 + return n;
7762 +
7763 if (__builtin_constant_p(n)) {
7764 unsigned long ret;
7765
7766 @@ -153,6 +165,8 @@ __copy_from_user(void *to, const void __
7767 return ret;
7768 }
7769 }
7770 + if (!__builtin_constant_p(n))
7771 + check_object_size(to, n, false);
7772 return __copy_from_user_ll(to, from, n);
7773 }
7774
7775 @@ -160,6 +174,10 @@ static __always_inline unsigned long __c
7776 const void __user *from, unsigned long n)
7777 {
7778 might_fault();
7779 +
7780 + if ((long)n < 0)
7781 + return n;
7782 +
7783 if (__builtin_constant_p(n)) {
7784 unsigned long ret;
7785
7786 @@ -182,14 +200,62 @@ static __always_inline unsigned long
7787 __copy_from_user_inatomic_nocache(void *to, const void __user *from,
7788 unsigned long n)
7789 {
7790 - return __copy_from_user_ll_nocache_nozero(to, from, n);
7791 + if ((long)n < 0)
7792 + return n;
7793 +
7794 + return __copy_from_user_ll_nocache_nozero(to, from, n);
7795 +}
7796 +
7797 +/**
7798 + * copy_to_user: - Copy a block of data into user space.
7799 + * @to: Destination address, in user space.
7800 + * @from: Source address, in kernel space.
7801 + * @n: Number of bytes to copy.
7802 + *
7803 + * Context: User context only. This function may sleep.
7804 + *
7805 + * Copy data from kernel space to user space.
7806 + *
7807 + * Returns number of bytes that could not be copied.
7808 + * On success, this will be zero.
7809 + */
7810 +static __always_inline unsigned long __must_check
7811 +copy_to_user(void __user *to, const void *from, unsigned long n)
7812 +{
7813 + if (access_ok(VERIFY_WRITE, to, n))
7814 + n = __copy_to_user(to, from, n);
7815 + return n;
7816 +}
7817 +
7818 +/**
7819 + * copy_from_user: - Copy a block of data from user space.
7820 + * @to: Destination address, in kernel space.
7821 + * @from: Source address, in user space.
7822 + * @n: Number of bytes to copy.
7823 + *
7824 + * Context: User context only. This function may sleep.
7825 + *
7826 + * Copy data from user space to kernel space.
7827 + *
7828 + * Returns number of bytes that could not be copied.
7829 + * On success, this will be zero.
7830 + *
7831 + * If some data could not be copied, this function will pad the copied
7832 + * data to the requested size using zero bytes.
7833 + */
7834 +static __always_inline unsigned long __must_check
7835 +copy_from_user(void *to, const void __user *from, unsigned long n)
7836 +{
7837 + if (access_ok(VERIFY_READ, from, n))
7838 + n = __copy_from_user(to, from, n);
7839 + else if ((long)n > 0) {
7840 + if (!__builtin_constant_p(n))
7841 + check_object_size(to, n, false);
7842 + memset(to, 0, n);
7843 + }
7844 + return n;
7845 }
7846
7847 -unsigned long __must_check copy_to_user(void __user *to,
7848 - const void *from, unsigned long n);
7849 -unsigned long __must_check copy_from_user(void *to,
7850 - const void __user *from,
7851 - unsigned long n);
7852 long __must_check strncpy_from_user(char *dst, const char __user *src,
7853 long count);
7854 long __must_check __strncpy_from_user(char *dst,
7855 diff -urNp linux-2.6.31.1/arch/x86/include/asm/uaccess_64.h linux-2.6.31.1/arch/x86/include/asm/uaccess_64.h
7856 --- linux-2.6.31.1/arch/x86/include/asm/uaccess_64.h 2009-09-24 11:45:25.000000000 -0400
7857 +++ linux-2.6.31.1/arch/x86/include/asm/uaccess_64.h 2009-10-01 20:12:42.000000000 -0400
7858 @@ -10,6 +10,8 @@
7859 #include <linux/lockdep.h>
7860 #include <asm/page.h>
7861
7862 +#define set_fs(x) (current_thread_info()->addr_limit = (x))
7863 +
7864 /*
7865 * Copy To/From Userspace
7866 */
7867 @@ -19,20 +21,22 @@ __must_check unsigned long
7868 copy_user_generic(void *to, const void *from, unsigned len);
7869
7870 __must_check unsigned long
7871 -copy_to_user(void __user *to, const void *from, unsigned len);
7872 -__must_check unsigned long
7873 -copy_from_user(void *to, const void __user *from, unsigned len);
7874 -__must_check unsigned long
7875 copy_in_user(void __user *to, const void __user *from, unsigned len);
7876
7877 static __always_inline __must_check
7878 -int __copy_from_user(void *dst, const void __user *src, unsigned size)
7879 +unsigned long __copy_from_user(void *dst, const void __user *src, unsigned size)
7880 {
7881 - int ret = 0;
7882 + unsigned ret = 0;
7883
7884 might_fault();
7885 - if (!__builtin_constant_p(size))
7886 +
7887 + if ((int)size < 0)
7888 + return size;
7889 +
7890 + if (!__builtin_constant_p(size)) {
7891 + check_object_size(dst, size, false);
7892 return copy_user_generic(dst, (__force void *)src, size);
7893 + }
7894 switch (size) {
7895 case 1:__get_user_asm(*(u8 *)dst, (u8 __user *)src,
7896 ret, "b", "b", "=q", 1);
7897 @@ -70,13 +74,19 @@ int __copy_from_user(void *dst, const vo
7898 }
7899
7900 static __always_inline __must_check
7901 -int __copy_to_user(void __user *dst, const void *src, unsigned size)
7902 +unsigned long __copy_to_user(void __user *dst, const void *src, unsigned size)
7903 {
7904 - int ret = 0;
7905 + unsigned ret = 0;
7906
7907 might_fault();
7908 - if (!__builtin_constant_p(size))
7909 +
7910 + if ((int)size < 0)
7911 + return size;
7912 +
7913 + if (!__builtin_constant_p(size)) {
7914 + check_object_size(src, size, true);
7915 return copy_user_generic((__force void *)dst, src, size);
7916 + }
7917 switch (size) {
7918 case 1:__put_user_asm(*(u8 *)src, (u8 __user *)dst,
7919 ret, "b", "b", "iq", 1);
7920 @@ -114,11 +124,39 @@ int __copy_to_user(void __user *dst, con
7921 }
7922
7923 static __always_inline __must_check
7924 -int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
7925 +unsigned long copy_to_user(void __user *to, const void *from, unsigned len)
7926 {
7927 - int ret = 0;
7928 + if (access_ok(VERIFY_WRITE, to, len))
7929 + len = __copy_to_user(to, from, len);
7930 + return len;
7931 +}
7932 +
7933 +static __always_inline __must_check
7934 +unsigned long copy_from_user(void *to, const void __user *from, unsigned len)
7935 +{
7936 + if ((int)len < 0)
7937 + return len;
7938 +
7939 + if (access_ok(VERIFY_READ, from, len))
7940 + len = __copy_from_user(to, from, len);
7941 + else if ((int)len > 0) {
7942 + if (!__builtin_constant_p(len))
7943 + check_object_size(to, len, false);
7944 + memset(to, 0, len);
7945 + }
7946 + return len;
7947 +}
7948 +
7949 +static __always_inline __must_check
7950 +unsigned long __copy_in_user(void __user *dst, const void __user *src, unsigned size)
7951 +{
7952 + unsigned ret = 0;
7953
7954 might_fault();
7955 +
7956 + if ((int)size < 0)
7957 + return size;
7958 +
7959 if (!__builtin_constant_p(size))
7960 return copy_user_generic((__force void *)dst,
7961 (__force void *)src, size);
7962 @@ -179,30 +217,38 @@ __must_check unsigned long __clear_user(
7963 __must_check long __copy_from_user_inatomic(void *dst, const void __user *src,
7964 unsigned size);
7965
7966 -static __must_check __always_inline int
7967 +static __must_check __always_inline unsigned long
7968 __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size)
7969 {
7970 + if ((int)size < 0)
7971 + return size;
7972 +
7973 return copy_user_generic((__force void *)dst, src, size);
7974 }
7975
7976 -extern long __copy_user_nocache(void *dst, const void __user *src,
7977 +extern unsigned long __copy_user_nocache(void *dst, const void __user *src,
7978 unsigned size, int zerorest);
7979
7980 -static inline int
7981 -__copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
7982 +static inline unsigned long __copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
7983 {
7984 might_sleep();
7985 +
7986 + if ((int)size < 0)
7987 + return size;
7988 +
7989 return __copy_user_nocache(dst, src, size, 1);
7990 }
7991
7992 -static inline int
7993 -__copy_from_user_inatomic_nocache(void *dst, const void __user *src,
7994 +static inline unsigned long __copy_from_user_inatomic_nocache(void *dst, const void __user *src,
7995 unsigned size)
7996 {
7997 + if ((int)size < 0)
7998 + return size;
7999 +
8000 return __copy_user_nocache(dst, src, size, 0);
8001 }
8002
8003 -unsigned long
8004 +extern unsigned long
8005 copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest);
8006
8007 #endif /* _ASM_X86_UACCESS_64_H */
8008 diff -urNp linux-2.6.31.1/arch/x86/include/asm/uaccess.h linux-2.6.31.1/arch/x86/include/asm/uaccess.h
8009 --- linux-2.6.31.1/arch/x86/include/asm/uaccess.h 2009-09-24 11:45:25.000000000 -0400
8010 +++ linux-2.6.31.1/arch/x86/include/asm/uaccess.h 2009-10-01 20:12:42.000000000 -0400
8011 @@ -8,8 +8,11 @@
8012 #include <linux/thread_info.h>
8013 #include <linux/prefetch.h>
8014 #include <linux/string.h>
8015 +#include <linux/sched.h>
8016 +#include <linux/slab.h>
8017 #include <asm/asm.h>
8018 #include <asm/page.h>
8019 +#include <asm/segment.h>
8020
8021 #define VERIFY_READ 0
8022 #define VERIFY_WRITE 1
8023 @@ -29,7 +32,12 @@
8024
8025 #define get_ds() (KERNEL_DS)
8026 #define get_fs() (current_thread_info()->addr_limit)
8027 +#ifdef CONFIG_X86_32
8028 +void __set_fs(mm_segment_t x, int cpu);
8029 +void set_fs(mm_segment_t x);
8030 +#else
8031 #define set_fs(x) (current_thread_info()->addr_limit = (x))
8032 +#endif
8033
8034 #define segment_eq(a, b) ((a).seg == (b).seg)
8035
8036 @@ -77,7 +85,26 @@
8037 * checks that the pointer is in the user space range - after calling
8038 * this function, memory access functions may still return -EFAULT.
8039 */
8040 -#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0))
8041 +#define access_ok(type, addr, size) \
8042 +({ \
8043 + bool __ret_ao = __range_not_ok(addr, size) == 0; \
8044 + unsigned long __addr_ao = (unsigned long)addr & PAGE_MASK; \
8045 + unsigned long __end_ao = (unsigned long)addr + size - 1; \
8046 + if (__ret_ao && unlikely((__end_ao ^ __addr_ao) & PAGE_MASK)) { \
8047 + for (; __addr_ao <= __end_ao; __addr_ao += PAGE_SIZE) { \
8048 + char __c_ao; \
8049 + if (size > PAGE_SIZE) \
8050 + cond_resched(); \
8051 + if (__get_user(__c_ao, (char __user *)__addr_ao))\
8052 + break; \
8053 + if (type != VERIFY_WRITE) \
8054 + continue; \
8055 + if (__put_user(__c_ao, (char __user *)__addr_ao))\
8056 + break; \
8057 + } \
8058 + } \
8059 + __ret_ao; \
8060 +})
8061
8062 /*
8063 * The exception table consists of pairs of addresses: the first is the
8064 @@ -183,13 +210,21 @@ extern int __get_user_bad(void);
8065 asm volatile("call __put_user_" #size : "=a" (__ret_pu) \
8066 : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
8067
8068 -
8069 +#ifdef CONFIG_X86_32
8070 +#define _ASM_LOAD_USER_DS(ds) "movw %w" #ds ",%%ds\n"
8071 +#define _ASM_LOAD_KERNEL_DS "pushl %%ss; popl %%ds\n"
8072 +#else
8073 +#define _ASM_LOAD_USER_DS(ds)
8074 +#define _ASM_LOAD_KERNEL_DS
8075 +#endif
8076
8077 #ifdef CONFIG_X86_32
8078 #define __put_user_asm_u64(x, addr, err, errret) \
8079 - asm volatile("1: movl %%eax,0(%2)\n" \
8080 - "2: movl %%edx,4(%2)\n" \
8081 + asm volatile(_ASM_LOAD_USER_DS(5) \
8082 + "1: movl %%eax,%%ds:0(%2)\n" \
8083 + "2: movl %%edx,%%ds:4(%2)\n" \
8084 "3:\n" \
8085 + _ASM_LOAD_KERNEL_DS \
8086 ".section .fixup,\"ax\"\n" \
8087 "4: movl %3,%0\n" \
8088 " jmp 3b\n" \
8089 @@ -197,15 +232,18 @@ extern int __get_user_bad(void);
8090 _ASM_EXTABLE(1b, 4b) \
8091 _ASM_EXTABLE(2b, 4b) \
8092 : "=r" (err) \
8093 - : "A" (x), "r" (addr), "i" (errret), "0" (err))
8094 + : "A" (x), "r" (addr), "i" (errret), "0" (err), \
8095 + "r"(__USER_DS))
8096
8097 #define __put_user_asm_ex_u64(x, addr) \
8098 - asm volatile("1: movl %%eax,0(%1)\n" \
8099 - "2: movl %%edx,4(%1)\n" \
8100 + asm volatile(_ASM_LOAD_USER_DS(2) \
8101 + "1: movl %%eax,%%ds:0(%1)\n" \
8102 + "2: movl %%edx,%%ds:4(%1)\n" \
8103 "3:\n" \
8104 + _ASM_LOAD_KERNEL_DS \
8105 _ASM_EXTABLE(1b, 2b - 1b) \
8106 _ASM_EXTABLE(2b, 3b - 2b) \
8107 - : : "A" (x), "r" (addr))
8108 + : : "A" (x), "r" (addr), "r"(__USER_DS))
8109
8110 #define __put_user_x8(x, ptr, __ret_pu) \
8111 asm volatile("call __put_user_8" : "=a" (__ret_pu) \
8112 @@ -374,16 +412,18 @@ do { \
8113 } while (0)
8114
8115 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
8116 - asm volatile("1: mov"itype" %2,%"rtype"1\n" \
8117 + asm volatile(_ASM_LOAD_USER_DS(5) \
8118 + "1: mov"itype" %%ds:%2,%"rtype"1\n" \
8119 "2:\n" \
8120 + _ASM_LOAD_KERNEL_DS \
8121 ".section .fixup,\"ax\"\n" \
8122 "3: mov %3,%0\n" \
8123 " xor"itype" %"rtype"1,%"rtype"1\n" \
8124 " jmp 2b\n" \
8125 ".previous\n" \
8126 _ASM_EXTABLE(1b, 3b) \
8127 - : "=r" (err), ltype(x) \
8128 - : "m" (__m(addr)), "i" (errret), "0" (err))
8129 + : "=r" (err), ltype (x) \
8130 + : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
8131
8132 #define __get_user_size_ex(x, ptr, size) \
8133 do { \
8134 @@ -407,10 +447,12 @@ do { \
8135 } while (0)
8136
8137 #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
8138 - asm volatile("1: mov"itype" %1,%"rtype"0\n" \
8139 + asm volatile(_ASM_LOAD_USER_DS(2) \
8140 + "1: mov"itype" %%ds:%1,%"rtype"0\n" \
8141 "2:\n" \
8142 + _ASM_LOAD_KERNEL_DS \
8143 _ASM_EXTABLE(1b, 2b - 1b) \
8144 - : ltype(x) : "m" (__m(addr)))
8145 + : ltype(x) : "m" (__m(addr)), "r"(__USER_DS))
8146
8147 #define __put_user_nocheck(x, ptr, size) \
8148 ({ \
8149 @@ -438,21 +480,26 @@ struct __large_struct { unsigned long bu
8150 * aliasing issues.
8151 */
8152 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
8153 - asm volatile("1: mov"itype" %"rtype"1,%2\n" \
8154 + asm volatile(_ASM_LOAD_USER_DS(5) \
8155 + "1: mov"itype" %"rtype"1,%%ds:%2\n" \
8156 "2:\n" \
8157 + _ASM_LOAD_KERNEL_DS \
8158 ".section .fixup,\"ax\"\n" \
8159 "3: mov %3,%0\n" \
8160 " jmp 2b\n" \
8161 ".previous\n" \
8162 _ASM_EXTABLE(1b, 3b) \
8163 : "=r"(err) \
8164 - : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
8165 + : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
8166 + "r"(__USER_DS))
8167
8168 #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \
8169 - asm volatile("1: mov"itype" %"rtype"0,%1\n" \
8170 + asm volatile(_ASM_LOAD_USER_DS(2) \
8171 + "1: mov"itype" %"rtype"0,%%ds:%1\n" \
8172 "2:\n" \
8173 + _ASM_LOAD_KERNEL_DS \
8174 _ASM_EXTABLE(1b, 2b - 1b) \
8175 - : : ltype(x), "m" (__m(addr)))
8176 + : : ltype(x), "m" (__m(addr)), "r"(__USER_DS))
8177
8178 /*
8179 * uaccess_try and catch
8180 @@ -567,6 +614,7 @@ extern struct movsl_mask {
8181
8182 #define ARCH_HAS_NOCACHE_UACCESS 1
8183
8184 +#define ARCH_HAS_SORT_EXTABLE
8185 #ifdef CONFIG_X86_32
8186 # include "uaccess_32.h"
8187 #else
8188 diff -urNp linux-2.6.31.1/arch/x86/include/asm/vgtod.h linux-2.6.31.1/arch/x86/include/asm/vgtod.h
8189 --- linux-2.6.31.1/arch/x86/include/asm/vgtod.h 2009-09-24 11:45:25.000000000 -0400
8190 +++ linux-2.6.31.1/arch/x86/include/asm/vgtod.h 2009-10-01 20:12:42.000000000 -0400
8191 @@ -14,6 +14,7 @@ struct vsyscall_gtod_data {
8192 int sysctl_enabled;
8193 struct timezone sys_tz;
8194 struct { /* extract of a clocksource struct */
8195 + char name[8];
8196 cycle_t (*vread)(void);
8197 cycle_t cycle_last;
8198 cycle_t mask;
8199 diff -urNp linux-2.6.31.1/arch/x86/include/asm/vsyscall.h linux-2.6.31.1/arch/x86/include/asm/vsyscall.h
8200 --- linux-2.6.31.1/arch/x86/include/asm/vsyscall.h 2009-09-24 11:45:25.000000000 -0400
8201 +++ linux-2.6.31.1/arch/x86/include/asm/vsyscall.h 2009-10-01 20:12:42.000000000 -0400
8202 @@ -15,9 +15,10 @@ enum vsyscall_num {
8203
8204 #ifdef __KERNEL__
8205 #include <linux/seqlock.h>
8206 +#include <linux/getcpu.h>
8207 +#include <linux/time.h>
8208
8209 #define __section_vgetcpu_mode __attribute__ ((unused, __section__ (".vgetcpu_mode"), aligned(16)))
8210 -#define __section_jiffies __attribute__ ((unused, __section__ (".jiffies"), aligned(16)))
8211
8212 /* Definitions for CONFIG_GENERIC_TIME definitions */
8213 #define __section_vsyscall_gtod_data __attribute__ \
8214 @@ -31,7 +32,6 @@ enum vsyscall_num {
8215 #define VGETCPU_LSL 2
8216
8217 extern int __vgetcpu_mode;
8218 -extern volatile unsigned long __jiffies;
8219
8220 /* kernel space (writeable) */
8221 extern int vgetcpu_mode;
8222 @@ -39,6 +39,9 @@ extern struct timezone sys_tz;
8223
8224 extern void map_vsyscall(void);
8225
8226 +extern int vgettimeofday(struct timeval * tv, struct timezone * tz);
8227 +extern time_t vtime(time_t *t);
8228 +extern long vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache);
8229 #endif /* __KERNEL__ */
8230
8231 #endif /* _ASM_X86_VSYSCALL_H */
8232 diff -urNp linux-2.6.31.1/arch/x86/Kconfig linux-2.6.31.1/arch/x86/Kconfig
8233 --- linux-2.6.31.1/arch/x86/Kconfig 2009-09-24 11:45:25.000000000 -0400
8234 +++ linux-2.6.31.1/arch/x86/Kconfig 2009-10-01 20:12:42.000000000 -0400
8235 @@ -1098,7 +1098,7 @@ config PAGE_OFFSET
8236 hex
8237 default 0xB0000000 if VMSPLIT_3G_OPT
8238 default 0x80000000 if VMSPLIT_2G
8239 - default 0x78000000 if VMSPLIT_2G_OPT
8240 + default 0x70000000 if VMSPLIT_2G_OPT
8241 default 0x40000000 if VMSPLIT_1G
8242 default 0xC0000000
8243 depends on X86_32
8244 @@ -1416,7 +1416,7 @@ config X86_PAT
8245
8246 config EFI
8247 bool "EFI runtime service support"
8248 - depends on ACPI
8249 + depends on ACPI && !PAX_KERNEXEC
8250 ---help---
8251 This enables the kernel to use EFI runtime services that are
8252 available (such as the EFI variable services).
8253 @@ -1602,9 +1602,10 @@ config HOTPLUG_CPU
8254 Say N if you want to disable CPU hotplug.
8255
8256 config COMPAT_VDSO
8257 - def_bool y
8258 + def_bool n
8259 prompt "Compat VDSO support"
8260 depends on X86_32 || IA32_EMULATION
8261 + depends on !PAX_NOEXEC && !PAX_MEMORY_UDEREF
8262 ---help---
8263 Map the 32-bit VDSO to the predictable old-style address too.
8264 ---help---
8265 diff -urNp linux-2.6.31.1/arch/x86/Kconfig.cpu linux-2.6.31.1/arch/x86/Kconfig.cpu
8266 --- linux-2.6.31.1/arch/x86/Kconfig.cpu 2009-09-24 11:45:25.000000000 -0400
8267 +++ linux-2.6.31.1/arch/x86/Kconfig.cpu 2009-10-01 20:12:42.000000000 -0400
8268 @@ -331,7 +331,7 @@ config X86_PPRO_FENCE
8269
8270 config X86_F00F_BUG
8271 def_bool y
8272 - depends on M586MMX || M586TSC || M586 || M486 || M386
8273 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
8274
8275 config X86_WP_WORKS_OK
8276 def_bool y
8277 @@ -351,7 +351,7 @@ config X86_POPAD_OK
8278
8279 config X86_ALIGNMENT_16
8280 def_bool y
8281 - depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
8282 + depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
8283
8284 config X86_INTEL_USERCOPY
8285 def_bool y
8286 @@ -397,7 +397,7 @@ config X86_CMPXCHG64
8287 # generates cmov.
8288 config X86_CMOV
8289 def_bool y
8290 - depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64)
8291 + depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64)
8292
8293 config X86_MINIMUM_CPU_FAMILY
8294 int
8295 diff -urNp linux-2.6.31.1/arch/x86/Kconfig.debug linux-2.6.31.1/arch/x86/Kconfig.debug
8296 --- linux-2.6.31.1/arch/x86/Kconfig.debug 2009-09-24 11:45:25.000000000 -0400
8297 +++ linux-2.6.31.1/arch/x86/Kconfig.debug 2009-10-01 20:12:42.000000000 -0400
8298 @@ -99,7 +99,7 @@ config X86_PTDUMP
8299 config DEBUG_RODATA
8300 bool "Write protect kernel read-only data structures"
8301 default y
8302 - depends on DEBUG_KERNEL
8303 + depends on DEBUG_KERNEL && BROKEN
8304 ---help---
8305 Mark the kernel read-only data as write-protected in the pagetables,
8306 in order to catch accidental (and incorrect) writes to such const
8307 diff -urNp linux-2.6.31.1/arch/x86/kernel/acpi/boot.c linux-2.6.31.1/arch/x86/kernel/acpi/boot.c
8308 --- linux-2.6.31.1/arch/x86/kernel/acpi/boot.c 2009-09-24 11:45:25.000000000 -0400
8309 +++ linux-2.6.31.1/arch/x86/kernel/acpi/boot.c 2009-10-01 20:12:42.000000000 -0400
8310 @@ -1609,7 +1609,7 @@ static struct dmi_system_id __initdata a
8311 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
8312 },
8313 },
8314 - {}
8315 + { NULL, NULL, {{0, {0}}}, NULL}
8316 };
8317
8318 /*
8319 diff -urNp linux-2.6.31.1/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.31.1/arch/x86/kernel/acpi/realmode/wakeup.S
8320 --- linux-2.6.31.1/arch/x86/kernel/acpi/realmode/wakeup.S 2009-09-24 11:45:25.000000000 -0400
8321 +++ linux-2.6.31.1/arch/x86/kernel/acpi/realmode/wakeup.S 2009-10-01 20:12:42.000000000 -0400
8322 @@ -104,7 +104,7 @@ _start:
8323 movl %eax, %ecx
8324 orl %edx, %ecx
8325 jz 1f
8326 - movl $0xc0000080, %ecx
8327 + mov $MSR_EFER, %ecx
8328 wrmsr
8329 1:
8330
8331 diff -urNp linux-2.6.31.1/arch/x86/kernel/acpi/sleep.c linux-2.6.31.1/arch/x86/kernel/acpi/sleep.c
8332 --- linux-2.6.31.1/arch/x86/kernel/acpi/sleep.c 2009-09-24 11:45:25.000000000 -0400
8333 +++ linux-2.6.31.1/arch/x86/kernel/acpi/sleep.c 2009-10-01 20:12:42.000000000 -0400
8334 @@ -11,11 +11,12 @@
8335 #include <linux/cpumask.h>
8336 #include <asm/segment.h>
8337 #include <asm/desc.h>
8338 +#include <asm/e820.h>
8339
8340 #include "realmode/wakeup.h"
8341 #include "sleep.h"
8342
8343 -unsigned long acpi_wakeup_address;
8344 +unsigned long acpi_wakeup_address = 0x2000;
8345 unsigned long acpi_realmode_flags;
8346
8347 /* address in low memory of the wakeup routine. */
8348 @@ -37,6 +38,10 @@ int acpi_save_state_mem(void)
8349 {
8350 struct wakeup_header *header;
8351
8352 +#if defined(CONFIG_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_PAX_KERNEXEC)
8353 + unsigned long cr0;
8354 +#endif
8355 +
8356 if (!acpi_realmode) {
8357 printk(KERN_ERR "Could not allocate memory during boot, "
8358 "S3 disabled\n");
8359 @@ -99,8 +104,18 @@ int acpi_save_state_mem(void)
8360 header->trampoline_segment = setup_trampoline() >> 4;
8361 #ifdef CONFIG_SMP
8362 stack_start.sp = temp_stack + sizeof(temp_stack);
8363 +
8364 +#ifdef CONFIG_PAX_KERNEXEC
8365 + pax_open_kernel(cr0);
8366 +#endif
8367 +
8368 early_gdt_descr.address =
8369 (unsigned long)get_cpu_gdt_table(smp_processor_id());
8370 +
8371 +#ifdef CONFIG_PAX_KERNEXEC
8372 + pax_close_kernel(cr0);
8373 +#endif
8374 +
8375 initial_gs = per_cpu_offset(smp_processor_id());
8376 #endif
8377 initial_code = (unsigned long)wakeup_long64;
8378 @@ -134,14 +149,8 @@ void __init acpi_reserve_bootmem(void)
8379 return;
8380 }
8381
8382 - acpi_realmode = (unsigned long)alloc_bootmem_low(WAKEUP_SIZE);
8383 -
8384 - if (!acpi_realmode) {
8385 - printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
8386 - return;
8387 - }
8388 -
8389 - acpi_wakeup_address = virt_to_phys((void *)acpi_realmode);
8390 + reserve_early(acpi_wakeup_address, acpi_wakeup_address + WAKEUP_SIZE, "ACPI Wakeup Code");
8391 + acpi_realmode = (unsigned long)__va(acpi_wakeup_address);;
8392 }
8393
8394
8395 diff -urNp linux-2.6.31.1/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.31.1/arch/x86/kernel/acpi/wakeup_32.S
8396 --- linux-2.6.31.1/arch/x86/kernel/acpi/wakeup_32.S 2009-09-24 11:45:25.000000000 -0400
8397 +++ linux-2.6.31.1/arch/x86/kernel/acpi/wakeup_32.S 2009-10-01 20:12:42.000000000 -0400
8398 @@ -30,13 +30,11 @@ wakeup_pmode_return:
8399 # and restore the stack ... but you need gdt for this to work
8400 movl saved_context_esp, %esp
8401
8402 - movl %cs:saved_magic, %eax
8403 - cmpl $0x12345678, %eax
8404 + cmpl $0x12345678, saved_magic
8405 jne bogus_magic
8406
8407 # jump to place where we left off
8408 - movl saved_eip, %eax
8409 - jmp *%eax
8410 + jmp *(saved_eip)
8411
8412 bogus_magic:
8413 jmp bogus_magic
8414 diff -urNp linux-2.6.31.1/arch/x86/kernel/alternative.c linux-2.6.31.1/arch/x86/kernel/alternative.c
8415 --- linux-2.6.31.1/arch/x86/kernel/alternative.c 2009-09-24 11:45:25.000000000 -0400
8416 +++ linux-2.6.31.1/arch/x86/kernel/alternative.c 2009-10-01 20:12:42.000000000 -0400
8417 @@ -400,7 +400,7 @@ void apply_paravirt(struct paravirt_patc
8418
8419 BUG_ON(p->len > MAX_PATCH_LEN);
8420 /* prep the buffer with the original instructions */
8421 - memcpy(insnbuf, p->instr, p->len);
8422 + memcpy(insnbuf, ktla_ktva(p->instr), p->len);
8423 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
8424 (unsigned long)p->instr, p->len);
8425
8426 @@ -485,11 +485,26 @@ void __init alternative_instructions(voi
8427 * instructions. And on the local CPU you need to be protected again NMI or MCE
8428 * handlers seeing an inconsistent instruction while you patch.
8429 */
8430 -void *text_poke_early(void *addr, const void *opcode, size_t len)
8431 +void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
8432 {
8433 unsigned long flags;
8434 +
8435 +#ifdef CONFIG_PAX_KERNEXEC
8436 + unsigned long cr0;
8437 +#endif
8438 +
8439 local_irq_save(flags);
8440 - memcpy(addr, opcode, len);
8441 +
8442 +#ifdef CONFIG_PAX_KERNEXEC
8443 + pax_open_kernel(cr0);
8444 +#endif
8445 +
8446 + memcpy(ktla_ktva(addr), opcode, len);
8447 +
8448 +#ifdef CONFIG_PAX_KERNEXEC
8449 + pax_close_kernel(cr0);
8450 +#endif
8451 +
8452 local_irq_restore(flags);
8453 sync_core();
8454 /* Could also do a CLFLUSH here to speed up CPU recovery; but
8455 @@ -512,35 +527,27 @@ void *text_poke_early(void *addr, const
8456 */
8457 void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
8458 {
8459 - unsigned long flags;
8460 - char *vaddr;
8461 + unsigned char *vaddr = ktla_ktva(addr);
8462 struct page *pages[2];
8463 - int i;
8464 + size_t i;
8465 +
8466 + if (!core_kernel_text((unsigned long)addr)
8467
8468 - if (!core_kernel_text((unsigned long)addr)) {
8469 - pages[0] = vmalloc_to_page(addr);
8470 - pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
8471 +#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
8472 + && (vaddr < MODULES_EXEC_VADDR || MODULES_EXEC_END < vaddr)
8473 +#endif
8474 +
8475 + ) {
8476 + pages[0] = vmalloc_to_page(vaddr);
8477 + pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
8478 } else {
8479 - pages[0] = virt_to_page(addr);
8480 + pages[0] = virt_to_page(vaddr);
8481 WARN_ON(!PageReserved(pages[0]));
8482 - pages[1] = virt_to_page(addr + PAGE_SIZE);
8483 + pages[1] = virt_to_page(vaddr + PAGE_SIZE);
8484 }
8485 BUG_ON(!pages[0]);
8486 - local_irq_save(flags);
8487 - set_fixmap(FIX_TEXT_POKE0, page_to_phys(pages[0]));
8488 - if (pages[1])
8489 - set_fixmap(FIX_TEXT_POKE1, page_to_phys(pages[1]));
8490 - vaddr = (char *)fix_to_virt(FIX_TEXT_POKE0);
8491 - memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
8492 - clear_fixmap(FIX_TEXT_POKE0);
8493 - if (pages[1])
8494 - clear_fixmap(FIX_TEXT_POKE1);
8495 - local_flush_tlb();
8496 - sync_core();
8497 - /* Could also do a CLFLUSH here to speed up CPU recovery; but
8498 - that causes hangs on some VIA CPUs. */
8499 + text_poke_early(addr, opcode, len);
8500 for (i = 0; i < len; i++)
8501 - BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
8502 - local_irq_restore(flags);
8503 + BUG_ON(((char *)vaddr)[i] != ((char *)opcode)[i]);
8504 return addr;
8505 }
8506 diff -urNp linux-2.6.31.1/arch/x86/kernel/apm_32.c linux-2.6.31.1/arch/x86/kernel/apm_32.c
8507 --- linux-2.6.31.1/arch/x86/kernel/apm_32.c 2009-09-24 11:45:25.000000000 -0400
8508 +++ linux-2.6.31.1/arch/x86/kernel/apm_32.c 2009-10-01 20:12:42.000000000 -0400
8509 @@ -403,7 +403,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
8510 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
8511 static struct apm_user *user_list;
8512 static DEFINE_SPINLOCK(user_list_lock);
8513 -static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
8514 +static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
8515
8516 static const char driver_version[] = "1.16ac"; /* no spaces */
8517
8518 @@ -576,12 +576,25 @@ static long __apm_bios_call(void *_call)
8519 struct desc_struct *gdt;
8520 struct apm_bios_call *call = _call;
8521
8522 +#ifdef CONFIG_PAX_KERNEXEC
8523 + unsigned long cr0;
8524 +#endif
8525 +
8526 cpu = get_cpu();
8527 BUG_ON(cpu != 0);
8528 gdt = get_cpu_gdt_table(cpu);
8529 save_desc_40 = gdt[0x40 / 8];
8530 +
8531 +#ifdef CONFIG_PAX_KERNEXEC
8532 + pax_open_kernel(cr0);
8533 +#endif
8534 +
8535 gdt[0x40 / 8] = bad_bios_desc;
8536
8537 +#ifdef CONFIG_PAX_KERNEXEC
8538 + pax_close_kernel(cr0);
8539 +#endif
8540 +
8541 apm_irq_save(flags);
8542 APM_DO_SAVE_SEGS;
8543 apm_bios_call_asm(call->func, call->ebx, call->ecx,
8544 @@ -589,7 +602,17 @@ static long __apm_bios_call(void *_call)
8545 &call->esi);
8546 APM_DO_RESTORE_SEGS;
8547 apm_irq_restore(flags);
8548 +
8549 +#ifdef CONFIG_PAX_KERNEXEC
8550 + pax_open_kernel(cr0);
8551 +#endif
8552 +
8553 gdt[0x40 / 8] = save_desc_40;
8554 +
8555 +#ifdef CONFIG_PAX_KERNEXEC
8556 + pax_close_kernel(cr0);
8557 +#endif
8558 +
8559 put_cpu();
8560
8561 return call->eax & 0xff;
8562 @@ -652,19 +675,42 @@ static long __apm_bios_call_simple(void
8563 struct desc_struct *gdt;
8564 struct apm_bios_call *call = _call;
8565
8566 +#ifdef CONFIG_PAX_KERNEXEC
8567 + unsigned long cr0;
8568 +#endif
8569 +
8570 cpu = get_cpu();
8571 BUG_ON(cpu != 0);
8572 gdt = get_cpu_gdt_table(cpu);
8573 save_desc_40 = gdt[0x40 / 8];
8574 +
8575 +#ifdef CONFIG_PAX_KERNEXEC
8576 + pax_open_kernel(cr0);
8577 +#endif
8578 +
8579 gdt[0x40 / 8] = bad_bios_desc;
8580
8581 +#ifdef CONFIG_PAX_KERNEXEC
8582 + pax_close_kernel(cr0);
8583 +#endif
8584 +
8585 apm_irq_save(flags);
8586 APM_DO_SAVE_SEGS;
8587 error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
8588 &call->eax);
8589 APM_DO_RESTORE_SEGS;
8590 apm_irq_restore(flags);
8591 +
8592 +#ifdef CONFIG_PAX_KERNEXEC
8593 + pax_open_kernel(cr0);
8594 +#endif
8595 +
8596 gdt[0x40 / 8] = save_desc_40;
8597 +
8598 +#ifdef CONFIG_PAX_KERNEXEC
8599 + pax_close_kernel(cr0);
8600 +#endif
8601 +
8602 put_cpu();
8603 return error;
8604 }
8605 @@ -967,7 +1013,7 @@ recalc:
8606
8607 static void apm_power_off(void)
8608 {
8609 - unsigned char po_bios_call[] = {
8610 + const unsigned char po_bios_call[] = {
8611 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
8612 0x8e, 0xd0, /* movw ax,ss */
8613 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
8614 @@ -1925,7 +1971,10 @@ static const struct file_operations apm_
8615 static struct miscdevice apm_device = {
8616 APM_MINOR_DEV,
8617 "apm_bios",
8618 - &apm_bios_fops
8619 + &apm_bios_fops,
8620 + {NULL, NULL},
8621 + NULL,
8622 + NULL
8623 };
8624
8625
8626 @@ -2246,7 +2295,7 @@ static struct dmi_system_id __initdata a
8627 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
8628 },
8629
8630 - { }
8631 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
8632 };
8633
8634 /*
8635 @@ -2264,6 +2313,10 @@ static int __init apm_init(void)
8636 struct desc_struct *gdt;
8637 int err;
8638
8639 +#ifdef CONFIG_PAX_KERNEXEC
8640 + unsigned long cr0;
8641 +#endif
8642 +
8643 dmi_check_system(apm_dmi_table);
8644
8645 if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
8646 @@ -2337,9 +2390,18 @@ static int __init apm_init(void)
8647 * This is for buggy BIOS's that refer to (real mode) segment 0x40
8648 * even though they are called in protected mode.
8649 */
8650 +
8651 +#ifdef CONFIG_PAX_KERNEXEC
8652 + pax_open_kernel(cr0);
8653 +#endif
8654 +
8655 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
8656 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
8657
8658 +#ifdef CONFIG_PAX_KERNEXEC
8659 + pax_close_kernel(cr0);
8660 +#endif
8661 +
8662 /*
8663 * Set up the long jump entry point to the APM BIOS, which is called
8664 * from inline assembly.
8665 @@ -2358,6 +2420,11 @@ static int __init apm_init(void)
8666 * code to that CPU.
8667 */
8668 gdt = get_cpu_gdt_table(0);
8669 +
8670 +#ifdef CONFIG_PAX_KERNEXEC
8671 + pax_open_kernel(cr0);
8672 +#endif
8673 +
8674 set_base(gdt[APM_CS >> 3],
8675 __va((unsigned long)apm_info.bios.cseg << 4));
8676 set_base(gdt[APM_CS_16 >> 3],
8677 @@ -2365,6 +2432,10 @@ static int __init apm_init(void)
8678 set_base(gdt[APM_DS >> 3],
8679 __va((unsigned long)apm_info.bios.dseg << 4));
8680
8681 +#ifdef CONFIG_PAX_KERNEXEC
8682 + pax_close_kernel(cr0);
8683 +#endif
8684 +
8685 proc_create("apm", 0, NULL, &apm_file_ops);
8686
8687 kapmd_task = kthread_create(apm, NULL, "kapmd");
8688 diff -urNp linux-2.6.31.1/arch/x86/kernel/asm-offsets_32.c linux-2.6.31.1/arch/x86/kernel/asm-offsets_32.c
8689 --- linux-2.6.31.1/arch/x86/kernel/asm-offsets_32.c 2009-09-24 11:45:25.000000000 -0400
8690 +++ linux-2.6.31.1/arch/x86/kernel/asm-offsets_32.c 2009-10-01 20:12:42.000000000 -0400
8691 @@ -115,6 +115,7 @@ void foo(void)
8692 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
8693 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
8694 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
8695 + OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
8696 #endif
8697
8698 #ifdef CONFIG_XEN
8699 diff -urNp linux-2.6.31.1/arch/x86/kernel/asm-offsets_64.c linux-2.6.31.1/arch/x86/kernel/asm-offsets_64.c
8700 --- linux-2.6.31.1/arch/x86/kernel/asm-offsets_64.c 2009-09-24 11:45:25.000000000 -0400
8701 +++ linux-2.6.31.1/arch/x86/kernel/asm-offsets_64.c 2009-10-01 20:12:42.000000000 -0400
8702 @@ -114,6 +114,7 @@ int main(void)
8703 ENTRY(cr8);
8704 BLANK();
8705 #undef ENTRY
8706 + DEFINE(TSS_size, sizeof(struct tss_struct));
8707 DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
8708 BLANK();
8709 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
8710 diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/common.c linux-2.6.31.1/arch/x86/kernel/cpu/common.c
8711 --- linux-2.6.31.1/arch/x86/kernel/cpu/common.c 2009-09-24 11:45:25.000000000 -0400
8712 +++ linux-2.6.31.1/arch/x86/kernel/cpu/common.c 2009-10-01 20:12:42.000000000 -0400
8713 @@ -84,60 +84,6 @@ static const struct cpu_dev __cpuinitcon
8714
8715 static const struct cpu_dev *this_cpu __cpuinitdata = &default_cpu;
8716
8717 -DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
8718 -#ifdef CONFIG_X86_64
8719 - /*
8720 - * We need valid kernel segments for data and code in long mode too
8721 - * IRET will check the segment types kkeil 2000/10/28
8722 - * Also sysret mandates a special GDT layout
8723 - *
8724 - * TLS descriptors are currently at a different place compared to i386.
8725 - * Hopefully nobody expects them at a fixed place (Wine?)
8726 - */
8727 - [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
8728 - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
8729 - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
8730 - [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
8731 - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
8732 - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
8733 -#else
8734 - [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
8735 - [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
8736 - [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
8737 - [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
8738 - /*
8739 - * Segments used for calling PnP BIOS have byte granularity.
8740 - * They code segments and data segments have fixed 64k limits,
8741 - * the transfer segment sizes are set at run time.
8742 - */
8743 - /* 32-bit code */
8744 - [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
8745 - /* 16-bit code */
8746 - [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
8747 - /* 16-bit data */
8748 - [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
8749 - /* 16-bit data */
8750 - [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
8751 - /* 16-bit data */
8752 - [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
8753 - /*
8754 - * The APM segments have byte granularity and their bases
8755 - * are set at run time. All have 64k limits.
8756 - */
8757 - /* 32-bit code */
8758 - [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
8759 - /* 16-bit code */
8760 - [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
8761 - /* data */
8762 - [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
8763 -
8764 - [GDT_ENTRY_ESPFIX_SS] = { { { 0x0000ffff, 0x00cf9200 } } },
8765 - [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } },
8766 - GDT_STACK_CANARY_INIT
8767 -#endif
8768 -} };
8769 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
8770 -
8771 static int __init x86_xsave_setup(char *s)
8772 {
8773 setup_clear_cpu_cap(X86_FEATURE_XSAVE);
8774 @@ -345,7 +291,7 @@ void switch_to_new_gdt(int cpu)
8775 {
8776 struct desc_ptr gdt_descr;
8777
8778 - gdt_descr.address = (long)get_cpu_gdt_table(cpu);
8779 + gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
8780 gdt_descr.size = GDT_SIZE - 1;
8781 load_gdt(&gdt_descr);
8782 /* Reload the per-cpu base */
8783 @@ -799,6 +745,10 @@ static void __cpuinit identify_cpu(struc
8784 /* Filter out anything that depends on CPUID levels we don't have */
8785 filter_cpuid_features(c, true);
8786
8787 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
8788 + setup_clear_cpu_cap(X86_FEATURE_SEP);
8789 +#endif
8790 +
8791 /* If the model name is still unset, do table lookup. */
8792 if (!c->x86_model_id[0]) {
8793 const char *p;
8794 @@ -982,7 +932,7 @@ static __init int setup_disablecpuid(cha
8795 __setup("clearcpuid=", setup_disablecpuid);
8796
8797 #ifdef CONFIG_X86_64
8798 -struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
8799 +struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
8800
8801 DEFINE_PER_CPU_FIRST(union irq_stack_union,
8802 irq_stack_union) __aligned(PAGE_SIZE);
8803 @@ -1092,7 +1042,7 @@ void __cpuinit cpu_init(void)
8804 int i;
8805
8806 cpu = stack_smp_processor_id();
8807 - t = &per_cpu(init_tss, cpu);
8808 + t = init_tss + cpu;
8809 orig_ist = &per_cpu(orig_ist, cpu);
8810
8811 #ifdef CONFIG_NUMA
8812 @@ -1190,7 +1140,7 @@ void __cpuinit cpu_init(void)
8813 {
8814 int cpu = smp_processor_id();
8815 struct task_struct *curr = current;
8816 - struct tss_struct *t = &per_cpu(init_tss, cpu);
8817 + struct tss_struct *t = init_tss + cpu;
8818 struct thread_struct *thread = &curr->thread;
8819
8820 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
8821 diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
8822 --- linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2009-09-24 11:45:25.000000000 -0400
8823 +++ linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2009-10-01 20:12:42.000000000 -0400
8824 @@ -586,7 +586,7 @@ static const struct dmi_system_id sw_any
8825 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
8826 },
8827 },
8828 - { }
8829 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
8830 };
8831 #endif
8832
8833 diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
8834 --- linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2009-09-24 11:45:25.000000000 -0400
8835 +++ linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2009-10-01 20:12:42.000000000 -0400
8836 @@ -225,7 +225,7 @@ static struct cpu_model models[] =
8837 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
8838 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
8839
8840 - { NULL, }
8841 + { NULL, NULL, 0, NULL}
8842 };
8843 #undef _BANIAS
8844 #undef BANIAS
8845 diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/intel.c linux-2.6.31.1/arch/x86/kernel/cpu/intel.c
8846 --- linux-2.6.31.1/arch/x86/kernel/cpu/intel.c 2009-09-24 11:45:25.000000000 -0400
8847 +++ linux-2.6.31.1/arch/x86/kernel/cpu/intel.c 2009-10-01 20:12:42.000000000 -0400
8848 @@ -140,7 +140,7 @@ static void __cpuinit trap_init_f00f_bug
8849 * Update the IDT descriptor and reload the IDT so that
8850 * it uses the read-only mapped virtual address.
8851 */
8852 - idt_descr.address = fix_to_virt(FIX_F00F_IDT);
8853 + idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
8854 load_idt(&idt_descr);
8855 }
8856 #endif
8857 diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/Makefile linux-2.6.31.1/arch/x86/kernel/cpu/Makefile
8858 --- linux-2.6.31.1/arch/x86/kernel/cpu/Makefile 2009-09-24 11:45:25.000000000 -0400
8859 +++ linux-2.6.31.1/arch/x86/kernel/cpu/Makefile 2009-10-01 20:12:42.000000000 -0400
8860 @@ -7,10 +7,6 @@ ifdef CONFIG_FUNCTION_TRACER
8861 CFLAGS_REMOVE_common.o = -pg
8862 endif
8863
8864 -# Make sure load_percpu_segment has no stackprotector
8865 -nostackp := $(call cc-option, -fno-stack-protector)
8866 -CFLAGS_common.o := $(nostackp)
8867 -
8868 obj-y := intel_cacheinfo.o addon_cpuid_features.o
8869 obj-y += proc.o capflags.o powerflags.o common.o
8870 obj-y += vmware.o hypervisor.o
8871 diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/mcheck/mce.c linux-2.6.31.1/arch/x86/kernel/cpu/mcheck/mce.c
8872 --- linux-2.6.31.1/arch/x86/kernel/cpu/mcheck/mce.c 2009-09-24 11:45:25.000000000 -0400
8873 +++ linux-2.6.31.1/arch/x86/kernel/cpu/mcheck/mce.c 2009-10-01 20:12:42.000000000 -0400
8874 @@ -1370,14 +1370,14 @@ void __cpuinit mcheck_init(struct cpuinf
8875 */
8876
8877 static DEFINE_SPINLOCK(mce_state_lock);
8878 -static int open_count; /* #times opened */
8879 +static atomic_t open_count; /* #times opened */
8880 static int open_exclu; /* already open exclusive? */
8881
8882 static int mce_open(struct inode *inode, struct file *file)
8883 {
8884 spin_lock(&mce_state_lock);
8885
8886 - if (open_exclu || (open_count && (file->f_flags & O_EXCL))) {
8887 + if (open_exclu || (atomic_read(&open_count) && (file->f_flags & O_EXCL))) {
8888 spin_unlock(&mce_state_lock);
8889
8890 return -EBUSY;
8891 @@ -1385,7 +1385,7 @@ static int mce_open(struct inode *inode,
8892
8893 if (file->f_flags & O_EXCL)
8894 open_exclu = 1;
8895 - open_count++;
8896 + atomic_inc(&open_count);
8897
8898 spin_unlock(&mce_state_lock);
8899
8900 @@ -1396,7 +1396,7 @@ static int mce_release(struct inode *ino
8901 {
8902 spin_lock(&mce_state_lock);
8903
8904 - open_count--;
8905 + atomic_dec(&open_count);
8906 open_exclu = 0;
8907
8908 spin_unlock(&mce_state_lock);
8909 @@ -1536,6 +1536,7 @@ static struct miscdevice mce_log_device
8910 MISC_MCELOG_MINOR,
8911 "mcelog",
8912 &mce_chrdev_ops,
8913 + {NULL, NULL}, NULL, NULL
8914 };
8915
8916 /*
8917 diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.31.1/arch/x86/kernel/cpu/mtrr/generic.c
8918 --- linux-2.6.31.1/arch/x86/kernel/cpu/mtrr/generic.c 2009-09-24 11:45:25.000000000 -0400
8919 +++ linux-2.6.31.1/arch/x86/kernel/cpu/mtrr/generic.c 2009-10-01 20:12:42.000000000 -0400
8920 @@ -23,14 +23,14 @@ static struct fixed_range_block fixed_ra
8921 { MSR_MTRRfix64K_00000, 1 }, /* one 64k MTRR */
8922 { MSR_MTRRfix16K_80000, 2 }, /* two 16k MTRRs */
8923 { MSR_MTRRfix4K_C0000, 8 }, /* eight 4k MTRRs */
8924 - {}
8925 + { 0, 0 }
8926 };
8927
8928 static unsigned long smp_changes_mask;
8929 static int mtrr_state_set;
8930 u64 mtrr_tom2;
8931
8932 -struct mtrr_state_type mtrr_state = {};
8933 +struct mtrr_state_type mtrr_state;
8934 EXPORT_SYMBOL_GPL(mtrr_state);
8935
8936 /**
8937 diff -urNp linux-2.6.31.1/arch/x86/kernel/crash.c linux-2.6.31.1/arch/x86/kernel/crash.c
8938 --- linux-2.6.31.1/arch/x86/kernel/crash.c 2009-09-24 11:45:25.000000000 -0400
8939 +++ linux-2.6.31.1/arch/x86/kernel/crash.c 2009-10-01 20:12:42.000000000 -0400
8940 @@ -42,7 +42,7 @@ static void kdump_nmi_callback(int cpu,
8941 regs = args->regs;
8942
8943 #ifdef CONFIG_X86_32
8944 - if (!user_mode_vm(regs)) {
8945 + if (!user_mode(regs)) {
8946 crash_fixup_ss_esp(&fixed_regs, regs);
8947 regs = &fixed_regs;
8948 }
8949 diff -urNp linux-2.6.31.1/arch/x86/kernel/doublefault_32.c linux-2.6.31.1/arch/x86/kernel/doublefault_32.c
8950 --- linux-2.6.31.1/arch/x86/kernel/doublefault_32.c 2009-09-24 11:45:25.000000000 -0400
8951 +++ linux-2.6.31.1/arch/x86/kernel/doublefault_32.c 2009-10-01 20:12:42.000000000 -0400
8952 @@ -11,7 +11,7 @@
8953
8954 #define DOUBLEFAULT_STACKSIZE (1024)
8955 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
8956 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
8957 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
8958
8959 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
8960
8961 @@ -21,7 +21,7 @@ static void doublefault_fn(void)
8962 unsigned long gdt, tss;
8963
8964 store_gdt(&gdt_desc);
8965 - gdt = gdt_desc.address;
8966 + gdt = (unsigned long)gdt_desc.address;
8967
8968 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
8969
8970 @@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
8971 /* 0x2 bit is always set */
8972 .flags = X86_EFLAGS_SF | 0x2,
8973 .sp = STACK_START,
8974 - .es = __USER_DS,
8975 + .es = __KERNEL_DS,
8976 .cs = __KERNEL_CS,
8977 .ss = __KERNEL_DS,
8978 - .ds = __USER_DS,
8979 + .ds = __KERNEL_DS,
8980 .fs = __KERNEL_PERCPU,
8981
8982 .__cr3 = __pa_nodebug(swapper_pg_dir),
8983 diff -urNp linux-2.6.31.1/arch/x86/kernel/dumpstack_32.c linux-2.6.31.1/arch/x86/kernel/dumpstack_32.c
8984 --- linux-2.6.31.1/arch/x86/kernel/dumpstack_32.c 2009-09-24 11:45:25.000000000 -0400
8985 +++ linux-2.6.31.1/arch/x86/kernel/dumpstack_32.c 2009-10-01 20:12:42.000000000 -0400
8986 @@ -113,11 +113,12 @@ void show_registers(struct pt_regs *regs
8987 * When in-kernel, we also print out the stack and code at the
8988 * time of the fault..
8989 */
8990 - if (!user_mode_vm(regs)) {
8991 + if (!user_mode(regs)) {
8992 unsigned int code_prologue = code_bytes * 43 / 64;
8993 unsigned int code_len = code_bytes;
8994 unsigned char c;
8995 u8 *ip;
8996 + unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
8997
8998 printk(KERN_EMERG "Stack:\n");
8999 show_stack_log_lvl(NULL, regs, &regs->sp,
9000 @@ -125,10 +126,10 @@ void show_registers(struct pt_regs *regs
9001
9002 printk(KERN_EMERG "Code: ");
9003
9004 - ip = (u8 *)regs->ip - code_prologue;
9005 + ip = (u8 *)regs->ip - code_prologue + cs_base;
9006 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
9007 /* try starting at IP */
9008 - ip = (u8 *)regs->ip;
9009 + ip = (u8 *)regs->ip + cs_base;
9010 code_len = code_len - code_prologue + 1;
9011 }
9012 for (i = 0; i < code_len; i++, ip++) {
9013 @@ -137,7 +138,7 @@ void show_registers(struct pt_regs *regs
9014 printk(" Bad EIP value.");
9015 break;
9016 }
9017 - if (ip == (u8 *)regs->ip)
9018 + if (ip == (u8 *)regs->ip + cs_base)
9019 printk("<%02x> ", c);
9020 else
9021 printk("%02x ", c);
9022 @@ -150,6 +151,7 @@ int is_valid_bugaddr(unsigned long ip)
9023 {
9024 unsigned short ud2;
9025
9026 + ip = ktla_ktva(ip);
9027 if (ip < PAGE_OFFSET)
9028 return 0;
9029 if (probe_kernel_address((unsigned short *)ip, ud2))
9030 diff -urNp linux-2.6.31.1/arch/x86/kernel/dumpstack.c linux-2.6.31.1/arch/x86/kernel/dumpstack.c
9031 --- linux-2.6.31.1/arch/x86/kernel/dumpstack.c 2009-09-24 11:45:25.000000000 -0400
9032 +++ linux-2.6.31.1/arch/x86/kernel/dumpstack.c 2009-10-01 20:12:42.000000000 -0400
9033 @@ -181,7 +181,7 @@ void dump_stack(void)
9034 #endif
9035
9036 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
9037 - current->pid, current->comm, print_tainted(),
9038 + task_pid_nr(current), current->comm, print_tainted(),
9039 init_utsname()->release,
9040 (int)strcspn(init_utsname()->version, " "),
9041 init_utsname()->version);
9042 @@ -242,7 +242,7 @@ void __kprobes oops_end(unsigned long fl
9043 panic("Fatal exception in interrupt");
9044 if (panic_on_oops)
9045 panic("Fatal exception");
9046 - do_exit(signr);
9047 + do_group_exit(signr);
9048 }
9049
9050 int __kprobes __die(const char *str, struct pt_regs *regs, long err)
9051 @@ -296,7 +296,7 @@ void die(const char *str, struct pt_regs
9052 unsigned long flags = oops_begin();
9053 int sig = SIGSEGV;
9054
9055 - if (!user_mode_vm(regs))
9056 + if (!user_mode(regs))
9057 report_bug(regs->ip, regs);
9058
9059 if (__die(str, regs, err))
9060 diff -urNp linux-2.6.31.1/arch/x86/kernel/e820.c linux-2.6.31.1/arch/x86/kernel/e820.c
9061 --- linux-2.6.31.1/arch/x86/kernel/e820.c 2009-09-24 11:45:25.000000000 -0400
9062 +++ linux-2.6.31.1/arch/x86/kernel/e820.c 2009-10-01 20:12:42.000000000 -0400
9063 @@ -733,7 +733,10 @@ struct early_res {
9064 };
9065 static struct early_res early_res[MAX_EARLY_RES] __initdata = {
9066 { 0, PAGE_SIZE, "BIOS data page" }, /* BIOS data page */
9067 - {}
9068 +#ifdef CONFIG_VM86
9069 + { PAGE_SIZE, ISA_START_ADDRESS, "V86 mode memory", 1 },
9070 +#endif
9071 + { 0, 0, {0}, 0 }
9072 };
9073
9074 static int __init find_overlapped_early(u64 start, u64 end)
9075 diff -urNp linux-2.6.31.1/arch/x86/kernel/efi_32.c linux-2.6.31.1/arch/x86/kernel/efi_32.c
9076 --- linux-2.6.31.1/arch/x86/kernel/efi_32.c 2009-09-24 11:45:25.000000000 -0400
9077 +++ linux-2.6.31.1/arch/x86/kernel/efi_32.c 2009-10-01 20:12:42.000000000 -0400
9078 @@ -38,70 +38,38 @@
9079 */
9080
9081 static unsigned long efi_rt_eflags;
9082 -static pgd_t efi_bak_pg_dir_pointer[2];
9083 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
9084
9085 -void efi_call_phys_prelog(void)
9086 +void __init efi_call_phys_prelog(void)
9087 {
9088 - unsigned long cr4;
9089 - unsigned long temp;
9090 struct desc_ptr gdt_descr;
9091
9092 local_irq_save(efi_rt_eflags);
9093
9094 - /*
9095 - * If I don't have PAE, I should just duplicate two entries in page
9096 - * directory. If I have PAE, I just need to duplicate one entry in
9097 - * page directory.
9098 - */
9099 - cr4 = read_cr4_safe();
9100
9101 - if (cr4 & X86_CR4_PAE) {
9102 - efi_bak_pg_dir_pointer[0].pgd =
9103 - swapper_pg_dir[pgd_index(0)].pgd;
9104 - swapper_pg_dir[0].pgd =
9105 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
9106 - } else {
9107 - efi_bak_pg_dir_pointer[0].pgd =
9108 - swapper_pg_dir[pgd_index(0)].pgd;
9109 - efi_bak_pg_dir_pointer[1].pgd =
9110 - swapper_pg_dir[pgd_index(0x400000)].pgd;
9111 - swapper_pg_dir[pgd_index(0)].pgd =
9112 - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
9113 - temp = PAGE_OFFSET + 0x400000;
9114 - swapper_pg_dir[pgd_index(0x400000)].pgd =
9115 - swapper_pg_dir[pgd_index(temp)].pgd;
9116 - }
9117 + clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
9118 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
9119 + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
9120
9121 /*
9122 * After the lock is released, the original page table is restored.
9123 */
9124 __flush_tlb_all();
9125
9126 - gdt_descr.address = __pa(get_cpu_gdt_table(0));
9127 + gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
9128 gdt_descr.size = GDT_SIZE - 1;
9129 load_gdt(&gdt_descr);
9130 }
9131
9132 -void efi_call_phys_epilog(void)
9133 +void __init efi_call_phys_epilog(void)
9134 {
9135 - unsigned long cr4;
9136 struct desc_ptr gdt_descr;
9137
9138 - gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
9139 + gdt_descr.address = get_cpu_gdt_table(0);
9140 gdt_descr.size = GDT_SIZE - 1;
9141 load_gdt(&gdt_descr);
9142
9143 - cr4 = read_cr4_safe();
9144 -
9145 - if (cr4 & X86_CR4_PAE) {
9146 - swapper_pg_dir[pgd_index(0)].pgd =
9147 - efi_bak_pg_dir_pointer[0].pgd;
9148 - } else {
9149 - swapper_pg_dir[pgd_index(0)].pgd =
9150 - efi_bak_pg_dir_pointer[0].pgd;
9151 - swapper_pg_dir[pgd_index(0x400000)].pgd =
9152 - efi_bak_pg_dir_pointer[1].pgd;
9153 - }
9154 + clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
9155
9156 /*
9157 * After the lock is released, the original page table is restored.
9158 diff -urNp linux-2.6.31.1/arch/x86/kernel/efi_stub_32.S linux-2.6.31.1/arch/x86/kernel/efi_stub_32.S
9159 --- linux-2.6.31.1/arch/x86/kernel/efi_stub_32.S 2009-09-24 11:45:25.000000000 -0400
9160 +++ linux-2.6.31.1/arch/x86/kernel/efi_stub_32.S 2009-10-01 20:12:42.000000000 -0400
9161 @@ -6,6 +6,7 @@
9162 */
9163
9164 #include <linux/linkage.h>
9165 +#include <linux/init.h>
9166 #include <asm/page_types.h>
9167
9168 /*
9169 @@ -20,7 +21,7 @@
9170 * service functions will comply with gcc calling convention, too.
9171 */
9172
9173 -.text
9174 +__INIT
9175 ENTRY(efi_call_phys)
9176 /*
9177 * 0. The function can only be called in Linux kernel. So CS has been
9178 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
9179 * The mapping of lower virtual memory has been created in prelog and
9180 * epilog.
9181 */
9182 - movl $1f, %edx
9183 - subl $__PAGE_OFFSET, %edx
9184 - jmp *%edx
9185 + jmp 1f-__PAGE_OFFSET
9186 1:
9187
9188 /*
9189 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
9190 * parameter 2, ..., param n. To make things easy, we save the return
9191 * address of efi_call_phys in a global variable.
9192 */
9193 - popl %edx
9194 - movl %edx, saved_return_addr
9195 - /* get the function pointer into ECX*/
9196 - popl %ecx
9197 - movl %ecx, efi_rt_function_ptr
9198 - movl $2f, %edx
9199 - subl $__PAGE_OFFSET, %edx
9200 - pushl %edx
9201 + popl (saved_return_addr)
9202 + popl (efi_rt_function_ptr)
9203
9204 /*
9205 * 3. Clear PG bit in %CR0.
9206 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
9207 /*
9208 * 5. Call the physical function.
9209 */
9210 - jmp *%ecx
9211 + call *(efi_rt_function_ptr-__PAGE_OFFSET)
9212
9213 -2:
9214 /*
9215 * 6. After EFI runtime service returns, control will return to
9216 * following instruction. We'd better readjust stack pointer first.
9217 @@ -88,35 +80,28 @@ ENTRY(efi_call_phys)
9218 movl %cr0, %edx
9219 orl $0x80000000, %edx
9220 movl %edx, %cr0
9221 - jmp 1f
9222 -1:
9223 +
9224 /*
9225 * 8. Now restore the virtual mode from flat mode by
9226 * adding EIP with PAGE_OFFSET.
9227 */
9228 - movl $1f, %edx
9229 - jmp *%edx
9230 + jmp 1f+__PAGE_OFFSET
9231 1:
9232
9233 /*
9234 * 9. Balance the stack. And because EAX contain the return value,
9235 * we'd better not clobber it.
9236 */
9237 - leal efi_rt_function_ptr, %edx
9238 - movl (%edx), %ecx
9239 - pushl %ecx
9240 + pushl (efi_rt_function_ptr)
9241
9242 /*
9243 - * 10. Push the saved return address onto the stack and return.
9244 + * 10. Return to the saved return address.
9245 */
9246 - leal saved_return_addr, %edx
9247 - movl (%edx), %ecx
9248 - pushl %ecx
9249 - ret
9250 + jmpl *(saved_return_addr)
9251 ENDPROC(efi_call_phys)
9252 .previous
9253
9254 -.data
9255 +__INITDATA
9256 saved_return_addr:
9257 .long 0
9258 efi_rt_function_ptr:
9259 diff -urNp linux-2.6.31.1/arch/x86/kernel/entry_32.S linux-2.6.31.1/arch/x86/kernel/entry_32.S
9260 --- linux-2.6.31.1/arch/x86/kernel/entry_32.S 2009-09-24 11:45:25.000000000 -0400
9261 +++ linux-2.6.31.1/arch/x86/kernel/entry_32.S 2009-10-01 20:12:42.000000000 -0400
9262 @@ -191,7 +191,7 @@
9263
9264 #endif /* CONFIG_X86_32_LAZY_GS */
9265
9266 -.macro SAVE_ALL
9267 +.macro __SAVE_ALL _DS
9268 cld
9269 PUSH_GS
9270 pushl %fs
9271 @@ -224,7 +224,7 @@
9272 pushl %ebx
9273 CFI_ADJUST_CFA_OFFSET 4
9274 CFI_REL_OFFSET ebx, 0
9275 - movl $(__USER_DS), %edx
9276 + movl $\_DS, %edx
9277 movl %edx, %ds
9278 movl %edx, %es
9279 movl $(__KERNEL_PERCPU), %edx
9280 @@ -232,6 +232,21 @@
9281 SET_KERNEL_GS %edx
9282 .endm
9283
9284 +.macro SAVE_ALL
9285 +#ifdef CONFIG_PAX_KERNEXEC
9286 + __SAVE_ALL __KERNEL_DS
9287 + GET_CR0_INTO_EDX;
9288 + movl %edx, %esi;
9289 + orl $X86_CR0_WP, %edx;
9290 + xorl %edx, %esi;
9291 + SET_CR0_FROM_EDX
9292 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
9293 + __SAVE_ALL __KERNEL_DS
9294 +#else
9295 + __SAVE_ALL __USER_DS
9296 +#endif
9297 +.endm
9298 +
9299 .macro RESTORE_INT_REGS
9300 popl %ebx
9301 CFI_ADJUST_CFA_OFFSET -4
9302 @@ -329,6 +344,11 @@ ENTRY(ret_from_fork)
9303 CFI_ADJUST_CFA_OFFSET 4
9304 popfl
9305 CFI_ADJUST_CFA_OFFSET -4
9306 +
9307 +#ifdef CONFIG_PAX_KERNEXEC
9308 + xorl %esi, %esi
9309 +#endif
9310 +
9311 jmp syscall_exit
9312 CFI_ENDPROC
9313 END(ret_from_fork)
9314 @@ -352,7 +372,17 @@ check_userspace:
9315 movb PT_CS(%esp), %al
9316 andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
9317 cmpl $USER_RPL, %eax
9318 +
9319 +#ifdef CONFIG_PAX_KERNEXEC
9320 + jae resume_userspace
9321 +
9322 + GET_CR0_INTO_EDX
9323 + xorl %esi, %edx
9324 + SET_CR0_FROM_EDX
9325 + jmp resume_kernel
9326 +#else
9327 jb resume_kernel # not returning to v8086 or userspace
9328 +#endif
9329
9330 ENTRY(resume_userspace)
9331 LOCKDEP_SYS_EXIT
9332 @@ -414,10 +444,9 @@ sysenter_past_esp:
9333 /*CFI_REL_OFFSET cs, 0*/
9334 /*
9335 * Push current_thread_info()->sysenter_return to the stack.
9336 - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
9337 - * pushed above; +8 corresponds to copy_thread's esp0 setting.
9338 */
9339 - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
9340 + GET_THREAD_INFO(%ebp)
9341 + pushl TI_sysenter_return(%ebp)
9342 CFI_ADJUST_CFA_OFFSET 4
9343 CFI_REL_OFFSET eip, 0
9344
9345 @@ -430,9 +459,19 @@ sysenter_past_esp:
9346 * Load the potential sixth argument from user stack.
9347 * Careful about security.
9348 */
9349 + movl PT_OLDESP(%esp),%ebp
9350 +
9351 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9352 + mov PT_OLDSS(%esp),%ds
9353 +1: movl %ds:(%ebp),%ebp
9354 + push %ss
9355 + pop %ds
9356 +#else
9357 cmpl $__PAGE_OFFSET-3,%ebp
9358 jae syscall_fault
9359 1: movl (%ebp),%ebp
9360 +#endif
9361 +
9362 movl %ebp,PT_EBP(%esp)
9363 .section __ex_table,"a"
9364 .align 4
9365 @@ -455,12 +494,23 @@ sysenter_do_call:
9366 testl $_TIF_ALLWORK_MASK, %ecx
9367 jne sysexit_audit
9368 sysenter_exit:
9369 +
9370 +#ifdef CONFIG_PAX_RANDKSTACK
9371 + pushl %eax
9372 + CFI_ADJUST_CFA_OFFSET 4
9373 + call pax_randomize_kstack
9374 + popl %eax
9375 + CFI_ADJUST_CFA_OFFSET -4
9376 +#endif
9377 +
9378 /* if something modifies registers it must also disable sysexit */
9379 movl PT_EIP(%esp), %edx
9380 movl PT_OLDESP(%esp), %ecx
9381 xorl %ebp,%ebp
9382 TRACE_IRQS_ON
9383 1: mov PT_FS(%esp), %fs
9384 +2: mov PT_DS(%esp), %ds
9385 +3: mov PT_ES(%esp), %es
9386 PTGS_TO_GS
9387 ENABLE_INTERRUPTS_SYSEXIT
9388
9389 @@ -504,11 +554,17 @@ sysexit_audit:
9390
9391 CFI_ENDPROC
9392 .pushsection .fixup,"ax"
9393 -2: movl $0,PT_FS(%esp)
9394 +4: movl $0,PT_FS(%esp)
9395 + jmp 1b
9396 +5: movl $0,PT_DS(%esp)
9397 + jmp 1b
9398 +6: movl $0,PT_ES(%esp)
9399 jmp 1b
9400 .section __ex_table,"a"
9401 .align 4
9402 - .long 1b,2b
9403 + .long 1b,4b
9404 + .long 2b,5b
9405 + .long 3b,6b
9406 .popsection
9407 PTGS_TO_GS_EX
9408 ENDPROC(ia32_sysenter_target)
9409 @@ -538,6 +594,10 @@ syscall_exit:
9410 testl $_TIF_ALLWORK_MASK, %ecx # current->work
9411 jne syscall_exit_work
9412
9413 +#ifdef CONFIG_PAX_RANDKSTACK
9414 + call pax_randomize_kstack
9415 +#endif
9416 +
9417 restore_all:
9418 TRACE_IRQS_IRET
9419 restore_all_notrace:
9420 @@ -602,7 +662,13 @@ ldt_ss:
9421 mov PT_OLDESP(%esp), %eax /* load userspace esp */
9422 mov %dx, %ax /* eax: new kernel esp */
9423 sub %eax, %edx /* offset (low word is 0) */
9424 - PER_CPU(gdt_page, %ebx)
9425 +#ifdef CONFIG_SMP
9426 + movl PER_CPU_VAR(cpu_number), %ebx
9427 + shll $PAGE_SHIFT_asm, %ebx
9428 + addl $cpu_gdt_table, %ebx
9429 +#else
9430 + movl $cpu_gdt_table, %ebx
9431 +#endif
9432 shr $16, %edx
9433 mov %dl, GDT_ENTRY_ESPFIX_SS * 8 + 4(%ebx) /* bits 16..23 */
9434 mov %dh, GDT_ENTRY_ESPFIX_SS * 8 + 7(%ebx) /* bits 24..31 */
9435 @@ -642,25 +708,19 @@ work_resched:
9436
9437 work_notifysig: # deal with pending signals and
9438 # notify-resume requests
9439 + movl %esp, %eax
9440 #ifdef CONFIG_VM86
9441 testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
9442 - movl %esp, %eax
9443 - jne work_notifysig_v86 # returning to kernel-space or
9444 + jz 1f # returning to kernel-space or
9445 # vm86-space
9446 - xorl %edx, %edx
9447 - call do_notify_resume
9448 - jmp resume_userspace_sig
9449
9450 - ALIGN
9451 -work_notifysig_v86:
9452 pushl %ecx # save ti_flags for do_notify_resume
9453 CFI_ADJUST_CFA_OFFSET 4
9454 call save_v86_state # %eax contains pt_regs pointer
9455 popl %ecx
9456 CFI_ADJUST_CFA_OFFSET -4
9457 movl %eax, %esp
9458 -#else
9459 - movl %esp, %eax
9460 +1:
9461 #endif
9462 xorl %edx, %edx
9463 call do_notify_resume
9464 @@ -695,6 +755,10 @@ END(syscall_exit_work)
9465
9466 RING0_INT_FRAME # can't unwind into user space anyway
9467 syscall_fault:
9468 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9469 + push %ss
9470 + pop %ds
9471 +#endif
9472 GET_THREAD_INFO(%ebp)
9473 movl $-EFAULT,PT_EAX(%esp)
9474 jmp resume_userspace
9475 @@ -735,7 +799,13 @@ PTREGSCALL(vm86old)
9476 * normal stack and adjusts ESP with the matching offset.
9477 */
9478 /* fixup the stack */
9479 - PER_CPU(gdt_page, %ebx)
9480 +#ifdef CONFIG_SMP
9481 + movl PER_CPU_VAR(cpu_number), %ebx
9482 + shll $PAGE_SHIFT_asm, %ebx
9483 + addl $cpu_gdt_table, %ebx
9484 +#else
9485 + movl $cpu_gdt_table, %ebx
9486 +#endif
9487 mov GDT_ENTRY_ESPFIX_SS * 8 + 4(%ebx), %al /* bits 16..23 */
9488 mov GDT_ENTRY_ESPFIX_SS * 8 + 7(%ebx), %ah /* bits 24..31 */
9489 shl $16, %eax
9490 @@ -1198,7 +1268,6 @@ return_to_handler:
9491 ret
9492 #endif
9493
9494 -.section .rodata,"a"
9495 #include "syscall_table_32.S"
9496
9497 syscall_table_size=(.-sys_call_table)
9498 @@ -1250,12 +1319,21 @@ error_code:
9499 movl %ecx, %fs
9500 UNWIND_ESPFIX_STACK
9501 GS_TO_REG %ecx
9502 +
9503 +#ifdef CONFIG_PAX_KERNEXEC
9504 + GET_CR0_INTO_EDX
9505 + movl %edx, %esi
9506 + orl $X86_CR0_WP, %edx
9507 + xorl %edx, %esi
9508 + SET_CR0_FROM_EDX
9509 +#endif
9510 +
9511 movl PT_GS(%esp), %edi # get the function address
9512 movl PT_ORIG_EAX(%esp), %edx # get the error code
9513 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
9514 REG_TO_PTGS %ecx
9515 SET_KERNEL_GS %ecx
9516 - movl $(__USER_DS), %ecx
9517 + movl $(__KERNEL_DS), %ecx
9518 movl %ecx, %ds
9519 movl %ecx, %es
9520 TRACE_IRQS_OFF
9521 @@ -1351,6 +1429,13 @@ nmi_stack_correct:
9522 xorl %edx,%edx # zero error code
9523 movl %esp,%eax # pt_regs pointer
9524 call do_nmi
9525 +
9526 +#ifdef CONFIG_PAX_KERNEXEC
9527 + GET_CR0_INTO_EDX
9528 + xorl %esi, %edx
9529 + SET_CR0_FROM_EDX
9530 +#endif
9531 +
9532 jmp restore_all_notrace
9533 CFI_ENDPROC
9534
9535 @@ -1391,6 +1476,13 @@ nmi_espfix_stack:
9536 FIXUP_ESPFIX_STACK # %eax == %esp
9537 xorl %edx,%edx # zero error code
9538 call do_nmi
9539 +
9540 +#ifdef CONFIG_PAX_KERNEXEC
9541 + GET_CR0_INTO_EDX
9542 + xorl %esi, %edx
9543 + SET_CR0_FROM_EDX
9544 +#endif
9545 +
9546 RESTORE_REGS
9547 lss 12+4(%esp), %esp # back to espfix stack
9548 CFI_ADJUST_CFA_OFFSET -24
9549 diff -urNp linux-2.6.31.1/arch/x86/kernel/entry_64.S linux-2.6.31.1/arch/x86/kernel/entry_64.S
9550 --- linux-2.6.31.1/arch/x86/kernel/entry_64.S 2009-09-24 11:45:25.000000000 -0400
9551 +++ linux-2.6.31.1/arch/x86/kernel/entry_64.S 2009-10-01 20:12:42.000000000 -0400
9552 @@ -1074,7 +1074,12 @@ ENTRY(\sym)
9553 TRACE_IRQS_OFF
9554 movq %rsp,%rdi /* pt_regs pointer */
9555 xorl %esi,%esi /* no error code */
9556 - PER_CPU(init_tss, %rbp)
9557 +#ifdef CONFIG_SMP
9558 + imul $TSS_size, PER_CPU_VAR(cpu_number), %ebp
9559 + lea init_tss(%rbp), %rbp
9560 +#else
9561 + lea init_tss(%rip), %rbp
9562 +#endif
9563 subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
9564 call \do_sym
9565 addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
9566 diff -urNp linux-2.6.31.1/arch/x86/kernel/ftrace.c linux-2.6.31.1/arch/x86/kernel/ftrace.c
9567 --- linux-2.6.31.1/arch/x86/kernel/ftrace.c 2009-09-24 11:45:25.000000000 -0400
9568 +++ linux-2.6.31.1/arch/x86/kernel/ftrace.c 2009-10-01 20:12:42.000000000 -0400
9569 @@ -284,9 +284,9 @@ int ftrace_update_ftrace_func(ftrace_fun
9570 unsigned char old[MCOUNT_INSN_SIZE], *new;
9571 int ret;
9572
9573 - memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
9574 + memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
9575 new = ftrace_call_replace(ip, (unsigned long)func);
9576 - ret = ftrace_modify_code(ip, old, new);
9577 + ret = ftrace_modify_code(ktla_ktva(ip), old, new);
9578
9579 return ret;
9580 }
9581 diff -urNp linux-2.6.31.1/arch/x86/kernel/head32.c linux-2.6.31.1/arch/x86/kernel/head32.c
9582 --- linux-2.6.31.1/arch/x86/kernel/head32.c 2009-09-24 11:45:25.000000000 -0400
9583 +++ linux-2.6.31.1/arch/x86/kernel/head32.c 2009-10-01 20:12:42.000000000 -0400
9584 @@ -13,12 +13,13 @@
9585 #include <asm/e820.h>
9586 #include <asm/bios_ebda.h>
9587 #include <asm/trampoline.h>
9588 +#include <asm/boot.h>
9589
9590 void __init i386_start_kernel(void)
9591 {
9592 reserve_trampoline_memory();
9593
9594 - reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
9595 + reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&__bss_stop), "TEXT DATA BSS");
9596
9597 #ifdef CONFIG_BLK_DEV_INITRD
9598 /* Reserve INITRD */
9599 diff -urNp linux-2.6.31.1/arch/x86/kernel/head_32.S linux-2.6.31.1/arch/x86/kernel/head_32.S
9600 --- linux-2.6.31.1/arch/x86/kernel/head_32.S 2009-09-24 11:45:25.000000000 -0400
9601 +++ linux-2.6.31.1/arch/x86/kernel/head_32.S 2009-10-01 20:12:42.000000000 -0400
9602 @@ -19,6 +19,7 @@
9603 #include <asm/setup.h>
9604 #include <asm/processor-flags.h>
9605 #include <asm/percpu.h>
9606 +#include <asm/msr-index.h>
9607
9608 /* Physical address */
9609 #define pa(X) ((X) - __PAGE_OFFSET)
9610 @@ -52,11 +53,7 @@
9611 * and small than max_low_pfn, otherwise will waste some page table entries
9612 */
9613
9614 -#if PTRS_PER_PMD > 1
9615 -#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
9616 -#else
9617 -#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
9618 -#endif
9619 +#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PTE)
9620
9621 /* Enough space to fit pagetables for the low memory linear map */
9622 MAPPING_BEYOND_END = \
9623 @@ -73,6 +70,12 @@ INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_P
9624 RESERVE_BRK(pagetables, INIT_MAP_SIZE)
9625
9626 /*
9627 + * Real beginning of normal "text" segment
9628 + */
9629 +ENTRY(stext)
9630 +ENTRY(_stext)
9631 +
9632 +/*
9633 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
9634 * %esi points to the real-mode code as a 32-bit pointer.
9635 * CS and DS must be 4 GB flat segments, but we don't depend on
9636 @@ -80,6 +83,13 @@ RESERVE_BRK(pagetables, INIT_MAP_SIZE)
9637 * can.
9638 */
9639 .section .text.head,"ax",@progbits
9640 +
9641 +#ifdef CONFIG_PAX_KERNEXEC
9642 + jmp startup_32
9643 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
9644 +.fill PAGE_SIZE-5,1,0xcc
9645 +#endif
9646 +
9647 ENTRY(startup_32)
9648 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
9649 us to not reload segments */
9650 @@ -97,6 +107,48 @@ ENTRY(startup_32)
9651 movl %eax,%gs
9652 2:
9653
9654 +#ifdef CONFIG_SMP
9655 + movl $pa(cpu_gdt_table),%edi
9656 + movl $__per_cpu_load,%eax
9657 + movw %ax,__KERNEL_PERCPU + 2(%edi)
9658 + rorl $16,%eax
9659 + movb %al,__KERNEL_PERCPU + 4(%edi)
9660 + movb %ah,__KERNEL_PERCPU + 7(%edi)
9661 + movl $__per_cpu_end - 1,%eax
9662 + subl $__per_cpu_load,%eax
9663 + movw %ax,__KERNEL_PERCPU + 0(%edi)
9664 +#endif
9665 +
9666 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9667 + movl $NR_CPUS,%ecx
9668 + movl $pa(cpu_gdt_table),%edi
9669 +1:
9670 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
9671 + addl $PAGE_SIZE_asm,%edi
9672 + loop 1b
9673 +#endif
9674 +
9675 +#ifdef CONFIG_PAX_KERNEXEC
9676 + movl $pa(boot_gdt),%edi
9677 + movl $__LOAD_PHYSICAL_ADDR + __PAGE_OFFSET,%eax
9678 + movw %ax,__BOOT_CS + 2(%edi)
9679 + rorl $16,%eax
9680 + movb %al,__BOOT_CS + 4(%edi)
9681 + movb %ah,__BOOT_CS + 7(%edi)
9682 + rorl $16,%eax
9683 +
9684 + movl $NR_CPUS,%ecx
9685 + movl $pa(cpu_gdt_table),%edi
9686 +1:
9687 + movw %ax,__KERNEL_CS + 2(%edi)
9688 + rorl $16,%eax
9689 + movb %al,__KERNEL_CS + 4(%edi)
9690 + movb %ah,__KERNEL_CS + 7(%edi)
9691 + rorl $16,%eax
9692 + addl $PAGE_SIZE_asm,%edi
9693 + loop 1b
9694 +#endif
9695 +
9696 /*
9697 * Clear BSS first so that there are no surprises...
9698 */
9699 @@ -140,9 +192,7 @@ ENTRY(startup_32)
9700 cmpl $num_subarch_entries, %eax
9701 jae bad_subarch
9702
9703 - movl pa(subarch_entries)(,%eax,4), %eax
9704 - subl $__PAGE_OFFSET, %eax
9705 - jmp *%eax
9706 + jmp *pa(subarch_entries)(,%eax,4)
9707
9708 bad_subarch:
9709 WEAK(lguest_entry)
9710 @@ -154,9 +204,9 @@ WEAK(xen_entry)
9711 __INITDATA
9712
9713 subarch_entries:
9714 - .long default_entry /* normal x86/PC */
9715 - .long lguest_entry /* lguest hypervisor */
9716 - .long xen_entry /* Xen hypervisor */
9717 + .long pa(default_entry) /* normal x86/PC */
9718 + .long pa(lguest_entry) /* lguest hypervisor */
9719 + .long pa(xen_entry) /* Xen hypervisor */
9720 num_subarch_entries = (. - subarch_entries) / 4
9721 .previous
9722 #endif /* CONFIG_PARAVIRT */
9723 @@ -217,8 +267,11 @@ default_entry:
9724 movl %eax, pa(max_pfn_mapped)
9725
9726 /* Do early initialization of the fixmap area */
9727 - movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
9728 - movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
9729 +#ifdef CONFIG_COMPAT_VDSO
9730 + movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR+_PAGE_USER,pa(swapper_pg_pmd+0x1000*KPMDS-8)
9731 +#else
9732 + movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
9733 +#endif
9734 #else /* Not PAE */
9735
9736 page_pde_offset = (__PAGE_OFFSET >> 20);
9737 @@ -248,8 +301,11 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
9738 movl %eax, pa(max_pfn_mapped)
9739
9740 /* Do early initialization of the fixmap area */
9741 - movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
9742 - movl %eax,pa(swapper_pg_dir+0xffc)
9743 +#ifdef CONFIG_COMPAT_VDSO
9744 + movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR+_PAGE_USER,pa(swapper_pg_dir+0xffc)
9745 +#else
9746 + movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,pa(swapper_pg_dir+0xffc)
9747 +#endif
9748 #endif
9749 jmp 3f
9750 /*
9751 @@ -296,6 +352,7 @@ ENTRY(startup_32_smp)
9752 orl %edx,%eax
9753 movl %eax,%cr4
9754
9755 +#ifdef CONFIG_X86_PAE
9756 btl $5, %eax # check if PAE is enabled
9757 jnc 6f
9758
9759 @@ -311,13 +368,16 @@ ENTRY(startup_32_smp)
9760 jnc 6f
9761
9762 /* Setup EFER (Extended Feature Enable Register) */
9763 - movl $0xc0000080, %ecx
9764 + movl $MSR_EFER, %ecx
9765 rdmsr
9766
9767 btsl $11, %eax
9768 /* Make changes effective */
9769 wrmsr
9770
9771 + btsl $_PAGE_BIT_NX-32,pa(__supported_pte_mask+4)
9772 + movl $1,pa(nx_enabled)
9773 +#endif
9774 6:
9775
9776 /*
9777 @@ -343,9 +403,7 @@ ENTRY(startup_32_smp)
9778
9779 #ifdef CONFIG_SMP
9780 cmpb $0, ready
9781 - jz 1f /* Initial CPU cleans BSS */
9782 - jmp checkCPUtype
9783 -1:
9784 + jnz checkCPUtype /* Initial CPU cleans BSS */
9785 #endif /* CONFIG_SMP */
9786
9787 /*
9788 @@ -423,7 +481,7 @@ is386: movl $2,%ecx # set MP
9789 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
9790 movl %eax,%ss # after changing gdt.
9791
9792 - movl $(__USER_DS),%eax # DS/ES contains default USER segment
9793 +# movl $(__KERNEL_DS),%eax # DS/ES contains default KERNEL segment
9794 movl %eax,%ds
9795 movl %eax,%es
9796
9797 @@ -437,8 +495,11 @@ is386: movl $2,%ecx # set MP
9798 */
9799 cmpb $0,ready
9800 jne 1f
9801 - movl $per_cpu__gdt_page,%eax
9802 + movl $cpu_gdt_table,%eax
9803 movl $per_cpu__stack_canary,%ecx
9804 +#ifdef CONFIG_SMP
9805 + addl $__per_cpu_load,%ecx
9806 +#endif
9807 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
9808 shrl $16, %ecx
9809 movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
9810 @@ -456,10 +517,6 @@ is386: movl $2,%ecx # set MP
9811 #ifdef CONFIG_SMP
9812 movb ready, %cl
9813 movb $1, ready
9814 - cmpb $0,%cl # the first CPU calls start_kernel
9815 - je 1f
9816 - movl (stack_start), %esp
9817 -1:
9818 #endif /* CONFIG_SMP */
9819 jmp *(initial_code)
9820
9821 @@ -545,22 +602,22 @@ early_page_fault:
9822 jmp early_fault
9823
9824 early_fault:
9825 - cld
9826 #ifdef CONFIG_PRINTK
9827 + cmpl $1,%ss:early_recursion_flag
9828 + je hlt_loop
9829 + incl %ss:early_recursion_flag
9830 + cld
9831 pusha
9832 movl $(__KERNEL_DS),%eax
9833 movl %eax,%ds
9834 movl %eax,%es
9835 - cmpl $2,early_recursion_flag
9836 - je hlt_loop
9837 - incl early_recursion_flag
9838 movl %cr2,%eax
9839 pushl %eax
9840 pushl %edx /* trapno */
9841 pushl $fault_msg
9842 call printk
9843 +; call dump_stack
9844 #endif
9845 - call dump_stack
9846 hlt_loop:
9847 hlt
9848 jmp hlt_loop
9849 @@ -568,8 +625,11 @@ hlt_loop:
9850 /* This is the default interrupt "handler" :-) */
9851 ALIGN
9852 ignore_int:
9853 - cld
9854 #ifdef CONFIG_PRINTK
9855 + cmpl $2,%ss:early_recursion_flag
9856 + je hlt_loop
9857 + incl %ss:early_recursion_flag
9858 + cld
9859 pushl %eax
9860 pushl %ecx
9861 pushl %edx
9862 @@ -578,9 +638,6 @@ ignore_int:
9863 movl $(__KERNEL_DS),%eax
9864 movl %eax,%ds
9865 movl %eax,%es
9866 - cmpl $2,early_recursion_flag
9867 - je hlt_loop
9868 - incl early_recursion_flag
9869 pushl 16(%esp)
9870 pushl 24(%esp)
9871 pushl 32(%esp)
9872 @@ -607,27 +664,37 @@ ENTRY(initial_code)
9873 /*
9874 * BSS section
9875 */
9876 -.section ".bss.page_aligned","wa"
9877 - .align PAGE_SIZE_asm
9878 #ifdef CONFIG_X86_PAE
9879 +.section .swapper_pg_pmd,"a",@progbits
9880 swapper_pg_pmd:
9881 .fill 1024*KPMDS,4,0
9882 #else
9883 +.section .swapper_pg_dir,"a",@progbits
9884 ENTRY(swapper_pg_dir)
9885 .fill 1024,4,0
9886 #endif
9887 +
9888 swapper_pg_fixmap:
9889 .fill 1024,4,0
9890 +
9891 +.section .empty_zero_page,"a",@progbits
9892 ENTRY(empty_zero_page)
9893 .fill 4096,1,0
9894
9895 /*
9896 + * The IDT has to be page-aligned to simplify the Pentium
9897 + * F0 0F bug workaround.. We have a special link segment
9898 + * for this.
9899 + */
9900 +.section .idt,"a",@progbits
9901 +ENTRY(idt_table)
9902 + .fill 256,8,0
9903 +
9904 +/*
9905 * This starts the data section.
9906 */
9907 #ifdef CONFIG_X86_PAE
9908 -.section ".data.page_aligned","wa"
9909 - /* Page-aligned for the benefit of paravirt? */
9910 - .align PAGE_SIZE_asm
9911 +.section .swapper_pg_dir,"a",@progbits
9912 ENTRY(swapper_pg_dir)
9913 .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */
9914 # if KPMDS == 3
9915 @@ -650,11 +717,12 @@ ENTRY(swapper_pg_dir)
9916
9917 .data
9918 ENTRY(stack_start)
9919 - .long init_thread_union+THREAD_SIZE
9920 + .long init_thread_union+THREAD_SIZE-8
9921 .long __BOOT_DS
9922
9923 ready: .byte 0
9924
9925 +.section .rodata,"a",@progbits
9926 early_recursion_flag:
9927 .long 0
9928
9929 @@ -690,7 +758,7 @@ fault_msg:
9930 .word 0 # 32 bit align gdt_desc.address
9931 boot_gdt_descr:
9932 .word __BOOT_DS+7
9933 - .long boot_gdt - __PAGE_OFFSET
9934 + .long pa(boot_gdt)
9935
9936 .word 0 # 32-bit align idt_desc.address
9937 idt_descr:
9938 @@ -701,7 +769,7 @@ idt_descr:
9939 .word 0 # 32 bit align gdt_desc.address
9940 ENTRY(early_gdt_descr)
9941 .word GDT_ENTRIES*8-1
9942 - .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
9943 + .long cpu_gdt_table /* Overwritten for secondary CPUs */
9944
9945 /*
9946 * The boot_gdt must mirror the equivalent in setup.S and is
9947 @@ -710,5 +778,59 @@ ENTRY(early_gdt_descr)
9948 .align L1_CACHE_BYTES
9949 ENTRY(boot_gdt)
9950 .fill GDT_ENTRY_BOOT_CS,8,0
9951 - .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
9952 - .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
9953 + .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
9954 + .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
9955 +
9956 + .align PAGE_SIZE_asm
9957 +ENTRY(cpu_gdt_table)
9958 + .rept NR_CPUS
9959 + .quad 0x0000000000000000 /* NULL descriptor */
9960 + .quad 0x0000000000000000 /* 0x0b reserved */
9961 + .quad 0x0000000000000000 /* 0x13 reserved */
9962 + .quad 0x0000000000000000 /* 0x1b reserved */
9963 + .quad 0x0000000000000000 /* 0x20 unused */
9964 + .quad 0x0000000000000000 /* 0x28 unused */
9965 + .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
9966 + .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
9967 + .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
9968 + .quad 0x0000000000000000 /* 0x4b reserved */
9969 + .quad 0x0000000000000000 /* 0x53 reserved */
9970 + .quad 0x0000000000000000 /* 0x5b reserved */
9971 +
9972 + .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
9973 + .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
9974 + .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
9975 + .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
9976 +
9977 + .quad 0x0000000000000000 /* 0x80 TSS descriptor */
9978 + .quad 0x0000000000000000 /* 0x88 LDT descriptor */
9979 +
9980 + /*
9981 + * Segments used for calling PnP BIOS have byte granularity.
9982 + * The code segments and data segments have fixed 64k limits,
9983 + * the transfer segment sizes are set at run time.
9984 + */
9985 + .quad 0x00409b000000ffff /* 0x90 32-bit code */
9986 + .quad 0x00009b000000ffff /* 0x98 16-bit code */
9987 + .quad 0x000093000000ffff /* 0xa0 16-bit data */
9988 + .quad 0x0000930000000000 /* 0xa8 16-bit data */
9989 + .quad 0x0000930000000000 /* 0xb0 16-bit data */
9990 +
9991 + /*
9992 + * The APM segments have byte granularity and their bases
9993 + * are set at run time. All have 64k limits.
9994 + */
9995 + .quad 0x00409b000000ffff /* 0xb8 APM CS code */
9996 + .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
9997 + .quad 0x004093000000ffff /* 0xc8 APM DS data */
9998 +
9999 + .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
10000 + .quad 0x0040930000000000 /* 0xd8 - PERCPU */
10001 + .quad 0x0040930000000018 /* 0xe0 - STACK_CANARY */
10002 + .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_CS */
10003 + .quad 0x0000000000000000 /* 0xf0 - PCIBIOS_DS */
10004 + .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
10005 +
10006 + /* Be sure this is zeroed to avoid false validations in Xen */
10007 + .fill PAGE_SIZE_asm - GDT_SIZE,1,0
10008 + .endr
10009 diff -urNp linux-2.6.31.1/arch/x86/kernel/head_64.S linux-2.6.31.1/arch/x86/kernel/head_64.S
10010 --- linux-2.6.31.1/arch/x86/kernel/head_64.S 2009-09-24 11:45:25.000000000 -0400
10011 +++ linux-2.6.31.1/arch/x86/kernel/head_64.S 2009-10-01 20:12:42.000000000 -0400
10012 @@ -38,6 +38,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
10013 L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
10014 L4_START_KERNEL = pgd_index(__START_KERNEL_map)
10015 L3_START_KERNEL = pud_index(__START_KERNEL_map)
10016 +L4_VMALLOC_START = pgd_index(VMALLOC_START)
10017 +L3_VMALLOC_START = pud_index(VMALLOC_START)
10018 +L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
10019 +L3_VMEMMAP_START = pud_index(VMEMMAP_START)
10020
10021 .text
10022 .section .text.head
10023 @@ -85,35 +89,22 @@ startup_64:
10024 */
10025 addq %rbp, init_level4_pgt + 0(%rip)
10026 addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
10027 + addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
10028 + addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
10029 addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
10030
10031 addq %rbp, level3_ident_pgt + 0(%rip)
10032 + addq %rbp, level3_ident_pgt + 8(%rip)
10033 + addq %rbp, level3_ident_pgt + 16(%rip)
10034 + addq %rbp, level3_ident_pgt + 24(%rip)
10035
10036 - addq %rbp, level3_kernel_pgt + (510*8)(%rip)
10037 - addq %rbp, level3_kernel_pgt + (511*8)(%rip)
10038 + addq %rbp, level3_vmemmap_pgt + (L3_VMEMMAP_START*8)(%rip)
10039
10040 - addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
10041 + addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
10042 + addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
10043
10044 - /* Add an Identity mapping if I am above 1G */
10045 - leaq _text(%rip), %rdi
10046 - andq $PMD_PAGE_MASK, %rdi
10047 -
10048 - movq %rdi, %rax
10049 - shrq $PUD_SHIFT, %rax
10050 - andq $(PTRS_PER_PUD - 1), %rax
10051 - jz ident_complete
10052 -
10053 - leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx
10054 - leaq level3_ident_pgt(%rip), %rbx
10055 - movq %rdx, 0(%rbx, %rax, 8)
10056 -
10057 - movq %rdi, %rax
10058 - shrq $PMD_SHIFT, %rax
10059 - andq $(PTRS_PER_PMD - 1), %rax
10060 - leaq __PAGE_KERNEL_IDENT_LARGE_EXEC(%rdi), %rdx
10061 - leaq level2_spare_pgt(%rip), %rbx
10062 - movq %rdx, 0(%rbx, %rax, 8)
10063 -ident_complete:
10064 + addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
10065 + addq %rbp, level2_fixmap_pgt + (507*8)(%rip)
10066
10067 /*
10068 * Fixup the kernel text+data virtual addresses. Note that
10069 @@ -187,6 +178,10 @@ ENTRY(secondary_startup_64)
10070 btl $20,%edi /* No Execute supported? */
10071 jnc 1f
10072 btsl $_EFER_NX, %eax
10073 + leaq init_level4_pgt(%rip), %rdi
10074 + btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
10075 + btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
10076 + btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
10077 1: wrmsr /* Make changes effective */
10078
10079 /* Setup cr0 */
10080 @@ -262,16 +257,16 @@ ENTRY(secondary_startup_64)
10081 .quad x86_64_start_kernel
10082 ENTRY(initial_gs)
10083 .quad INIT_PER_CPU_VAR(irq_stack_union)
10084 - __FINITDATA
10085
10086 ENTRY(stack_start)
10087 .quad init_thread_union+THREAD_SIZE-8
10088 .word 0
10089 + __FINITDATA
10090
10091 bad_address:
10092 jmp bad_address
10093
10094 - .section ".init.text","ax"
10095 + __INIT
10096 #ifdef CONFIG_EARLY_PRINTK
10097 .globl early_idt_handlers
10098 early_idt_handlers:
10099 @@ -316,18 +311,23 @@ ENTRY(early_idt_handler)
10100 #endif /* EARLY_PRINTK */
10101 1: hlt
10102 jmp 1b
10103 + .previous
10104
10105 #ifdef CONFIG_EARLY_PRINTK
10106 + __INITDATA
10107 early_recursion_flag:
10108 .long 0
10109 + .previous
10110
10111 + .section .rodata,"a",@progbits
10112 early_idt_msg:
10113 .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
10114 early_idt_ripmsg:
10115 .asciz "RIP %s\n"
10116 -#endif /* CONFIG_EARLY_PRINTK */
10117 .previous
10118 +#endif /* CONFIG_EARLY_PRINTK */
10119
10120 + .section .rodata,"a",@progbits
10121 #define NEXT_PAGE(name) \
10122 .balign PAGE_SIZE; \
10123 ENTRY(name)
10124 @@ -350,13 +350,31 @@ NEXT_PAGE(init_level4_pgt)
10125 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
10126 .org init_level4_pgt + L4_PAGE_OFFSET*8, 0
10127 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
10128 + .org init_level4_pgt + L4_VMALLOC_START*8, 0
10129 + .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
10130 + .org init_level4_pgt + L4_VMEMMAP_START*8, 0
10131 + .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
10132 .org init_level4_pgt + L4_START_KERNEL*8, 0
10133 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
10134 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
10135
10136 NEXT_PAGE(level3_ident_pgt)
10137 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
10138 +#ifdef CONFIG_XEN
10139 .fill 511,8,0
10140 +#else
10141 + .quad level2_ident_pgt + PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
10142 + .quad level2_ident_pgt + 2*PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
10143 + .quad level2_ident_pgt + 3*PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
10144 + .fill 508,8,0
10145 +#endif
10146 +
10147 +NEXT_PAGE(level3_vmalloc_pgt)
10148 + .fill 512,8,0
10149 +
10150 +NEXT_PAGE(level3_vmemmap_pgt)
10151 + .fill L3_VMEMMAP_START,8,0
10152 + .quad level2_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
10153
10154 NEXT_PAGE(level3_kernel_pgt)
10155 .fill L3_START_KERNEL,8,0
10156 @@ -364,20 +382,23 @@ NEXT_PAGE(level3_kernel_pgt)
10157 .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
10158 .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
10159
10160 +NEXT_PAGE(level2_vmemmap_pgt)
10161 + .fill 512,8,0
10162 +
10163 NEXT_PAGE(level2_fixmap_pgt)
10164 - .fill 506,8,0
10165 - .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
10166 - /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
10167 - .fill 5,8,0
10168 + .fill 507,8,0
10169 + .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
10170 + /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
10171 + .fill 4,8,0
10172
10173 -NEXT_PAGE(level1_fixmap_pgt)
10174 +NEXT_PAGE(level1_vsyscall_pgt)
10175 .fill 512,8,0
10176
10177 -NEXT_PAGE(level2_ident_pgt)
10178 - /* Since I easily can, map the first 1G.
10179 + /* Since I easily can, map the first 4G.
10180 * Don't set NX because code runs from these pages.
10181 */
10182 - PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
10183 +NEXT_PAGE(level2_ident_pgt)
10184 + PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, 4*PTRS_PER_PMD)
10185
10186 NEXT_PAGE(level2_kernel_pgt)
10187 /*
10188 @@ -390,33 +411,49 @@ NEXT_PAGE(level2_kernel_pgt)
10189 * If you want to increase this then increase MODULES_VADDR
10190 * too.)
10191 */
10192 - PMDS(0, __PAGE_KERNEL_LARGE_EXEC,
10193 - KERNEL_IMAGE_SIZE/PMD_SIZE)
10194 -
10195 -NEXT_PAGE(level2_spare_pgt)
10196 - .fill 512, 8, 0
10197 + PMDS(0, __PAGE_KERNEL_LARGE_EXEC, KERNEL_IMAGE_SIZE/PMD_SIZE)
10198
10199 #undef PMDS
10200 #undef NEXT_PAGE
10201
10202 - .data
10203 + .align PAGE_SIZE
10204 +ENTRY(cpu_gdt_table)
10205 + .rept NR_CPUS
10206 + .quad 0x0000000000000000 /* NULL descriptor */
10207 + .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
10208 + .quad 0x00af9b000000ffff /* __KERNEL_CS */
10209 + .quad 0x00cf93000000ffff /* __KERNEL_DS */
10210 + .quad 0x00cffb000000ffff /* __USER32_CS */
10211 + .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
10212 + .quad 0x00affb000000ffff /* __USER_CS */
10213 + .quad 0x0 /* unused */
10214 + .quad 0,0 /* TSS */
10215 + .quad 0,0 /* LDT */
10216 + .quad 0,0,0 /* three TLS descriptors */
10217 + .quad 0x0000f40000000000 /* node/CPU stored in limit */
10218 + /* asm/segment.h:GDT_ENTRIES must match this */
10219 +
10220 + /* zero the remaining page */
10221 + .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
10222 + .endr
10223 +
10224 .align 16
10225 .globl early_gdt_descr
10226 early_gdt_descr:
10227 .word GDT_ENTRIES*8-1
10228 early_gdt_descr_base:
10229 - .quad INIT_PER_CPU_VAR(gdt_page)
10230 + .quad cpu_gdt_table
10231
10232 ENTRY(phys_base)
10233 /* This must match the first entry in level2_kernel_pgt */
10234 .quad 0x0000000000000000
10235
10236 #include "../../x86/xen/xen-head.S"
10237 -
10238 - .section .bss, "aw", @nobits
10239 +
10240 + .section .rodata,"a",@progbits
10241 .align L1_CACHE_BYTES
10242 ENTRY(idt_table)
10243 - .skip IDT_ENTRIES * 16
10244 + .fill 512,8,0
10245
10246 .section .bss.page_aligned, "aw", @nobits
10247 .align PAGE_SIZE
10248 diff -urNp linux-2.6.31.1/arch/x86/kernel/i386_ksyms_32.c linux-2.6.31.1/arch/x86/kernel/i386_ksyms_32.c
10249 --- linux-2.6.31.1/arch/x86/kernel/i386_ksyms_32.c 2009-09-24 11:45:25.000000000 -0400
10250 +++ linux-2.6.31.1/arch/x86/kernel/i386_ksyms_32.c 2009-10-01 20:12:42.000000000 -0400
10251 @@ -10,8 +10,12 @@
10252 EXPORT_SYMBOL(mcount);
10253 #endif
10254
10255 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
10256 +
10257 /* Networking helper routines. */
10258 EXPORT_SYMBOL(csum_partial_copy_generic);
10259 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
10260 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
10261
10262 EXPORT_SYMBOL(__get_user_1);
10263 EXPORT_SYMBOL(__get_user_2);
10264 @@ -26,3 +30,7 @@ EXPORT_SYMBOL(strstr);
10265
10266 EXPORT_SYMBOL(csum_partial);
10267 EXPORT_SYMBOL(empty_zero_page);
10268 +
10269 +#ifdef CONFIG_PAX_KERNEXEC
10270 +EXPORT_SYMBOL(__LOAD_PHYSICAL_ADDR);
10271 +#endif
10272 diff -urNp linux-2.6.31.1/arch/x86/kernel/init_task.c linux-2.6.31.1/arch/x86/kernel/init_task.c
10273 --- linux-2.6.31.1/arch/x86/kernel/init_task.c 2009-09-24 11:45:25.000000000 -0400
10274 +++ linux-2.6.31.1/arch/x86/kernel/init_task.c 2009-10-01 20:12:42.000000000 -0400
10275 @@ -39,5 +39,5 @@ EXPORT_SYMBOL(init_task);
10276 * section. Since TSS's are completely CPU-local, we want them
10277 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
10278 */
10279 -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
10280 -
10281 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
10282 +EXPORT_SYMBOL(init_tss);
10283 diff -urNp linux-2.6.31.1/arch/x86/kernel/ioport.c linux-2.6.31.1/arch/x86/kernel/ioport.c
10284 --- linux-2.6.31.1/arch/x86/kernel/ioport.c 2009-09-24 11:45:25.000000000 -0400
10285 +++ linux-2.6.31.1/arch/x86/kernel/ioport.c 2009-10-01 20:12:42.000000000 -0400
10286 @@ -6,6 +6,7 @@
10287 #include <linux/sched.h>
10288 #include <linux/kernel.h>
10289 #include <linux/capability.h>
10290 +#include <linux/security.h>
10291 #include <linux/errno.h>
10292 #include <linux/types.h>
10293 #include <linux/ioport.h>
10294 @@ -41,6 +42,12 @@ asmlinkage long sys_ioperm(unsigned long
10295
10296 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
10297 return -EINVAL;
10298 +#ifdef CONFIG_GRKERNSEC_IO
10299 + if (turn_on) {
10300 + gr_handle_ioperm();
10301 + return -EPERM;
10302 + }
10303 +#endif
10304 if (turn_on && !capable(CAP_SYS_RAWIO))
10305 return -EPERM;
10306
10307 @@ -67,7 +74,7 @@ asmlinkage long sys_ioperm(unsigned long
10308 * because the ->io_bitmap_max value must match the bitmap
10309 * contents:
10310 */
10311 - tss = &per_cpu(init_tss, get_cpu());
10312 + tss = init_tss + get_cpu();
10313
10314 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
10315
10316 @@ -111,8 +118,13 @@ static int do_iopl(unsigned int level, s
10317 return -EINVAL;
10318 /* Trying to gain more privileges? */
10319 if (level > old) {
10320 +#ifdef CONFIG_GRKERNSEC_IO
10321 + gr_handle_iopl();
10322 + return -EPERM;
10323 +#else
10324 if (!capable(CAP_SYS_RAWIO))
10325 return -EPERM;
10326 +#endif
10327 }
10328 regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
10329
10330 diff -urNp linux-2.6.31.1/arch/x86/kernel/irq_32.c linux-2.6.31.1/arch/x86/kernel/irq_32.c
10331 --- linux-2.6.31.1/arch/x86/kernel/irq_32.c 2009-09-24 11:45:25.000000000 -0400
10332 +++ linux-2.6.31.1/arch/x86/kernel/irq_32.c 2009-10-01 20:12:42.000000000 -0400
10333 @@ -94,7 +94,7 @@ execute_on_irq_stack(int overflow, struc
10334 return 0;
10335
10336 /* build the stack frame on the IRQ stack */
10337 - isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
10338 + isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
10339 irqctx->tinfo.task = curctx->tinfo.task;
10340 irqctx->tinfo.previous_esp = current_stack_pointer;
10341
10342 @@ -175,7 +175,7 @@ asmlinkage void do_softirq(void)
10343 irqctx->tinfo.previous_esp = current_stack_pointer;
10344
10345 /* build the stack frame on the softirq stack */
10346 - isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
10347 + isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
10348
10349 call_on_stack(__do_softirq, isp);
10350 /*
10351 diff -urNp linux-2.6.31.1/arch/x86/kernel/kprobes.c linux-2.6.31.1/arch/x86/kernel/kprobes.c
10352 --- linux-2.6.31.1/arch/x86/kernel/kprobes.c 2009-09-24 11:45:25.000000000 -0400
10353 +++ linux-2.6.31.1/arch/x86/kernel/kprobes.c 2009-10-01 20:12:42.000000000 -0400
10354 @@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
10355 char op;
10356 s32 raddr;
10357 } __attribute__((packed)) * jop;
10358 - jop = (struct __arch_jmp_op *)from;
10359 +
10360 +#ifdef CONFIG_PAX_KERNEXEC
10361 + unsigned long cr0;
10362 +#endif
10363 +
10364 + jop = (struct __arch_jmp_op *)(ktla_ktva(from));
10365 +
10366 +#ifdef CONFIG_PAX_KERNEXEC
10367 + pax_open_kernel(cr0);
10368 +#endif
10369 +
10370 jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
10371 jop->op = RELATIVEJUMP_INSTRUCTION;
10372 +
10373 +#ifdef CONFIG_PAX_KERNEXEC
10374 + pax_close_kernel(cr0);
10375 +#endif
10376 +
10377 }
10378
10379 /*
10380 @@ -345,16 +360,29 @@ static void __kprobes fix_riprel(struct
10381
10382 static void __kprobes arch_copy_kprobe(struct kprobe *p)
10383 {
10384 - memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
10385 +
10386 +#ifdef CONFIG_PAX_KERNEXEC
10387 + unsigned long cr0;
10388 +#endif
10389 +
10390 +#ifdef CONFIG_PAX_KERNEXEC
10391 + pax_open_kernel(cr0);
10392 +#endif
10393 +
10394 + memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
10395 +
10396 +#ifdef CONFIG_PAX_KERNEXEC
10397 + pax_close_kernel(cr0);
10398 +#endif
10399
10400 fix_riprel(p);
10401
10402 - if (can_boost(p->addr))
10403 + if (can_boost(ktla_ktva(p->addr)))
10404 p->ainsn.boostable = 0;
10405 else
10406 p->ainsn.boostable = -1;
10407
10408 - p->opcode = *p->addr;
10409 + p->opcode = *(ktla_ktva(p->addr));
10410 }
10411
10412 int __kprobes arch_prepare_kprobe(struct kprobe *p)
10413 @@ -432,7 +460,7 @@ static void __kprobes prepare_singlestep
10414 if (p->opcode == BREAKPOINT_INSTRUCTION)
10415 regs->ip = (unsigned long)p->addr;
10416 else
10417 - regs->ip = (unsigned long)p->ainsn.insn;
10418 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
10419 }
10420
10421 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
10422 @@ -453,7 +481,7 @@ static void __kprobes setup_singlestep(s
10423 if (p->ainsn.boostable == 1 && !p->post_handler) {
10424 /* Boost up -- we can execute copied instructions directly */
10425 reset_current_kprobe();
10426 - regs->ip = (unsigned long)p->ainsn.insn;
10427 + regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
10428 preempt_enable_no_resched();
10429 return;
10430 }
10431 @@ -523,7 +551,7 @@ static int __kprobes kprobe_handler(stru
10432 struct kprobe_ctlblk *kcb;
10433
10434 addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
10435 - if (*addr != BREAKPOINT_INSTRUCTION) {
10436 + if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) {
10437 /*
10438 * The breakpoint instruction was removed right
10439 * after we hit it. Another cpu has removed
10440 @@ -775,7 +803,7 @@ static void __kprobes resume_execution(s
10441 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
10442 {
10443 unsigned long *tos = stack_addr(regs);
10444 - unsigned long copy_ip = (unsigned long)p->ainsn.insn;
10445 + unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
10446 unsigned long orig_ip = (unsigned long)p->addr;
10447 kprobe_opcode_t *insn = p->ainsn.insn;
10448
10449 @@ -958,7 +986,7 @@ int __kprobes kprobe_exceptions_notify(s
10450 struct die_args *args = data;
10451 int ret = NOTIFY_DONE;
10452
10453 - if (args->regs && user_mode_vm(args->regs))
10454 + if (args->regs && user_mode(args->regs))
10455 return ret;
10456
10457 switch (val) {
10458 diff -urNp linux-2.6.31.1/arch/x86/kernel/ldt.c linux-2.6.31.1/arch/x86/kernel/ldt.c
10459 --- linux-2.6.31.1/arch/x86/kernel/ldt.c 2009-09-24 11:45:25.000000000 -0400
10460 +++ linux-2.6.31.1/arch/x86/kernel/ldt.c 2009-10-01 20:12:42.000000000 -0400
10461 @@ -66,13 +66,13 @@ static int alloc_ldt(mm_context_t *pc, i
10462 if (reload) {
10463 #ifdef CONFIG_SMP
10464 preempt_disable();
10465 - load_LDT(pc);
10466 + load_LDT_nolock(pc);
10467 if (!cpus_equal(current->mm->cpu_vm_mask,
10468 cpumask_of_cpu(smp_processor_id())))
10469 smp_call_function(flush_ldt, current->mm, 1);
10470 preempt_enable();
10471 #else
10472 - load_LDT(pc);
10473 + load_LDT_nolock(pc);
10474 #endif
10475 }
10476 if (oldsize) {
10477 @@ -94,7 +94,7 @@ static inline int copy_ldt(mm_context_t
10478 return err;
10479
10480 for (i = 0; i < old->size; i++)
10481 - write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);
10482 + write_ldt_entry(new->ldt, i, old->ldt + i);
10483 return 0;
10484 }
10485
10486 @@ -115,6 +115,24 @@ int init_new_context(struct task_struct
10487 retval = copy_ldt(&mm->context, &old_mm->context);
10488 mutex_unlock(&old_mm->context.lock);
10489 }
10490 +
10491 + if (tsk == current) {
10492 + mm->context.vdso = ~0UL;
10493 +
10494 +#ifdef CONFIG_X86_32
10495 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10496 + mm->context.user_cs_base = 0UL;
10497 + mm->context.user_cs_limit = ~0UL;
10498 +
10499 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
10500 + cpus_clear(mm->context.cpu_user_cs_mask);
10501 +#endif
10502 +
10503 +#endif
10504 +#endif
10505 +
10506 + }
10507 +
10508 return retval;
10509 }
10510
10511 @@ -229,6 +247,13 @@ static int write_ldt(void __user *ptr, u
10512 }
10513 }
10514
10515 +#ifdef CONFIG_PAX_SEGMEXEC
10516 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
10517 + error = -EINVAL;
10518 + goto out_unlock;
10519 + }
10520 +#endif
10521 +
10522 fill_ldt(&ldt, &ldt_info);
10523 if (oldmode)
10524 ldt.avl = 0;
10525 diff -urNp linux-2.6.31.1/arch/x86/kernel/machine_kexec_32.c linux-2.6.31.1/arch/x86/kernel/machine_kexec_32.c
10526 --- linux-2.6.31.1/arch/x86/kernel/machine_kexec_32.c 2009-09-24 11:45:25.000000000 -0400
10527 +++ linux-2.6.31.1/arch/x86/kernel/machine_kexec_32.c 2009-10-01 20:12:42.000000000 -0400
10528 @@ -26,7 +26,7 @@
10529 #include <asm/system.h>
10530 #include <asm/cacheflush.h>
10531
10532 -static void set_idt(void *newidt, __u16 limit)
10533 +static void set_idt(struct desc_struct *newidt, __u16 limit)
10534 {
10535 struct desc_ptr curidt;
10536
10537 @@ -38,7 +38,7 @@ static void set_idt(void *newidt, __u16
10538 }
10539
10540
10541 -static void set_gdt(void *newgdt, __u16 limit)
10542 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
10543 {
10544 struct desc_ptr curgdt;
10545
10546 @@ -217,7 +217,7 @@ void machine_kexec(struct kimage *image)
10547 }
10548
10549 control_page = page_address(image->control_code_page);
10550 - memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
10551 + memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
10552
10553 relocate_kernel_ptr = control_page;
10554 page_list[PA_CONTROL_PAGE] = __pa(control_page);
10555 diff -urNp linux-2.6.31.1/arch/x86/kernel/module.c linux-2.6.31.1/arch/x86/kernel/module.c
10556 --- linux-2.6.31.1/arch/x86/kernel/module.c 2009-09-24 11:45:25.000000000 -0400
10557 +++ linux-2.6.31.1/arch/x86/kernel/module.c 2009-10-01 20:12:42.000000000 -0400
10558 @@ -27,6 +27,7 @@
10559 #include <asm/system.h>
10560 #include <asm/page.h>
10561 #include <asm/pgtable.h>
10562 +#include <asm/desc.h>
10563
10564 #if 0
10565 #define DEBUGP printk
10566 @@ -34,7 +35,7 @@
10567 #define DEBUGP(fmt...)
10568 #endif
10569
10570 -void *module_alloc(unsigned long size)
10571 +static void *__module_alloc(unsigned long size, pgprot_t prot)
10572 {
10573 struct vm_struct *area;
10574
10575 @@ -48,9 +49,92 @@ void *module_alloc(unsigned long size)
10576 if (!area)
10577 return NULL;
10578
10579 - return __vmalloc_area(area, GFP_KERNEL | __GFP_HIGHMEM,
10580 - PAGE_KERNEL_EXEC);
10581 + return __vmalloc_area(area, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, prot);
10582 +}
10583 +
10584 +#ifdef CONFIG_PAX_KERNEXEC
10585 +#ifdef CONFIG_X86_32
10586 +void *module_alloc(unsigned long size)
10587 +{
10588 + return __module_alloc(size, PAGE_KERNEL);
10589 +}
10590 +
10591 +void *module_alloc_exec(unsigned long size)
10592 +{
10593 + struct vm_struct *area;
10594 +
10595 + if (size == 0)
10596 + return NULL;
10597 +
10598 + area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_EXEC_VADDR, (unsigned long)&MODULES_EXEC_END);
10599 + if (area)
10600 + return area->addr;
10601 +
10602 + return NULL;
10603 +}
10604 +EXPORT_SYMBOL(module_alloc_exec);
10605 +
10606 +void module_free_exec(struct module *mod, void *module_region)
10607 +{
10608 + struct vm_struct **p, *tmp;
10609 +
10610 + if (!module_region)
10611 + return;
10612 +
10613 + if ((PAGE_SIZE-1) & (unsigned long)module_region) {
10614 + printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
10615 + WARN_ON(1);
10616 + return;
10617 + }
10618 +
10619 + write_lock(&vmlist_lock);
10620 + for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
10621 + if (tmp->addr == module_region)
10622 + break;
10623 +
10624 + if (tmp) {
10625 + unsigned long cr0;
10626 +
10627 + pax_open_kernel(cr0);
10628 + memset(tmp->addr, 0xCC, tmp->size);
10629 + pax_close_kernel(cr0);
10630 +
10631 + *p = tmp->next;
10632 + kfree(tmp);
10633 + }
10634 + write_unlock(&vmlist_lock);
10635 +
10636 + if (!tmp) {
10637 + printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
10638 + module_region);
10639 + WARN_ON(1);
10640 + }
10641 +}
10642 +EXPORT_SYMBOL(module_free_exec);
10643 +#else
10644 +void *module_alloc(unsigned long size)
10645 +{
10646 + return __module_alloc(size, PAGE_KERNEL);
10647 +}
10648 +
10649 +void module_free_exec(struct module *mod, void *module_region)
10650 +{
10651 + module_free(mod, module_region);
10652 +}
10653 +EXPORT_SYMBOL(module_free_exec);
10654 +
10655 +void *module_alloc_exec(unsigned long size)
10656 +{
10657 + return __module_alloc(size, PAGE_KERNEL_RX);
10658 +}
10659 +EXPORT_SYMBOL(module_alloc_exec);
10660 +#endif
10661 +#else
10662 +void *module_alloc(unsigned long size)
10663 +{
10664 + return __module_alloc(size, PAGE_KERNEL_EXEC);
10665 }
10666 +#endif
10667
10668 /* Free memory returned from module_alloc */
10669 void module_free(struct module *mod, void *module_region)
10670 @@ -77,14 +161,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
10671 unsigned int i;
10672 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
10673 Elf32_Sym *sym;
10674 - uint32_t *location;
10675 + uint32_t *plocation, location;
10676 +
10677 +#ifdef CONFIG_PAX_KERNEXEC
10678 + unsigned long cr0;
10679 +#endif
10680
10681 DEBUGP("Applying relocate section %u to %u\n", relsec,
10682 sechdrs[relsec].sh_info);
10683 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
10684 /* This is where to make the change */
10685 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
10686 - + rel[i].r_offset;
10687 + plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
10688 + location = (uint32_t)plocation;
10689 + if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
10690 + plocation = ktla_ktva((void *)plocation);
10691 /* This is the symbol it is referring to. Note that all
10692 undefined symbols have been resolved. */
10693 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
10694 @@ -93,11 +183,31 @@ int apply_relocate(Elf32_Shdr *sechdrs,
10695 switch (ELF32_R_TYPE(rel[i].r_info)) {
10696 case R_386_32:
10697 /* We add the value into the location given */
10698 - *location += sym->st_value;
10699 +
10700 +#ifdef CONFIG_PAX_KERNEXEC
10701 + pax_open_kernel(cr0);
10702 +#endif
10703 +
10704 + *plocation += sym->st_value;
10705 +
10706 +#ifdef CONFIG_PAX_KERNEXEC
10707 + pax_close_kernel(cr0);
10708 +#endif
10709 +
10710 break;
10711 case R_386_PC32:
10712 /* Add the value, subtract its postition */
10713 - *location += sym->st_value - (uint32_t)location;
10714 +
10715 +#ifdef CONFIG_PAX_KERNEXEC
10716 + pax_open_kernel(cr0);
10717 +#endif
10718 +
10719 + *plocation += sym->st_value - location;
10720 +
10721 +#ifdef CONFIG_PAX_KERNEXEC
10722 + pax_close_kernel(cr0);
10723 +#endif
10724 +
10725 break;
10726 default:
10727 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
10728 @@ -131,6 +241,10 @@ int apply_relocate_add(Elf64_Shdr *sechd
10729 void *loc;
10730 u64 val;
10731
10732 +#ifdef CONFIG_PAX_KERNEXEC
10733 + unsigned long cr0;
10734 +#endif
10735 +
10736 DEBUGP("Applying relocate section %u to %u\n", relsec,
10737 sechdrs[relsec].sh_info);
10738 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
10739 @@ -153,21 +267,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
10740 case R_X86_64_NONE:
10741 break;
10742 case R_X86_64_64:
10743 +
10744 +#ifdef CONFIG_PAX_KERNEXEC
10745 + pax_open_kernel(cr0);
10746 +#endif
10747 +
10748 *(u64 *)loc = val;
10749 +
10750 +#ifdef CONFIG_PAX_KERNEXEC
10751 + pax_close_kernel(cr0);
10752 +#endif
10753 +
10754 break;
10755 case R_X86_64_32:
10756 +
10757 +#ifdef CONFIG_PAX_KERNEXEC
10758 + pax_open_kernel(cr0);
10759 +#endif
10760 +
10761 *(u32 *)loc = val;
10762 +
10763 +#ifdef CONFIG_PAX_KERNEXEC
10764 + pax_close_kernel(cr0);
10765 +#endif
10766 +
10767 if (val != *(u32 *)loc)
10768 goto overflow;
10769 break;
10770 case R_X86_64_32S:
10771 +
10772 +#ifdef CONFIG_PAX_KERNEXEC
10773 + pax_open_kernel(cr0);
10774 +#endif
10775 +
10776 *(s32 *)loc = val;
10777 +
10778 +#ifdef CONFIG_PAX_KERNEXEC
10779 + pax_close_kernel(cr0);
10780 +#endif
10781 +
10782 if ((s64)val != *(s32 *)loc)
10783 goto overflow;
10784 break;
10785 case R_X86_64_PC32:
10786 val -= (u64)loc;
10787 +
10788 +#ifdef CONFIG_PAX_KERNEXEC
10789 + pax_open_kernel(cr0);
10790 +#endif
10791 +
10792 *(u32 *)loc = val;
10793 +
10794 +#ifdef CONFIG_PAX_KERNEXEC
10795 + pax_close_kernel(cr0);
10796 +#endif
10797 +
10798 #if 0
10799 if ((s64)val != *(s32 *)loc)
10800 goto overflow;
10801 diff -urNp linux-2.6.31.1/arch/x86/kernel/paravirt.c linux-2.6.31.1/arch/x86/kernel/paravirt.c
10802 --- linux-2.6.31.1/arch/x86/kernel/paravirt.c 2009-09-24 11:45:25.000000000 -0400
10803 +++ linux-2.6.31.1/arch/x86/kernel/paravirt.c 2009-10-01 20:12:42.000000000 -0400
10804 @@ -54,7 +54,7 @@ u64 _paravirt_ident_64(u64 x)
10805 return x;
10806 }
10807
10808 -static void __init default_banner(void)
10809 +static void default_banner(void)
10810 {
10811 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
10812 pv_info.name);
10813 @@ -125,9 +125,9 @@ unsigned paravirt_patch_jmp(void *insnbu
10814
10815 /* Neat trick to map patch type back to the call within the
10816 * corresponding structure. */
10817 -static void *get_call_destination(u8 type)
10818 +static const void *get_call_destination(u8 type)
10819 {
10820 - struct paravirt_patch_template tmpl = {
10821 + const struct paravirt_patch_template tmpl = {
10822 .pv_init_ops = pv_init_ops,
10823 .pv_time_ops = pv_time_ops,
10824 .pv_cpu_ops = pv_cpu_ops,
10825 @@ -138,13 +138,13 @@ static void *get_call_destination(u8 typ
10826 .pv_lock_ops = pv_lock_ops,
10827 #endif
10828 };
10829 - return *((void **)&tmpl + type);
10830 + return *((const void **)&tmpl + type);
10831 }
10832
10833 unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
10834 unsigned long addr, unsigned len)
10835 {
10836 - void *opfunc = get_call_destination(type);
10837 + const void *opfunc = get_call_destination(type);
10838 unsigned ret;
10839
10840 if (opfunc == NULL)
10841 @@ -183,7 +183,7 @@ unsigned paravirt_patch_insns(void *insn
10842 if (insn_len > len || start == NULL)
10843 insn_len = len;
10844 else
10845 - memcpy(insnbuf, start, insn_len);
10846 + memcpy(insnbuf, ktla_ktva(start), insn_len);
10847
10848 return insn_len;
10849 }
10850 @@ -311,21 +311,21 @@ void arch_flush_lazy_mmu_mode(void)
10851 preempt_enable();
10852 }
10853
10854 -struct pv_info pv_info = {
10855 +struct pv_info pv_info __read_only = {
10856 .name = "bare hardware",
10857 .paravirt_enabled = 0,
10858 .kernel_rpl = 0,
10859 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
10860 };
10861
10862 -struct pv_init_ops pv_init_ops = {
10863 +struct pv_init_ops pv_init_ops __read_only = {
10864 .patch = native_patch,
10865 .banner = default_banner,
10866 .arch_setup = paravirt_nop,
10867 .memory_setup = machine_specific_memory_setup,
10868 };
10869
10870 -struct pv_time_ops pv_time_ops = {
10871 +struct pv_time_ops pv_time_ops __read_only = {
10872 .time_init = hpet_time_init,
10873 .get_wallclock = native_get_wallclock,
10874 .set_wallclock = native_set_wallclock,
10875 @@ -333,7 +333,7 @@ struct pv_time_ops pv_time_ops = {
10876 .get_tsc_khz = native_calibrate_tsc,
10877 };
10878
10879 -struct pv_irq_ops pv_irq_ops = {
10880 +struct pv_irq_ops pv_irq_ops __read_only = {
10881 .init_IRQ = native_init_IRQ,
10882 .save_fl = __PV_IS_CALLEE_SAVE(native_save_fl),
10883 .restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl),
10884 @@ -346,7 +346,7 @@ struct pv_irq_ops pv_irq_ops = {
10885 #endif
10886 };
10887
10888 -struct pv_cpu_ops pv_cpu_ops = {
10889 +struct pv_cpu_ops pv_cpu_ops __read_only = {
10890 .cpuid = native_cpuid,
10891 .get_debugreg = native_get_debugreg,
10892 .set_debugreg = native_set_debugreg,
10893 @@ -406,7 +406,7 @@ struct pv_cpu_ops pv_cpu_ops = {
10894 .end_context_switch = paravirt_nop,
10895 };
10896
10897 -struct pv_apic_ops pv_apic_ops = {
10898 +struct pv_apic_ops pv_apic_ops __read_only = {
10899 #ifdef CONFIG_X86_LOCAL_APIC
10900 .setup_boot_clock = setup_boot_APIC_clock,
10901 .setup_secondary_clock = setup_secondary_APIC_clock,
10902 @@ -422,7 +422,7 @@ struct pv_apic_ops pv_apic_ops = {
10903 #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64)
10904 #endif
10905
10906 -struct pv_mmu_ops pv_mmu_ops = {
10907 +struct pv_mmu_ops pv_mmu_ops __read_only = {
10908 #ifndef CONFIG_X86_64
10909 .pagetable_setup_start = native_pagetable_setup_start,
10910 .pagetable_setup_done = native_pagetable_setup_done,
10911 diff -urNp linux-2.6.31.1/arch/x86/kernel/paravirt-spinlocks.c linux-2.6.31.1/arch/x86/kernel/paravirt-spinlocks.c
10912 --- linux-2.6.31.1/arch/x86/kernel/paravirt-spinlocks.c 2009-09-24 11:45:25.000000000 -0400
10913 +++ linux-2.6.31.1/arch/x86/kernel/paravirt-spinlocks.c 2009-10-01 20:12:42.000000000 -0400
10914 @@ -13,7 +13,7 @@ default_spin_lock_flags(raw_spinlock_t *
10915 __raw_spin_lock(lock);
10916 }
10917
10918 -struct pv_lock_ops pv_lock_ops = {
10919 +struct pv_lock_ops pv_lock_ops __read_only = {
10920 #ifdef CONFIG_SMP
10921 .spin_is_locked = __ticket_spin_is_locked,
10922 .spin_is_contended = __ticket_spin_is_contended,
10923 diff -urNp linux-2.6.31.1/arch/x86/kernel/process_32.c linux-2.6.31.1/arch/x86/kernel/process_32.c
10924 --- linux-2.6.31.1/arch/x86/kernel/process_32.c 2009-09-24 11:45:25.000000000 -0400
10925 +++ linux-2.6.31.1/arch/x86/kernel/process_32.c 2009-10-01 20:12:42.000000000 -0400
10926 @@ -70,6 +70,7 @@ EXPORT_PER_CPU_SYMBOL(current_task);
10927 unsigned long thread_saved_pc(struct task_struct *tsk)
10928 {
10929 return ((unsigned long *)tsk->thread.sp)[3];
10930 +//XXX return tsk->thread.eip;
10931 }
10932
10933 #ifndef CONFIG_SMP
10934 @@ -132,7 +133,7 @@ void __show_regs(struct pt_regs *regs, i
10935 unsigned short ss, gs;
10936 const char *board;
10937
10938 - if (user_mode_vm(regs)) {
10939 + if (user_mode(regs)) {
10940 sp = regs->sp;
10941 ss = regs->ss & 0xffff;
10942 gs = get_user_gs(regs);
10943 @@ -213,8 +214,8 @@ int kernel_thread(int (*fn)(void *), voi
10944 regs.bx = (unsigned long) fn;
10945 regs.dx = (unsigned long) arg;
10946
10947 - regs.ds = __USER_DS;
10948 - regs.es = __USER_DS;
10949 + regs.ds = __KERNEL_DS;
10950 + regs.es = __KERNEL_DS;
10951 regs.fs = __KERNEL_PERCPU;
10952 regs.gs = __KERNEL_STACK_CANARY;
10953 regs.orig_ax = -1;
10954 @@ -250,7 +251,7 @@ int copy_thread(unsigned long clone_flag
10955 struct task_struct *tsk;
10956 int err;
10957
10958 - childregs = task_pt_regs(p);
10959 + childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
10960 *childregs = *regs;
10961 childregs->ax = 0;
10962 childregs->sp = sp;
10963 @@ -279,6 +280,7 @@ int copy_thread(unsigned long clone_flag
10964 * Set a new TLS for the child thread?
10965 */
10966 if (clone_flags & CLONE_SETTLS)
10967 +//XXX needs set_fs()?
10968 err = do_set_thread_area(p, -1,
10969 (struct user_desc __user *)childregs->si, 0);
10970
10971 @@ -349,7 +351,7 @@ __switch_to(struct task_struct *prev_p,
10972 struct thread_struct *prev = &prev_p->thread,
10973 *next = &next_p->thread;
10974 int cpu = smp_processor_id();
10975 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
10976 + struct tss_struct *tss = init_tss + cpu;
10977
10978 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
10979
10980 @@ -377,6 +379,11 @@ __switch_to(struct task_struct *prev_p,
10981 */
10982 lazy_save_gs(prev->gs);
10983
10984 +#ifdef CONFIG_PAX_MEMORY_UDEREF
10985 + if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
10986 + __set_fs(task_thread_info(next_p)->addr_limit, cpu);
10987 +#endif
10988 +
10989 /*
10990 * Load the per-thread Thread-Local Storage descriptor.
10991 */
10992 @@ -495,3 +502,27 @@ unsigned long get_wchan(struct task_stru
10993 return 0;
10994 }
10995
10996 +#ifdef CONFIG_PAX_RANDKSTACK
10997 +asmlinkage void pax_randomize_kstack(void)
10998 +{
10999 + struct thread_struct *thread = &current->thread;
11000 + unsigned long time;
11001 +
11002 + if (!randomize_va_space)
11003 + return;
11004 +
11005 + rdtscl(time);
11006 +
11007 + /* P4 seems to return a 0 LSB, ignore it */
11008 +#ifdef CONFIG_MPENTIUM4
11009 + time &= 0x1EUL;
11010 + time <<= 2;
11011 +#else
11012 + time &= 0xFUL;
11013 + time <<= 3;
11014 +#endif
11015 +
11016 + thread->sp0 ^= time;
11017 + load_sp0(init_tss + smp_processor_id(), thread);
11018 +}
11019 +#endif
11020 diff -urNp linux-2.6.31.1/arch/x86/kernel/process_64.c linux-2.6.31.1/arch/x86/kernel/process_64.c
11021 --- linux-2.6.31.1/arch/x86/kernel/process_64.c 2009-09-24 11:45:25.000000000 -0400
11022 +++ linux-2.6.31.1/arch/x86/kernel/process_64.c 2009-10-01 20:12:42.000000000 -0400
11023 @@ -94,7 +94,7 @@ static void __exit_idle(void)
11024 void exit_idle(void)
11025 {
11026 /* idle loop has pid 0 */
11027 - if (current->pid)
11028 + if (task_pid_nr(current))
11029 return;
11030 __exit_idle();
11031 }
11032 @@ -173,7 +173,7 @@ void __show_regs(struct pt_regs *regs, i
11033 if (!board)
11034 board = "";
11035 printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n",
11036 - current->pid, current->comm, print_tainted(),
11037 + task_pid_nr(current), current->comm, print_tainted(),
11038 init_utsname()->release,
11039 (int)strcspn(init_utsname()->version, " "),
11040 init_utsname()->version, board);
11041 @@ -384,7 +384,7 @@ __switch_to(struct task_struct *prev_p,
11042 struct thread_struct *prev = &prev_p->thread;
11043 struct thread_struct *next = &next_p->thread;
11044 int cpu = smp_processor_id();
11045 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
11046 + struct tss_struct *tss = init_tss + cpu;
11047 unsigned fsindex, gsindex;
11048
11049 /* we're going to use this soon, after a few expensive things */
11050 @@ -543,12 +543,11 @@ unsigned long get_wchan(struct task_stru
11051 if (!p || p == current || p->state == TASK_RUNNING)
11052 return 0;
11053 stack = (unsigned long)task_stack_page(p);
11054 - if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
11055 + if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64))
11056 return 0;
11057 fp = *(u64 *)(p->thread.sp);
11058 do {
11059 - if (fp < (unsigned long)stack ||
11060 - fp >= (unsigned long)stack+THREAD_SIZE)
11061 + if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64))
11062 return 0;
11063 ip = *(u64 *)(fp+8);
11064 if (!in_sched_functions(ip))
11065 diff -urNp linux-2.6.31.1/arch/x86/kernel/process.c linux-2.6.31.1/arch/x86/kernel/process.c
11066 --- linux-2.6.31.1/arch/x86/kernel/process.c 2009-09-24 11:45:25.000000000 -0400
11067 +++ linux-2.6.31.1/arch/x86/kernel/process.c 2009-10-01 20:12:42.000000000 -0400
11068 @@ -76,7 +76,7 @@ void exit_thread(void)
11069 unsigned long *bp = t->io_bitmap_ptr;
11070
11071 if (bp) {
11072 - struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
11073 + struct tss_struct *tss = init_tss + get_cpu();
11074
11075 t->io_bitmap_ptr = NULL;
11076 clear_thread_flag(TIF_IO_BITMAP);
11077 @@ -108,6 +108,9 @@ void flush_thread(void)
11078
11079 clear_tsk_thread_flag(tsk, TIF_DEBUG);
11080
11081 +#if defined(CONFIG_X86_32) && !defined(CONFIG_CC_STACKPROTECTOR)
11082 + loadsegment(gs, 0);
11083 +#endif
11084 tsk->thread.debugreg0 = 0;
11085 tsk->thread.debugreg1 = 0;
11086 tsk->thread.debugreg2 = 0;
11087 @@ -611,17 +614,3 @@ static int __init idle_setup(char *str)
11088 return 0;
11089 }
11090 early_param("idle", idle_setup);
11091 -
11092 -unsigned long arch_align_stack(unsigned long sp)
11093 -{
11094 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
11095 - sp -= get_random_int() % 8192;
11096 - return sp & ~0xf;
11097 -}
11098 -
11099 -unsigned long arch_randomize_brk(struct mm_struct *mm)
11100 -{
11101 - unsigned long range_end = mm->brk + 0x02000000;
11102 - return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
11103 -}
11104 -
11105 diff -urNp linux-2.6.31.1/arch/x86/kernel/ptrace.c linux-2.6.31.1/arch/x86/kernel/ptrace.c
11106 --- linux-2.6.31.1/arch/x86/kernel/ptrace.c 2009-09-24 11:45:25.000000000 -0400
11107 +++ linux-2.6.31.1/arch/x86/kernel/ptrace.c 2009-10-01 20:12:42.000000000 -0400
11108 @@ -1454,7 +1454,7 @@ void send_sigtrap(struct task_struct *ts
11109 info.si_code = si_code;
11110
11111 /* User-mode ip? */
11112 - info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
11113 + info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
11114
11115 /* Send us the fake SIGTRAP */
11116 force_sig_info(SIGTRAP, &info, tsk);
11117 diff -urNp linux-2.6.31.1/arch/x86/kernel/reboot.c linux-2.6.31.1/arch/x86/kernel/reboot.c
11118 --- linux-2.6.31.1/arch/x86/kernel/reboot.c 2009-09-24 11:45:25.000000000 -0400
11119 +++ linux-2.6.31.1/arch/x86/kernel/reboot.c 2009-10-01 20:12:42.000000000 -0400
11120 @@ -31,7 +31,7 @@ void (*pm_power_off)(void);
11121 EXPORT_SYMBOL(pm_power_off);
11122
11123 static const struct desc_ptr no_idt = {};
11124 -static int reboot_mode;
11125 +static unsigned short reboot_mode;
11126 enum reboot_type reboot_type = BOOT_KBD;
11127 int reboot_force;
11128
11129 @@ -257,7 +257,7 @@ static struct dmi_system_id __initdata r
11130 DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"),
11131 },
11132 },
11133 - { }
11134 + { NULL, NULL, {{0, {0}}}, NULL}
11135 };
11136
11137 static int __init reboot_init(void)
11138 @@ -273,12 +273,12 @@ core_initcall(reboot_init);
11139 controller to pulse the CPU reset line, which is more thorough, but
11140 doesn't work with at least one type of 486 motherboard. It is easy
11141 to stop this code working; hence the copious comments. */
11142 -static const unsigned long long
11143 -real_mode_gdt_entries [3] =
11144 +static struct desc_struct
11145 +real_mode_gdt_entries [3] __read_only =
11146 {
11147 - 0x0000000000000000ULL, /* Null descriptor */
11148 - 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
11149 - 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
11150 + {{{0x00000000, 0x00000000}}}, /* Null descriptor */
11151 + {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
11152 + {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
11153 };
11154
11155 static const struct desc_ptr
11156 @@ -327,7 +327,7 @@ static const unsigned char jump_to_bios
11157 * specified by the code and length parameters.
11158 * We assume that length will aways be less that 100!
11159 */
11160 -void machine_real_restart(const unsigned char *code, int length)
11161 +void machine_real_restart(const unsigned char *code, unsigned int length)
11162 {
11163 local_irq_disable();
11164
11165 @@ -347,8 +347,8 @@ void machine_real_restart(const unsigned
11166 /* Remap the kernel at virtual address zero, as well as offset zero
11167 from the kernel segment. This assumes the kernel segment starts at
11168 virtual address PAGE_OFFSET. */
11169 - memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
11170 - sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
11171 + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
11172 + min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
11173
11174 /*
11175 * Use `swapper_pg_dir' as our page directory.
11176 @@ -360,16 +360,15 @@ void machine_real_restart(const unsigned
11177 boot)". This seems like a fairly standard thing that gets set by
11178 REBOOT.COM programs, and the previous reset routine did this
11179 too. */
11180 - *((unsigned short *)0x472) = reboot_mode;
11181 + *(unsigned short *)(__va(0x472)) = reboot_mode;
11182
11183 /* For the switch to real mode, copy some code to low memory. It has
11184 to be in the first 64k because it is running in 16-bit mode, and it
11185 has to have the same physical and virtual address, because it turns
11186 off paging. Copy it near the end of the first page, out of the way
11187 of BIOS variables. */
11188 - memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
11189 - real_mode_switch, sizeof (real_mode_switch));
11190 - memcpy((void *)(0x1000 - 100), code, length);
11191 + memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
11192 + memcpy(__va(0x1000 - 100), code, length);
11193
11194 /* Set up the IDT for real mode. */
11195 load_idt(&real_mode_idt);
11196 diff -urNp linux-2.6.31.1/arch/x86/kernel/setup.c linux-2.6.31.1/arch/x86/kernel/setup.c
11197 --- linux-2.6.31.1/arch/x86/kernel/setup.c 2009-09-24 11:45:25.000000000 -0400
11198 +++ linux-2.6.31.1/arch/x86/kernel/setup.c 2009-10-01 20:12:42.000000000 -0400
11199 @@ -768,14 +768,14 @@ void __init setup_arch(char **cmdline_p)
11200
11201 if (!boot_params.hdr.root_flags)
11202 root_mountflags &= ~MS_RDONLY;
11203 - init_mm.start_code = (unsigned long) _text;
11204 - init_mm.end_code = (unsigned long) _etext;
11205 + init_mm.start_code = ktla_ktva((unsigned long) _text);
11206 + init_mm.end_code = ktla_ktva((unsigned long) _etext);
11207 init_mm.end_data = (unsigned long) _edata;
11208 init_mm.brk = _brk_end;
11209
11210 - code_resource.start = virt_to_phys(_text);
11211 - code_resource.end = virt_to_phys(_etext)-1;
11212 - data_resource.start = virt_to_phys(_etext);
11213 + code_resource.start = virt_to_phys(ktla_ktva(_text));
11214 + code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
11215 + data_resource.start = virt_to_phys(_sdata);
11216 data_resource.end = virt_to_phys(_edata)-1;
11217 bss_resource.start = virt_to_phys(&__bss_start);
11218 bss_resource.end = virt_to_phys(&__bss_stop)-1;
11219 diff -urNp linux-2.6.31.1/arch/x86/kernel/setup_percpu.c linux-2.6.31.1/arch/x86/kernel/setup_percpu.c
11220 --- linux-2.6.31.1/arch/x86/kernel/setup_percpu.c 2009-09-24 11:45:25.000000000 -0400
11221 +++ linux-2.6.31.1/arch/x86/kernel/setup_percpu.c 2009-10-01 20:12:42.000000000 -0400
11222 @@ -25,19 +25,17 @@
11223 # define DBG(x...)
11224 #endif
11225
11226 +#ifdef CONFIG_SMP
11227 DEFINE_PER_CPU(int, cpu_number);
11228 EXPORT_PER_CPU_SYMBOL(cpu_number);
11229 +#endif
11230
11231 -#ifdef CONFIG_X86_64
11232 #define BOOT_PERCPU_OFFSET ((unsigned long)__per_cpu_load)
11233 -#else
11234 -#define BOOT_PERCPU_OFFSET 0
11235 -#endif
11236
11237 DEFINE_PER_CPU(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET;
11238 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
11239
11240 -unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = {
11241 +unsigned long __per_cpu_offset[NR_CPUS] __read_only = {
11242 [0 ... NR_CPUS-1] = BOOT_PERCPU_OFFSET,
11243 };
11244 EXPORT_SYMBOL(__per_cpu_offset);
11245 @@ -429,13 +427,15 @@ early_param("percpu_alloc", percpu_alloc
11246 static inline void setup_percpu_segment(int cpu)
11247 {
11248 #ifdef CONFIG_X86_32
11249 - struct desc_struct gdt;
11250 -
11251 - pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
11252 - 0x2 | DESCTYPE_S, 0x8);
11253 - gdt.s = 1;
11254 - write_gdt_entry(get_cpu_gdt_table(cpu),
11255 - GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
11256 + struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
11257 + unsigned long base = per_cpu_offset(cpu);
11258 + const unsigned long limit = VMALLOC_END - base - 1;
11259 +
11260 + if (limit < 64*1024)
11261 + pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
11262 + else
11263 + pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
11264 + write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
11265 #endif
11266 }
11267
11268 @@ -486,6 +486,11 @@ void __init setup_per_cpu_areas(void)
11269 /* alrighty, percpu areas up and running */
11270 delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
11271 for_each_possible_cpu(cpu) {
11272 +#ifdef CONFIG_CC_STACKPROTECTOR
11273 +#ifdef CONFIG_x86_32
11274 + unsigned long canary = per_cpu(stack_canary, cpu);
11275 +#endif
11276 +#endif
11277 per_cpu_offset(cpu) = delta + cpu * pcpu_unit_size;
11278 per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
11279 per_cpu(cpu_number, cpu) = cpu;
11280 @@ -513,6 +518,12 @@ void __init setup_per_cpu_areas(void)
11281 early_per_cpu_map(x86_cpu_to_node_map, cpu);
11282 #endif
11283 #endif
11284 +#ifdef CONFIG_CC_STACKPROTECTOR
11285 +#ifdef CONFIG_x86_32
11286 + if (cpu == boot_cpu_id)
11287 + per_cpu(stack_canary, cpu) = canary;
11288 +#endif
11289 +#endif
11290 /*
11291 * Up to this point, the boot CPU has been using .data.init
11292 * area. Reload any changed state for the boot CPU.
11293 diff -urNp linux-2.6.31.1/arch/x86/kernel/signal.c linux-2.6.31.1/arch/x86/kernel/signal.c
11294 --- linux-2.6.31.1/arch/x86/kernel/signal.c 2009-09-24 11:45:25.000000000 -0400
11295 +++ linux-2.6.31.1/arch/x86/kernel/signal.c 2009-10-01 20:12:42.000000000 -0400
11296 @@ -197,7 +197,7 @@ static unsigned long align_sigframe(unsi
11297 * Align the stack pointer according to the i386 ABI,
11298 * i.e. so that on function entry ((sp + 4) & 15) == 0.
11299 */
11300 - sp = ((sp + 4) & -16ul) - 4;
11301 + sp = ((sp - 12) & -16ul) - 4;
11302 #else /* !CONFIG_X86_32 */
11303 sp = round_down(sp, 16) - 8;
11304 #endif
11305 @@ -307,9 +307,9 @@ __setup_frame(int sig, struct k_sigactio
11306 }
11307
11308 if (current->mm->context.vdso)
11309 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
11310 + restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
11311 else
11312 - restorer = &frame->retcode;
11313 + restorer = (void __user *)&frame->retcode;
11314 if (ka->sa.sa_flags & SA_RESTORER)
11315 restorer = ka->sa.sa_restorer;
11316
11317 @@ -377,7 +377,7 @@ static int __setup_rt_frame(int sig, str
11318 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
11319
11320 /* Set up to return from userspace. */
11321 - restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
11322 + restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
11323 if (ka->sa.sa_flags & SA_RESTORER)
11324 restorer = ka->sa.sa_restorer;
11325 put_user_ex(restorer, &frame->pretcode);
11326 @@ -789,7 +789,7 @@ static void do_signal(struct pt_regs *re
11327 * X86_32: vm86 regs switched out by assembly code before reaching
11328 * here, so testing against kernel CS suffices.
11329 */
11330 - if (!user_mode(regs))
11331 + if (!user_mode_novm(regs))
11332 return;
11333
11334 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
11335 diff -urNp linux-2.6.31.1/arch/x86/kernel/smpboot.c linux-2.6.31.1/arch/x86/kernel/smpboot.c
11336 --- linux-2.6.31.1/arch/x86/kernel/smpboot.c 2009-09-24 11:45:25.000000000 -0400
11337 +++ linux-2.6.31.1/arch/x86/kernel/smpboot.c 2009-10-01 20:12:42.000000000 -0400
11338 @@ -685,6 +685,10 @@ static int __cpuinit do_boot_cpu(int api
11339 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
11340 };
11341
11342 +#ifdef CONFIG_PAX_KERNEXEC
11343 + unsigned long cr0;
11344 +#endif
11345 +
11346 INIT_WORK(&c_idle.work, do_fork_idle);
11347
11348 alternatives_smp_switch(1);
11349 @@ -727,7 +731,17 @@ do_rest:
11350 (unsigned long)task_stack_page(c_idle.idle) -
11351 KERNEL_STACK_OFFSET + THREAD_SIZE;
11352 #endif
11353 +
11354 +#ifdef CONFIG_PAX_KERNEXEC
11355 + pax_open_kernel(cr0);
11356 +#endif
11357 +
11358 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
11359 +
11360 +#ifdef CONFIG_PAX_KERNEXEC
11361 + pax_close_kernel(cr0);
11362 +#endif
11363 +
11364 initial_code = (unsigned long)start_secondary;
11365 stack_start.sp = (void *) c_idle.idle->thread.sp;
11366
11367 diff -urNp linux-2.6.31.1/arch/x86/kernel/step.c linux-2.6.31.1/arch/x86/kernel/step.c
11368 --- linux-2.6.31.1/arch/x86/kernel/step.c 2009-09-24 11:45:25.000000000 -0400
11369 +++ linux-2.6.31.1/arch/x86/kernel/step.c 2009-10-01 20:12:42.000000000 -0400
11370 @@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
11371 * and APM bios ones we just ignore here.
11372 */
11373 if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
11374 - u32 *desc;
11375 + struct desc_struct *desc;
11376 unsigned long base;
11377
11378 - seg &= ~7UL;
11379 + seg >>= 3;
11380
11381 mutex_lock(&child->mm->context.lock);
11382 - if (unlikely((seg >> 3) >= child->mm->context.size))
11383 - addr = -1L; /* bogus selector, access would fault */
11384 + if (unlikely(seg >= child->mm->context.size))
11385 + addr = -EINVAL;
11386 else {
11387 - desc = child->mm->context.ldt + seg;
11388 - base = ((desc[0] >> 16) |
11389 - ((desc[1] & 0xff) << 16) |
11390 - (desc[1] & 0xff000000));
11391 + desc = &child->mm->context.ldt[seg];
11392 + base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
11393
11394 /* 16-bit code segment? */
11395 - if (!((desc[1] >> 22) & 1))
11396 + if (!((desc->b >> 22) & 1))
11397 addr &= 0xffff;
11398 addr += base;
11399 }
11400 @@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
11401 unsigned char opcode[15];
11402 unsigned long addr = convert_ip_to_linear(child, regs);
11403
11404 + if (addr == -EINVAL)
11405 + return 0;
11406 +
11407 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
11408 for (i = 0; i < copied; i++) {
11409 switch (opcode[i]) {
11410 @@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
11411
11412 #ifdef CONFIG_X86_64
11413 case 0x40 ... 0x4f:
11414 - if (regs->cs != __USER_CS)
11415 + if ((regs->cs & 0xffff) != __USER_CS)
11416 /* 32-bit mode: register increment */
11417 return 0;
11418 /* 64-bit mode: REX prefix */
11419 diff -urNp linux-2.6.31.1/arch/x86/kernel/syscall_table_32.S linux-2.6.31.1/arch/x86/kernel/syscall_table_32.S
11420 --- linux-2.6.31.1/arch/x86/kernel/syscall_table_32.S 2009-09-24 11:45:25.000000000 -0400
11421 +++ linux-2.6.31.1/arch/x86/kernel/syscall_table_32.S 2009-10-01 20:12:42.000000000 -0400
11422 @@ -1,3 +1,4 @@
11423 +.section .rodata,"a",@progbits
11424 ENTRY(sys_call_table)
11425 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
11426 .long sys_exit
11427 diff -urNp linux-2.6.31.1/arch/x86/kernel/sys_i386_32.c linux-2.6.31.1/arch/x86/kernel/sys_i386_32.c
11428 --- linux-2.6.31.1/arch/x86/kernel/sys_i386_32.c 2009-09-24 11:45:25.000000000 -0400
11429 +++ linux-2.6.31.1/arch/x86/kernel/sys_i386_32.c 2009-10-01 20:12:42.000000000 -0400
11430 @@ -24,6 +24,21 @@
11431
11432 #include <asm/syscalls.h>
11433
11434 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
11435 +{
11436 + unsigned long pax_task_size = TASK_SIZE;
11437 +
11438 +#ifdef CONFIG_PAX_SEGMEXEC
11439 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
11440 + pax_task_size = SEGMEXEC_TASK_SIZE;
11441 +#endif
11442 +
11443 + if (len > pax_task_size || addr > pax_task_size - len)
11444 + return -EINVAL;
11445 +
11446 + return 0;
11447 +}
11448 +
11449 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
11450 unsigned long prot, unsigned long flags,
11451 unsigned long fd, unsigned long pgoff)
11452 @@ -83,6 +98,205 @@ out:
11453 return err;
11454 }
11455
11456 +unsigned long
11457 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
11458 + unsigned long len, unsigned long pgoff, unsigned long flags)
11459 +{
11460 + struct mm_struct *mm = current->mm;
11461 + struct vm_area_struct *vma;
11462 + unsigned long start_addr, pax_task_size = TASK_SIZE;
11463 +
11464 +#ifdef CONFIG_PAX_SEGMEXEC
11465 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11466 + pax_task_size = SEGMEXEC_TASK_SIZE;
11467 +#endif
11468 +
11469 + if (len > pax_task_size)
11470 + return -ENOMEM;
11471 +
11472 + if (flags & MAP_FIXED)
11473 + return addr;
11474 +
11475 +#ifdef CONFIG_PAX_RANDMMAP
11476 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
11477 +#endif
11478 +
11479 + if (addr) {
11480 + addr = PAGE_ALIGN(addr);
11481 + vma = find_vma(mm, addr);
11482 + if (pax_task_size - len >= addr &&
11483 + (!vma || addr + len <= vma->vm_start))
11484 + return addr;
11485 + }
11486 + if (len > mm->cached_hole_size) {
11487 + start_addr = addr = mm->free_area_cache;
11488 + } else {
11489 + start_addr = addr = mm->mmap_base;
11490 + mm->cached_hole_size = 0;
11491 + }
11492 +
11493 +#ifdef CONFIG_PAX_PAGEEXEC
11494 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
11495 + start_addr = 0x00110000UL;
11496 +
11497 +#ifdef CONFIG_PAX_RANDMMAP
11498 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11499 + start_addr += mm->delta_mmap & 0x03FFF000UL;
11500 +#endif
11501 +
11502 + if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
11503 + start_addr = addr = mm->mmap_base;
11504 + else
11505 + addr = start_addr;
11506 + }
11507 +#endif
11508 +
11509 +full_search:
11510 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
11511 + /* At this point: (!vma || addr < vma->vm_end). */
11512 + if (pax_task_size - len < addr) {
11513 + /*
11514 + * Start a new search - just in case we missed
11515 + * some holes.
11516 + */
11517 + if (start_addr != mm->mmap_base) {
11518 + start_addr = addr = mm->mmap_base;
11519 + mm->cached_hole_size = 0;
11520 + goto full_search;
11521 + }
11522 + return -ENOMEM;
11523 + }
11524 + if (!vma || addr + len <= vma->vm_start) {
11525 + /*
11526 + * Remember the place where we stopped the search:
11527 + */
11528 + mm->free_area_cache = addr + len;
11529 + return addr;
11530 + }
11531 + if (addr + mm->cached_hole_size < vma->vm_start)
11532 + mm->cached_hole_size = vma->vm_start - addr;
11533 + addr = vma->vm_end;
11534 + if (mm->start_brk <= addr && addr < mm->mmap_base) {
11535 + start_addr = addr = mm->mmap_base;
11536 + mm->cached_hole_size = 0;
11537 + goto full_search;
11538 + }
11539 + }
11540 +}
11541 +
11542 +unsigned long
11543 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
11544 + const unsigned long len, const unsigned long pgoff,
11545 + const unsigned long flags)
11546 +{
11547 + struct vm_area_struct *vma;
11548 + struct mm_struct *mm = current->mm;
11549 + unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
11550 +
11551 +#ifdef CONFIG_PAX_SEGMEXEC
11552 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11553 + pax_task_size = SEGMEXEC_TASK_SIZE;
11554 +#endif
11555 +
11556 + /* requested length too big for entire address space */
11557 + if (len > pax_task_size)
11558 + return -ENOMEM;
11559 +
11560 + if (flags & MAP_FIXED)
11561 + return addr;
11562 +
11563 +#ifdef CONFIG_PAX_PAGEEXEC
11564 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
11565 + goto bottomup;
11566 +#endif
11567 +
11568 +#ifdef CONFIG_PAX_RANDMMAP
11569 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
11570 +#endif
11571 +
11572 + /* requesting a specific address */
11573 + if (addr) {
11574 + addr = PAGE_ALIGN(addr);
11575 + vma = find_vma(mm, addr);
11576 + if (pax_task_size - len >= addr &&
11577 + (!vma || addr + len <= vma->vm_start))
11578 + return addr;
11579 + }
11580 +
11581 + /* check if free_area_cache is useful for us */
11582 + if (len <= mm->cached_hole_size) {
11583 + mm->cached_hole_size = 0;
11584 + mm->free_area_cache = mm->mmap_base;
11585 + }
11586 +
11587 + /* either no address requested or can't fit in requested address hole */
11588 + addr = mm->free_area_cache;
11589 +
11590 + /* make sure it can fit in the remaining address space */
11591 + if (addr > len) {
11592 + vma = find_vma(mm, addr-len);
11593 + if (!vma || addr <= vma->vm_start)
11594 + /* remember the address as a hint for next time */
11595 + return (mm->free_area_cache = addr-len);
11596 + }
11597 +
11598 + if (mm->mmap_base < len)
11599 + goto bottomup;
11600 +
11601 + addr = mm->mmap_base-len;
11602 +
11603 + do {
11604 + /*
11605 + * Lookup failure means no vma is above this address,
11606 + * else if new region fits below vma->vm_start,
11607 + * return with success:
11608 + */
11609 + vma = find_vma(mm, addr);
11610 + if (!vma || addr+len <= vma->vm_start)
11611 + /* remember the address as a hint for next time */
11612 + return (mm->free_area_cache = addr);
11613 +
11614 + /* remember the largest hole we saw so far */
11615 + if (addr + mm->cached_hole_size < vma->vm_start)
11616 + mm->cached_hole_size = vma->vm_start - addr;
11617 +
11618 + /* try just below the current vma->vm_start */
11619 + addr = vma->vm_start-len;
11620 + } while (len < vma->vm_start);
11621 +
11622 +bottomup:
11623 + /*
11624 + * A failed mmap() very likely causes application failure,
11625 + * so fall back to the bottom-up function here. This scenario
11626 + * can happen with large stack limits and large mmap()
11627 + * allocations.
11628 + */
11629 +
11630 +#ifdef CONFIG_PAX_SEGMEXEC
11631 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11632 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
11633 + else
11634 +#endif
11635 +
11636 + mm->mmap_base = TASK_UNMAPPED_BASE;
11637 +
11638 +#ifdef CONFIG_PAX_RANDMMAP
11639 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11640 + mm->mmap_base += mm->delta_mmap;
11641 +#endif
11642 +
11643 + mm->free_area_cache = mm->mmap_base;
11644 + mm->cached_hole_size = ~0UL;
11645 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
11646 + /*
11647 + * Restore the topdown base:
11648 + */
11649 + mm->mmap_base = base;
11650 + mm->free_area_cache = base;
11651 + mm->cached_hole_size = ~0UL;
11652 +
11653 + return addr;
11654 +}
11655
11656 struct sel_arg_struct {
11657 unsigned long n;
11658 diff -urNp linux-2.6.31.1/arch/x86/kernel/sys_x86_64.c linux-2.6.31.1/arch/x86/kernel/sys_x86_64.c
11659 --- linux-2.6.31.1/arch/x86/kernel/sys_x86_64.c 2009-09-24 11:45:25.000000000 -0400
11660 +++ linux-2.6.31.1/arch/x86/kernel/sys_x86_64.c 2009-10-01 20:12:42.000000000 -0400
11661 @@ -47,8 +47,8 @@ out:
11662 return error;
11663 }
11664
11665 -static void find_start_end(unsigned long flags, unsigned long *begin,
11666 - unsigned long *end)
11667 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
11668 + unsigned long *begin, unsigned long *end)
11669 {
11670 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
11671 unsigned long new_begin;
11672 @@ -67,7 +67,7 @@ static void find_start_end(unsigned long
11673 *begin = new_begin;
11674 }
11675 } else {
11676 - *begin = TASK_UNMAPPED_BASE;
11677 + *begin = mm->mmap_base;
11678 *end = TASK_SIZE;
11679 }
11680 }
11681 @@ -84,11 +84,15 @@ arch_get_unmapped_area(struct file *filp
11682 if (flags & MAP_FIXED)
11683 return addr;
11684
11685 - find_start_end(flags, &begin, &end);
11686 + find_start_end(mm, flags, &begin, &end);
11687
11688 if (len > end)
11689 return -ENOMEM;
11690
11691 +#ifdef CONFIG_PAX_RANDMMAP
11692 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
11693 +#endif
11694 +
11695 if (addr) {
11696 addr = PAGE_ALIGN(addr);
11697 vma = find_vma(mm, addr);
11698 @@ -143,7 +147,7 @@ arch_get_unmapped_area_topdown(struct fi
11699 {
11700 struct vm_area_struct *vma;
11701 struct mm_struct *mm = current->mm;
11702 - unsigned long addr = addr0;
11703 + unsigned long base = mm->mmap_base, addr = addr0;
11704
11705 /* requested length too big for entire address space */
11706 if (len > TASK_SIZE)
11707 @@ -156,6 +160,10 @@ arch_get_unmapped_area_topdown(struct fi
11708 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
11709 goto bottomup;
11710
11711 +#ifdef CONFIG_PAX_RANDMMAP
11712 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
11713 +#endif
11714 +
11715 /* requesting a specific address */
11716 if (addr) {
11717 addr = PAGE_ALIGN(addr);
11718 @@ -213,13 +221,21 @@ bottomup:
11719 * can happen with large stack limits and large mmap()
11720 * allocations.
11721 */
11722 + mm->mmap_base = TASK_UNMAPPED_BASE;
11723 +
11724 +#ifdef CONFIG_PAX_RANDMMAP
11725 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11726 + mm->mmap_base += mm->delta_mmap;
11727 +#endif
11728 +
11729 + mm->free_area_cache = mm->mmap_base;
11730 mm->cached_hole_size = ~0UL;
11731 - mm->free_area_cache = TASK_UNMAPPED_BASE;
11732 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
11733 /*
11734 * Restore the topdown base:
11735 */
11736 - mm->free_area_cache = mm->mmap_base;
11737 + mm->mmap_base = base;
11738 + mm->free_area_cache = base;
11739 mm->cached_hole_size = ~0UL;
11740
11741 return addr;
11742 diff -urNp linux-2.6.31.1/arch/x86/kernel/time_32.c linux-2.6.31.1/arch/x86/kernel/time_32.c
11743 --- linux-2.6.31.1/arch/x86/kernel/time_32.c 2009-09-24 11:45:25.000000000 -0400
11744 +++ linux-2.6.31.1/arch/x86/kernel/time_32.c 2009-10-01 20:12:42.000000000 -0400
11745 @@ -47,22 +47,32 @@ unsigned long profile_pc(struct pt_regs
11746 unsigned long pc = instruction_pointer(regs);
11747
11748 #ifdef CONFIG_SMP
11749 - if (!user_mode_vm(regs) && in_lock_functions(pc)) {
11750 + if (!user_mode(regs) && in_lock_functions(pc)) {
11751 #ifdef CONFIG_FRAME_POINTER
11752 - return *(unsigned long *)(regs->bp + sizeof(long));
11753 + return ktla_ktva(*(unsigned long *)(regs->bp + sizeof(long)));
11754 #else
11755 unsigned long *sp = (unsigned long *)&regs->sp;
11756
11757 /* Return address is either directly at stack pointer
11758 or above a saved flags. Eflags has bits 22-31 zero,
11759 kernel addresses don't. */
11760 +
11761 +#ifdef CONFIG_PAX_KERNEXEC
11762 + return ktla_ktva(sp[0]);
11763 +#else
11764 if (sp[0] >> 22)
11765 return sp[0];
11766 if (sp[1] >> 22)
11767 return sp[1];
11768 #endif
11769 +
11770 +#endif
11771 }
11772 #endif
11773 +
11774 + if (!user_mode(regs))
11775 + pc = ktla_ktva(pc);
11776 +
11777 return pc;
11778 }
11779 EXPORT_SYMBOL(profile_pc);
11780 diff -urNp linux-2.6.31.1/arch/x86/kernel/time_64.c linux-2.6.31.1/arch/x86/kernel/time_64.c
11781 --- linux-2.6.31.1/arch/x86/kernel/time_64.c 2009-09-24 11:45:25.000000000 -0400
11782 +++ linux-2.6.31.1/arch/x86/kernel/time_64.c 2009-10-01 20:12:42.000000000 -0400
11783 @@ -25,8 +25,6 @@
11784 #include <asm/time.h>
11785 #include <asm/timer.h>
11786
11787 -volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
11788 -
11789 unsigned long profile_pc(struct pt_regs *regs)
11790 {
11791 unsigned long pc = instruction_pointer(regs);
11792 @@ -34,7 +32,7 @@ unsigned long profile_pc(struct pt_regs
11793 /* Assume the lock function has either no stack frame or a copy
11794 of flags from PUSHF
11795 Eflags always has bits 22 and up cleared unlike kernel addresses. */
11796 - if (!user_mode_vm(regs) && in_lock_functions(pc)) {
11797 + if (!user_mode(regs) && in_lock_functions(pc)) {
11798 #ifdef CONFIG_FRAME_POINTER
11799 return *(unsigned long *)(regs->bp + sizeof(long));
11800 #else
11801 diff -urNp linux-2.6.31.1/arch/x86/kernel/tls.c linux-2.6.31.1/arch/x86/kernel/tls.c
11802 --- linux-2.6.31.1/arch/x86/kernel/tls.c 2009-09-24 11:45:25.000000000 -0400
11803 +++ linux-2.6.31.1/arch/x86/kernel/tls.c 2009-10-01 20:12:42.000000000 -0400
11804 @@ -85,6 +85,11 @@ int do_set_thread_area(struct task_struc
11805 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
11806 return -EINVAL;
11807
11808 +#ifdef CONFIG_PAX_SEGMEXEC
11809 + if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
11810 + return -EINVAL;
11811 +#endif
11812 +
11813 set_tls_desc(p, idx, &info, 1);
11814
11815 return 0;
11816 diff -urNp linux-2.6.31.1/arch/x86/kernel/traps.c linux-2.6.31.1/arch/x86/kernel/traps.c
11817 --- linux-2.6.31.1/arch/x86/kernel/traps.c 2009-09-24 11:45:25.000000000 -0400
11818 +++ linux-2.6.31.1/arch/x86/kernel/traps.c 2009-10-01 20:12:42.000000000 -0400
11819 @@ -70,14 +70,6 @@ asmlinkage int system_call(void);
11820
11821 /* Do we ignore FPU interrupts ? */
11822 char ignore_fpu_irq;
11823 -
11824 -/*
11825 - * The IDT has to be page-aligned to simplify the Pentium
11826 - * F0 0F bug workaround.. We have a special link segment
11827 - * for this.
11828 - */
11829 -gate_desc idt_table[256]
11830 - __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
11831 #endif
11832
11833 DECLARE_BITMAP(used_vectors, NR_VECTORS);
11834 @@ -115,7 +107,7 @@ static inline void preempt_conditional_c
11835 static inline void
11836 die_if_kernel(const char *str, struct pt_regs *regs, long err)
11837 {
11838 - if (!user_mode_vm(regs))
11839 + if (!user_mode(regs))
11840 die(str, regs, err);
11841 }
11842 #endif
11843 @@ -127,7 +119,7 @@ do_trap(int trapnr, int signr, char *str
11844 struct task_struct *tsk = current;
11845
11846 #ifdef CONFIG_X86_32
11847 - if (regs->flags & X86_VM_MASK) {
11848 + if (v8086_mode(regs)) {
11849 /*
11850 * traps 0, 1, 3, 4, and 5 should be forwarded to vm86.
11851 * On nmi (interrupt 2), do_trap should not be called.
11852 @@ -138,7 +130,7 @@ do_trap(int trapnr, int signr, char *str
11853 }
11854 #endif
11855
11856 - if (!user_mode(regs))
11857 + if (!user_mode_novm(regs))
11858 goto kernel_trap;
11859
11860 #ifdef CONFIG_X86_32
11861 @@ -161,7 +153,7 @@ trap_signal:
11862 printk_ratelimit()) {
11863 printk(KERN_INFO
11864 "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
11865 - tsk->comm, tsk->pid, str,
11866 + tsk->comm, task_pid_nr(tsk), str,
11867 regs->ip, regs->sp, error_code);
11868 print_vma_addr(" in ", regs->ip);
11869 printk("\n");
11870 @@ -180,6 +172,12 @@ kernel_trap:
11871 tsk->thread.trap_no = trapnr;
11872 die(str, regs, error_code);
11873 }
11874 +
11875 +#ifdef CONFIG_PAX_REFCOUNT
11876 + if (trapnr == 4)
11877 + pax_report_refcount_overflow(regs);
11878 +#endif
11879 +
11880 return;
11881
11882 #ifdef CONFIG_X86_32
11883 @@ -268,14 +266,30 @@ do_general_protection(struct pt_regs *re
11884 conditional_sti(regs);
11885
11886 #ifdef CONFIG_X86_32
11887 - if (regs->flags & X86_VM_MASK)
11888 + if (v8086_mode(regs))
11889 goto gp_in_vm86;
11890 #endif
11891
11892 tsk = current;
11893 - if (!user_mode(regs))
11894 + if (!user_mode_novm(regs))
11895 goto gp_in_kernel;
11896
11897 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
11898 + if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
11899 + struct mm_struct *mm = tsk->mm;
11900 + unsigned long limit;
11901 +
11902 + down_write(&mm->mmap_sem);
11903 + limit = mm->context.user_cs_limit;
11904 + if (limit < TASK_SIZE) {
11905 + track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
11906 + up_write(&mm->mmap_sem);
11907 + return;
11908 + }
11909 + up_write(&mm->mmap_sem);
11910 + }
11911 +#endif
11912 +
11913 tsk->thread.error_code = error_code;
11914 tsk->thread.trap_no = 13;
11915
11916 @@ -308,6 +322,13 @@ gp_in_kernel:
11917 if (notify_die(DIE_GPF, "general protection fault", regs,
11918 error_code, 13, SIGSEGV) == NOTIFY_STOP)
11919 return;
11920 +
11921 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
11922 + if ((regs->cs & 0xFFFF) == __KERNEL_CS)
11923 + die("PAX: suspicious general protection fault", regs, error_code);
11924 + else
11925 +#endif
11926 +
11927 die("general protection fault", regs, error_code);
11928 }
11929
11930 @@ -561,7 +582,7 @@ dotraplinkage void __kprobes do_debug(st
11931 }
11932
11933 #ifdef CONFIG_X86_32
11934 - if (regs->flags & X86_VM_MASK)
11935 + if (v8086_mode(regs))
11936 goto debug_vm86;
11937 #endif
11938
11939 @@ -573,7 +594,7 @@ dotraplinkage void __kprobes do_debug(st
11940 * kernel space (but re-enable TF when returning to user mode).
11941 */
11942 if (condition & DR_STEP) {
11943 - if (!user_mode(regs))
11944 + if (!user_mode_novm(regs))
11945 goto clear_TF_reenable;
11946 }
11947
11948 @@ -760,7 +781,7 @@ do_simd_coprocessor_error(struct pt_regs
11949 * Handle strange cache flush from user space exception
11950 * in all other cases. This is undocumented behaviour.
11951 */
11952 - if (regs->flags & X86_VM_MASK) {
11953 + if (v8086_mode(regs)) {
11954 handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
11955 return;
11956 }
11957 @@ -789,19 +810,14 @@ do_spurious_interrupt_bug(struct pt_regs
11958 #ifdef CONFIG_X86_32
11959 unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
11960 {
11961 - struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
11962 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
11963 unsigned long new_kesp = kesp - base;
11964 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
11965 - __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
11966 + struct desc_struct ss;
11967
11968 /* Set up base for espfix segment */
11969 - desc &= 0x00f0ff0000000000ULL;
11970 - desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
11971 - ((((__u64)base) << 32) & 0xff00000000000000ULL) |
11972 - ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
11973 - (lim_pages & 0xffff);
11974 - *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
11975 + pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
11976 + write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
11977
11978 return new_kesp;
11979 }
11980 diff -urNp linux-2.6.31.1/arch/x86/kernel/tsc.c linux-2.6.31.1/arch/x86/kernel/tsc.c
11981 --- linux-2.6.31.1/arch/x86/kernel/tsc.c 2009-09-24 11:45:25.000000000 -0400
11982 +++ linux-2.6.31.1/arch/x86/kernel/tsc.c 2009-10-01 20:12:42.000000000 -0400
11983 @@ -790,7 +790,7 @@ static struct dmi_system_id __initdata b
11984 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
11985 },
11986 },
11987 - {}
11988 + { NULL, NULL, {{0, {0}}}, NULL}
11989 };
11990
11991 static void __init check_system_tsc_reliable(void)
11992 diff -urNp linux-2.6.31.1/arch/x86/kernel/vm86_32.c linux-2.6.31.1/arch/x86/kernel/vm86_32.c
11993 --- linux-2.6.31.1/arch/x86/kernel/vm86_32.c 2009-09-24 11:45:25.000000000 -0400
11994 +++ linux-2.6.31.1/arch/x86/kernel/vm86_32.c 2009-10-01 20:12:42.000000000 -0400
11995 @@ -148,7 +148,7 @@ struct pt_regs *save_v86_state(struct ke
11996 do_exit(SIGSEGV);
11997 }
11998
11999 - tss = &per_cpu(init_tss, get_cpu());
12000 + tss = init_tss + get_cpu();
12001 current->thread.sp0 = current->thread.saved_sp0;
12002 current->thread.sysenter_cs = __KERNEL_CS;
12003 load_sp0(tss, &current->thread);
12004 @@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
12005 tsk->thread.saved_fs = info->regs32->fs;
12006 tsk->thread.saved_gs = get_user_gs(info->regs32);
12007
12008 - tss = &per_cpu(init_tss, get_cpu());
12009 + tss = init_tss + get_cpu();
12010 tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
12011 if (cpu_has_sep)
12012 tsk->thread.sysenter_cs = 0;
12013 diff -urNp linux-2.6.31.1/arch/x86/kernel/vmi_32.c linux-2.6.31.1/arch/x86/kernel/vmi_32.c
12014 --- linux-2.6.31.1/arch/x86/kernel/vmi_32.c 2009-09-24 11:45:25.000000000 -0400
12015 +++ linux-2.6.31.1/arch/x86/kernel/vmi_32.c 2009-10-01 20:12:42.000000000 -0400
12016 @@ -102,18 +102,43 @@ static unsigned patch_internal(int call,
12017 {
12018 u64 reloc;
12019 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
12020 +
12021 +#ifdef CONFIG_PAX_KERNEXEC
12022 + unsigned long cr0;
12023 +#endif
12024 +
12025 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
12026 switch(rel->type) {
12027 case VMI_RELOCATION_CALL_REL:
12028 BUG_ON(len < 5);
12029 +
12030 +#ifdef CONFIG_PAX_KERNEXEC
12031 + pax_open_kernel(cr0);
12032 +#endif
12033 +
12034 *(char *)insnbuf = MNEM_CALL;
12035 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
12036 +
12037 +#ifdef CONFIG_PAX_KERNEXEC
12038 + pax_close_kernel(cr0);
12039 +#endif
12040 +
12041 return 5;
12042
12043 case VMI_RELOCATION_JUMP_REL:
12044 BUG_ON(len < 5);
12045 +
12046 +#ifdef CONFIG_PAX_KERNEXEC
12047 + pax_open_kernel(cr0);
12048 +#endif
12049 +
12050 *(char *)insnbuf = MNEM_JMP;
12051 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
12052 +
12053 +#ifdef CONFIG_PAX_KERNEXEC
12054 + pax_close_kernel(cr0);
12055 +#endif
12056 +
12057 return 5;
12058
12059 case VMI_RELOCATION_NOP:
12060 @@ -404,13 +429,13 @@ static void vmi_set_pud(pud_t *pudp, pud
12061
12062 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
12063 {
12064 - const pte_t pte = { .pte = 0 };
12065 + const pte_t pte = __pte(0ULL);
12066 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
12067 }
12068
12069 static void vmi_pmd_clear(pmd_t *pmd)
12070 {
12071 - const pte_t pte = { .pte = 0 };
12072 + const pte_t pte = __pte(0ULL);
12073 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
12074 }
12075 #endif
12076 @@ -438,8 +463,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
12077 ap.ss = __KERNEL_DS;
12078 ap.esp = (unsigned long) start_esp;
12079
12080 - ap.ds = __USER_DS;
12081 - ap.es = __USER_DS;
12082 + ap.ds = __KERNEL_DS;
12083 + ap.es = __KERNEL_DS;
12084 ap.fs = __KERNEL_PERCPU;
12085 ap.gs = __KERNEL_STACK_CANARY;
12086
12087 @@ -640,12 +665,20 @@ static inline int __init activate_vmi(vo
12088 u64 reloc;
12089 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
12090
12091 +#ifdef CONFIG_PAX_KERNEXEC
12092 + unsigned long cr0;
12093 +#endif
12094 +
12095 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
12096 printk(KERN_ERR "VMI ROM failed to initialize!");
12097 return 0;
12098 }
12099 savesegment(cs, kernel_cs);
12100
12101 +#ifdef CONFIG_PAX_KERNEXEC
12102 + pax_open_kernel(cr0);
12103 +#endif
12104 +
12105 pv_info.paravirt_enabled = 1;
12106 pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
12107 pv_info.name = "vmi";
12108 @@ -836,6 +869,10 @@ static inline int __init activate_vmi(vo
12109
12110 para_fill(pv_irq_ops.safe_halt, Halt);
12111
12112 +#ifdef CONFIG_PAX_KERNEXEC
12113 + pax_close_kernel(cr0);
12114 +#endif
12115 +
12116 /*
12117 * Alternative instruction rewriting doesn't happen soon enough
12118 * to convert VMI_IRET to a call instead of a jump; so we have
12119 diff -urNp linux-2.6.31.1/arch/x86/kernel/vmlinux.lds.S linux-2.6.31.1/arch/x86/kernel/vmlinux.lds.S
12120 --- linux-2.6.31.1/arch/x86/kernel/vmlinux.lds.S 2009-09-24 11:45:25.000000000 -0400
12121 +++ linux-2.6.31.1/arch/x86/kernel/vmlinux.lds.S 2009-10-01 20:12:42.000000000 -0400
12122 @@ -26,6 +26,22 @@
12123 #include <asm/page_types.h>
12124 #include <asm/cache.h>
12125 #include <asm/boot.h>
12126 +#include <asm/segment.h>
12127 +
12128 +#undef PMD_SIZE
12129 +#undef PMD_SHIFT
12130 +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
12131 +#define PMD_SHIFT 21
12132 +#else
12133 +#define PMD_SHIFT 22
12134 +#endif
12135 +#define PMD_SIZE (1 << PMD_SHIFT)
12136 +
12137 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
12138 +#define __KERNEL_TEXT_OFFSET (LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR)
12139 +#else
12140 +#define __KERNEL_TEXT_OFFSET 0
12141 +#endif
12142
12143 #undef i386 /* in case the preprocessor is a 32bit one */
12144
12145 @@ -34,46 +50,52 @@ OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONF
12146 #ifdef CONFIG_X86_32
12147 OUTPUT_ARCH(i386)
12148 ENTRY(phys_startup_32)
12149 -jiffies = jiffies_64;
12150 #else
12151 OUTPUT_ARCH(i386:x86-64)
12152 ENTRY(phys_startup_64)
12153 -jiffies_64 = jiffies;
12154 #endif
12155
12156 +jiffies = jiffies_64;
12157 +
12158 PHDRS {
12159 text PT_LOAD FLAGS(5); /* R_E */
12160 - data PT_LOAD FLAGS(7); /* RWE */
12161 + rodata PT_LOAD FLAGS(4); /* R__ */
12162 + data PT_LOAD FLAGS(6); /* RW_ */
12163 #ifdef CONFIG_X86_64
12164 - user PT_LOAD FLAGS(7); /* RWE */
12165 + user PT_LOAD FLAGS(5); /* R_E */
12166 +#endif
12167 + init.begin PT_LOAD FLAGS(6); /* RW_ */
12168 #ifdef CONFIG_SMP
12169 - percpu PT_LOAD FLAGS(7); /* RWE */
12170 + percpu PT_LOAD FLAGS(6); /* RW_ */
12171 #endif
12172 + text.init PT_LOAD FLAGS(5); /* R_E */
12173 + text.exit PT_LOAD FLAGS(5); /* R_E */
12174 init PT_LOAD FLAGS(7); /* RWE */
12175 -#endif
12176 note PT_NOTE FLAGS(0); /* ___ */
12177 }
12178
12179 SECTIONS
12180 {
12181 #ifdef CONFIG_X86_32
12182 - . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
12183 - phys_startup_32 = startup_32 - LOAD_OFFSET;
12184 + . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
12185 #else
12186 - . = __START_KERNEL;
12187 - phys_startup_64 = startup_64 - LOAD_OFFSET;
12188 + . = __START_KERNEL;
12189 #endif
12190
12191 /* Text and read-only data */
12192
12193 - /* bootstrapping code */
12194 - .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
12195 + .text (. - __KERNEL_TEXT_OFFSET): AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12196 + /* bootstrapping code */
12197 +#ifdef CONFIG_X86_32
12198 + phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
12199 +#else
12200 + phys_startup_64 = startup_64 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
12201 +#endif
12202 + __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
12203 _text = .;
12204 *(.text.head)
12205 - } :text = 0x9090
12206
12207 - /* The rest of the text */
12208 - .text : AT(ADDR(.text) - LOAD_OFFSET) {
12209 + /* The rest of the text */
12210 #ifdef CONFIG_X86_32
12211 /* not really needed, already page aligned */
12212 . = ALIGN(PAGE_SIZE);
12213 @@ -92,7 +114,10 @@ SECTIONS
12214 _etext = .;
12215 } :text = 0x9090
12216
12217 - NOTES :text :note
12218 + . += __KERNEL_TEXT_OFFSET;
12219 +
12220 + . = ALIGN(PAGE_SIZE);
12221 + NOTES :rodata :note
12222
12223 /* Exception table */
12224 . = ALIGN(16);
12225 @@ -100,22 +125,53 @@ SECTIONS
12226 __start___ex_table = .;
12227 *(__ex_table)
12228 __stop___ex_table = .;
12229 - } :text = 0x9090
12230 + } :rodata
12231
12232 RO_DATA(PAGE_SIZE)
12233
12234 +#ifdef CONFIG_X86_32
12235 + . = ALIGN(PAGE_SIZE);
12236 + .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
12237 + *(.idt)
12238 + . = ALIGN(PAGE_SIZE);
12239 + *(.empty_zero_page)
12240 + *(.swapper_pg_pmd)
12241 + *(.swapper_pg_dir)
12242 +
12243 +#if defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_MODULES)
12244 + . = ALIGN(PMD_SIZE);
12245 +#endif
12246 +
12247 + }
12248 +
12249 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
12250 + . = ALIGN(PAGE_SIZE);
12251 + .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
12252 + MODULES_EXEC_VADDR = .;
12253 + BYTE(0)
12254 + . += (8 * 1024 * 1024);
12255 + . = ALIGN(PMD_SIZE);
12256 + MODULES_EXEC_END = . - 1;
12257 + }
12258 +#endif
12259 +#endif
12260 +
12261 /* Data */
12262 .data : AT(ADDR(.data) - LOAD_OFFSET) {
12263 +
12264 +#ifdef CONFIG_PAX_KERNEXEC
12265 + . = ALIGN(PMD_SIZE);
12266 +#else
12267 + . = ALIGN(PAGE_SIZE);
12268 +#endif
12269 +
12270 /* Start of data section */
12271 _sdata = .;
12272
12273 /* init_task */
12274 INIT_TASK_DATA(THREAD_SIZE)
12275
12276 -#ifdef CONFIG_X86_32
12277 - /* 32 bit has nosave before _edata */
12278 NOSAVE_DATA
12279 -#endif
12280
12281 PAGE_ALIGNED_DATA(PAGE_SIZE)
12282 *(.data.idt)
12283 @@ -182,12 +238,6 @@ SECTIONS
12284 }
12285 vgetcpu_mode = VVIRT(.vgetcpu_mode);
12286
12287 - . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
12288 - .jiffies : AT(VLOAD(.jiffies)) {
12289 - *(.jiffies)
12290 - }
12291 - jiffies = VVIRT(.jiffies);
12292 -
12293 .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) {
12294 *(.vsyscall_3)
12295 }
12296 @@ -205,12 +255,19 @@ SECTIONS
12297 #endif /* CONFIG_X86_64 */
12298
12299 /* Init code and data - will be freed after init */
12300 - . = ALIGN(PAGE_SIZE);
12301 .init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {
12302 + BYTE(0)
12303 +
12304 +#ifdef CONFIG_PAX_KERNEXEC
12305 + . = ALIGN(PMD_SIZE);
12306 +#else
12307 + . = ALIGN(PAGE_SIZE);
12308 +#endif
12309 +
12310 __init_begin = .; /* paired with __init_end */
12311 - }
12312 + } :init.begin
12313
12314 -#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
12315 +#ifdef CONFIG_SMP
12316 /*
12317 * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
12318 * output PHDR, so the next output section - .init.text - should
12319 @@ -219,18 +276,26 @@ SECTIONS
12320 PERCPU_VADDR(0, :percpu)
12321 #endif
12322
12323 - .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
12324 + init_begin = .;
12325 + .init.text (. - __KERNEL_TEXT_OFFSET): AT(init_begin - LOAD_OFFSET) {
12326 _sinittext = .;
12327 INIT_TEXT
12328 _einittext = .;
12329 - }
12330 -#ifdef CONFIG_X86_64
12331 - :init
12332 -#endif
12333 + } :text.init
12334 +
12335 + /*
12336 + * .exit.text is discard at runtime, not link time, to deal with
12337 + * references from .altinstructions and .eh_frame
12338 + */
12339 + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
12340 + EXIT_TEXT
12341 + . = ALIGN(16);
12342 + } :text.exit
12343 + . = init_begin + SIZEOF(.init.text) + SIZEOF(.exit.text);
12344
12345 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
12346 INIT_DATA
12347 - }
12348 + } :init
12349
12350 . = ALIGN(16);
12351 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
12352 @@ -276,14 +341,6 @@ SECTIONS
12353 *(.altinstr_replacement)
12354 }
12355
12356 - /*
12357 - * .exit.text is discard at runtime, not link time, to deal with
12358 - * references from .altinstructions and .eh_frame
12359 - */
12360 - .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
12361 - EXIT_TEXT
12362 - }
12363 -
12364 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
12365 EXIT_DATA
12366 }
12367 @@ -297,7 +354,7 @@ SECTIONS
12368 }
12369 #endif
12370
12371 -#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
12372 +#ifndef CONFIG_SMP
12373 PERCPU(PAGE_SIZE)
12374 #endif
12375
12376 @@ -320,12 +377,6 @@ SECTIONS
12377 . = ALIGN(PAGE_SIZE);
12378 }
12379
12380 -#ifdef CONFIG_X86_64
12381 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
12382 - NOSAVE_DATA
12383 - }
12384 -#endif
12385 -
12386 /* BSS */
12387 . = ALIGN(PAGE_SIZE);
12388 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
12389 @@ -341,6 +392,7 @@ SECTIONS
12390 __brk_base = .;
12391 . += 64 * 1024; /* 64k alignment slop space */
12392 *(.brk_reservation) /* areas brk users have reserved */
12393 + . = ALIGN(PMD_SIZE);
12394 __brk_limit = .;
12395 }
12396
12397 @@ -369,13 +421,12 @@ SECTIONS
12398 * for the boot processor.
12399 */
12400 #define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load
12401 -INIT_PER_CPU(gdt_page);
12402 INIT_PER_CPU(irq_stack_union);
12403
12404 /*
12405 * Build-time check on the image size:
12406 */
12407 -. = ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),
12408 +. = ASSERT((_end - _text - __KERNEL_TEXT_OFFSET <= KERNEL_IMAGE_SIZE),
12409 "kernel image bigger than KERNEL_IMAGE_SIZE");
12410
12411 #ifdef CONFIG_SMP
12412 diff -urNp linux-2.6.31.1/arch/x86/kernel/vsyscall_64.c linux-2.6.31.1/arch/x86/kernel/vsyscall_64.c
12413 --- linux-2.6.31.1/arch/x86/kernel/vsyscall_64.c 2009-09-24 11:45:25.000000000 -0400
12414 +++ linux-2.6.31.1/arch/x86/kernel/vsyscall_64.c 2009-10-01 20:12:42.000000000 -0400
12415 @@ -79,6 +79,7 @@ void update_vsyscall(struct timespec *wa
12416
12417 write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags);
12418 /* copy vsyscall data */
12419 + strlcpy(vsyscall_gtod_data.clock.name, clock->name, sizeof vsyscall_gtod_data.clock.name);
12420 vsyscall_gtod_data.clock.vread = clock->vread;
12421 vsyscall_gtod_data.clock.cycle_last = clock->cycle_last;
12422 vsyscall_gtod_data.clock.mask = clock->mask;
12423 @@ -201,7 +202,7 @@ vgetcpu(unsigned *cpu, unsigned *node, s
12424 We do this here because otherwise user space would do it on
12425 its own in a likely inferior way (no access to jiffies).
12426 If you don't like it pass NULL. */
12427 - if (tcache && tcache->blob[0] == (j = __jiffies)) {
12428 + if (tcache && tcache->blob[0] == (j = jiffies)) {
12429 p = tcache->blob[1];
12430 } else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
12431 /* Load per CPU data from RDTSCP */
12432 @@ -240,13 +241,13 @@ static ctl_table kernel_table2[] = {
12433 .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
12434 .mode = 0644,
12435 .proc_handler = vsyscall_sysctl_change },
12436 - {}
12437 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
12438 };
12439
12440 static ctl_table kernel_root_table2[] = {
12441 { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
12442 .child = kernel_table2 },
12443 - {}
12444 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
12445 };
12446 #endif
12447
12448 diff -urNp linux-2.6.31.1/arch/x86/kernel/x8664_ksyms_64.c linux-2.6.31.1/arch/x86/kernel/x8664_ksyms_64.c
12449 --- linux-2.6.31.1/arch/x86/kernel/x8664_ksyms_64.c 2009-09-24 11:45:25.000000000 -0400
12450 +++ linux-2.6.31.1/arch/x86/kernel/x8664_ksyms_64.c 2009-10-01 20:12:42.000000000 -0400
12451 @@ -30,8 +30,6 @@ EXPORT_SYMBOL(__put_user_8);
12452
12453 EXPORT_SYMBOL(copy_user_generic);
12454 EXPORT_SYMBOL(__copy_user_nocache);
12455 -EXPORT_SYMBOL(copy_from_user);
12456 -EXPORT_SYMBOL(copy_to_user);
12457 EXPORT_SYMBOL(__copy_from_user_inatomic);
12458
12459 EXPORT_SYMBOL(copy_page);
12460 diff -urNp linux-2.6.31.1/arch/x86/kvm/svm.c linux-2.6.31.1/arch/x86/kvm/svm.c
12461 --- linux-2.6.31.1/arch/x86/kvm/svm.c 2009-09-24 11:45:25.000000000 -0400
12462 +++ linux-2.6.31.1/arch/x86/kvm/svm.c 2009-10-01 20:12:42.000000000 -0400
12463 @@ -2289,7 +2289,19 @@ static void reload_tss(struct kvm_vcpu *
12464 int cpu = raw_smp_processor_id();
12465
12466 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
12467 +
12468 +#ifdef CONFIG_PAX_KERNEXEC
12469 + unsigned long cr0;
12470 +
12471 + pax_open_kernel(cr0);
12472 +#endif
12473 +
12474 svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
12475 +
12476 +#ifdef CONFIG_PAX_KERNEXEC
12477 + pax_close_kernel(cr0);
12478 +#endif
12479 +
12480 load_TR_desc();
12481 }
12482
12483 @@ -2673,7 +2685,7 @@ static u64 svm_get_mt_mask(struct kvm_vc
12484 return 0;
12485 }
12486
12487 -static struct kvm_x86_ops svm_x86_ops = {
12488 +static const struct kvm_x86_ops svm_x86_ops = {
12489 .cpu_has_kvm_support = has_svm,
12490 .disabled_by_bios = is_disabled,
12491 .hardware_setup = svm_hardware_setup,
12492 diff -urNp linux-2.6.31.1/arch/x86/kvm/vmx.c linux-2.6.31.1/arch/x86/kvm/vmx.c
12493 --- linux-2.6.31.1/arch/x86/kvm/vmx.c 2009-09-24 11:45:25.000000000 -0400
12494 +++ linux-2.6.31.1/arch/x86/kvm/vmx.c 2009-10-01 20:12:42.000000000 -0400
12495 @@ -519,9 +519,23 @@ static void reload_tss(void)
12496 struct descriptor_table gdt;
12497 struct desc_struct *descs;
12498
12499 +#ifdef CONFIG_PAX_KERNEXEC
12500 + unsigned long cr0;
12501 +#endif
12502 +
12503 kvm_get_gdt(&gdt);
12504 descs = (void *)gdt.base;
12505 +
12506 +#ifdef CONFIG_PAX_KERNEXEC
12507 + pax_open_kernel(cr0);
12508 +#endif
12509 +
12510 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
12511 +
12512 +#ifdef CONFIG_PAX_KERNEXEC
12513 + pax_close_kernel(cr0);
12514 +#endif
12515 +
12516 load_TR_desc();
12517 }
12518
12519 @@ -1321,6 +1335,11 @@ static __init int alloc_kvm_area(void)
12520
12521 static __init int hardware_setup(void)
12522 {
12523 +
12524 +#ifdef CONFIG_PAX_KERNEXEC
12525 + unsigned long cr0;
12526 +#endif
12527 +
12528 if (setup_vmcs_config(&vmcs_config) < 0)
12529 return -EIO;
12530
12531 @@ -1336,8 +1355,19 @@ static __init int hardware_setup(void)
12532 if (!cpu_has_vmx_flexpriority())
12533 flexpriority_enabled = 0;
12534
12535 - if (!cpu_has_vmx_tpr_shadow())
12536 - kvm_x86_ops->update_cr8_intercept = NULL;
12537 + if (!cpu_has_vmx_tpr_shadow()) {
12538 +
12539 +#ifdef CONFIG_PAX_KERNEXEC
12540 + pax_open_kernel(cr0);
12541 +#endif
12542 +
12543 + *(void **)&kvm_x86_ops->update_cr8_intercept = NULL;
12544 +
12545 +#ifdef CONFIG_PAX_KERNEXEC
12546 + pax_close_kernel(cr0);
12547 +#endif
12548 +
12549 + }
12550
12551 return alloc_kvm_area();
12552 }
12553 @@ -2239,7 +2269,7 @@ static int vmx_vcpu_setup(struct vcpu_vm
12554 vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */
12555
12556 asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return));
12557 - vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */
12558 + vmcs_writel(HOST_RIP, ktla_ktva(kvm_vmx_return)); /* 22.2.5 */
12559 vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0);
12560 vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0);
12561 vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0);
12562 @@ -3493,6 +3523,12 @@ static void vmx_vcpu_run(struct kvm_vcpu
12563 "jmp .Lkvm_vmx_return \n\t"
12564 ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
12565 ".Lkvm_vmx_return: "
12566 +
12567 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
12568 + "ljmp %[cs],$.Lkvm_vmx_return2\n\t"
12569 + ".Lkvm_vmx_return2: "
12570 +#endif
12571 +
12572 /* Save guest registers, load host registers, keep flags */
12573 "xchg %0, (%%"R"sp) \n\t"
12574 "mov %%"R"ax, %c[rax](%0) \n\t"
12575 @@ -3539,6 +3575,11 @@ static void vmx_vcpu_run(struct kvm_vcpu
12576 [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
12577 #endif
12578 [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
12579 +
12580 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
12581 + ,[cs]"i"(__KERNEL_CS)
12582 +#endif
12583 +
12584 : "cc", "memory"
12585 , R"bx", R"di", R"si"
12586 #ifdef CONFIG_X86_64
12587 @@ -3555,7 +3596,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
12588 if (vmx->rmode.irq.pending)
12589 fixup_rmode_irq(vmx);
12590
12591 - asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
12592 + asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
12593 vmx->launched = 1;
12594
12595 vmx_complete_interrupts(vmx);
12596 @@ -3698,7 +3739,7 @@ static u64 vmx_get_mt_mask(struct kvm_vc
12597 return ret;
12598 }
12599
12600 -static struct kvm_x86_ops vmx_x86_ops = {
12601 +static const struct kvm_x86_ops vmx_x86_ops = {
12602 .cpu_has_kvm_support = cpu_has_kvm_support,
12603 .disabled_by_bios = vmx_disabled_by_bios,
12604 .hardware_setup = hardware_setup,
12605 diff -urNp linux-2.6.31.1/arch/x86/kvm/x86.c linux-2.6.31.1/arch/x86/kvm/x86.c
12606 --- linux-2.6.31.1/arch/x86/kvm/x86.c 2009-09-24 11:45:25.000000000 -0400
12607 +++ linux-2.6.31.1/arch/x86/kvm/x86.c 2009-10-01 20:12:42.000000000 -0400
12608 @@ -73,42 +73,42 @@ static int kvm_dev_ioctl_get_supported_c
12609 struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
12610 u32 function, u32 index);
12611
12612 -struct kvm_x86_ops *kvm_x86_ops;
12613 +const struct kvm_x86_ops *kvm_x86_ops;
12614 EXPORT_SYMBOL_GPL(kvm_x86_ops);
12615
12616 struct kvm_stats_debugfs_item debugfs_entries[] = {
12617 - { "pf_fixed", VCPU_STAT(pf_fixed) },
12618 - { "pf_guest", VCPU_STAT(pf_guest) },
12619 - { "tlb_flush", VCPU_STAT(tlb_flush) },
12620 - { "invlpg", VCPU_STAT(invlpg) },
12621 - { "exits", VCPU_STAT(exits) },
12622 - { "io_exits", VCPU_STAT(io_exits) },
12623 - { "mmio_exits", VCPU_STAT(mmio_exits) },
12624 - { "signal_exits", VCPU_STAT(signal_exits) },
12625 - { "irq_window", VCPU_STAT(irq_window_exits) },
12626 - { "nmi_window", VCPU_STAT(nmi_window_exits) },
12627 - { "halt_exits", VCPU_STAT(halt_exits) },
12628 - { "halt_wakeup", VCPU_STAT(halt_wakeup) },
12629 - { "hypercalls", VCPU_STAT(hypercalls) },
12630 - { "request_irq", VCPU_STAT(request_irq_exits) },
12631 - { "irq_exits", VCPU_STAT(irq_exits) },
12632 - { "host_state_reload", VCPU_STAT(host_state_reload) },
12633 - { "efer_reload", VCPU_STAT(efer_reload) },
12634 - { "fpu_reload", VCPU_STAT(fpu_reload) },
12635 - { "insn_emulation", VCPU_STAT(insn_emulation) },
12636 - { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
12637 - { "irq_injections", VCPU_STAT(irq_injections) },
12638 - { "nmi_injections", VCPU_STAT(nmi_injections) },
12639 - { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
12640 - { "mmu_pte_write", VM_STAT(mmu_pte_write) },
12641 - { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
12642 - { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
12643 - { "mmu_flooded", VM_STAT(mmu_flooded) },
12644 - { "mmu_recycled", VM_STAT(mmu_recycled) },
12645 - { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
12646 - { "mmu_unsync", VM_STAT(mmu_unsync) },
12647 - { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
12648 - { "largepages", VM_STAT(lpages) },
12649 + { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
12650 + { "pf_guest", VCPU_STAT(pf_guest), NULL },
12651 + { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
12652 + { "invlpg", VCPU_STAT(invlpg), NULL },
12653 + { "exits", VCPU_STAT(exits), NULL },
12654 + { "io_exits", VCPU_STAT(io_exits), NULL },
12655 + { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
12656 + { "signal_exits", VCPU_STAT(signal_exits), NULL },
12657 + { "irq_window", VCPU_STAT(irq_window_exits), NULL },
12658 + { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
12659 + { "halt_exits", VCPU_STAT(halt_exits), NULL },
12660 + { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
12661 + { "hypercalls", VCPU_STAT(hypercalls), NULL },
12662 + { "request_irq", VCPU_STAT(request_irq_exits), NULL },
12663 + { "irq_exits", VCPU_STAT(irq_exits), NULL },
12664 + { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
12665 + { "efer_reload", VCPU_STAT(efer_reload), NULL },
12666 + { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
12667 + { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
12668 + { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
12669 + { "irq_injections", VCPU_STAT(irq_injections), NULL },
12670 + { "nmi_injections", VCPU_STAT(nmi_injections), NULL },
12671 + { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
12672 + { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
12673 + { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
12674 + { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
12675 + { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
12676 + { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
12677 + { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
12678 + { "mmu_unsync", VM_STAT(mmu_unsync), NULL },
12679 + { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
12680 + { "largepages", VM_STAT(lpages), NULL },
12681 { NULL }
12682 };
12683
12684 @@ -1485,7 +1485,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
12685 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
12686 struct kvm_interrupt *irq)
12687 {
12688 - if (irq->irq < 0 || irq->irq >= 256)
12689 + if (irq->irq >= 256)
12690 return -EINVAL;
12691 if (irqchip_in_kernel(vcpu->kvm))
12692 return -ENXIO;
12693 @@ -2810,10 +2810,10 @@ static struct notifier_block kvmclock_cp
12694 .notifier_call = kvmclock_cpufreq_notifier
12695 };
12696
12697 -int kvm_arch_init(void *opaque)
12698 +int kvm_arch_init(const void *opaque)
12699 {
12700 int r, cpu;
12701 - struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
12702 + const struct kvm_x86_ops *ops = (const struct kvm_x86_ops *)opaque;
12703
12704 if (kvm_x86_ops) {
12705 printk(KERN_ERR "kvm: already loaded the other module\n");
12706 diff -urNp linux-2.6.31.1/arch/x86/lib/checksum_32.S linux-2.6.31.1/arch/x86/lib/checksum_32.S
12707 --- linux-2.6.31.1/arch/x86/lib/checksum_32.S 2009-09-24 11:45:25.000000000 -0400
12708 +++ linux-2.6.31.1/arch/x86/lib/checksum_32.S 2009-10-01 20:12:42.000000000 -0400
12709 @@ -28,7 +28,8 @@
12710 #include <linux/linkage.h>
12711 #include <asm/dwarf2.h>
12712 #include <asm/errno.h>
12713 -
12714 +#include <asm/segment.h>
12715 +
12716 /*
12717 * computes a partial checksum, e.g. for TCP/UDP fragments
12718 */
12719 @@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
12720
12721 #define ARGBASE 16
12722 #define FP 12
12723 -
12724 -ENTRY(csum_partial_copy_generic)
12725 +
12726 +ENTRY(csum_partial_copy_generic_to_user)
12727 CFI_STARTPROC
12728 + pushl $(__USER_DS)
12729 + CFI_ADJUST_CFA_OFFSET 4
12730 + popl %es
12731 + CFI_ADJUST_CFA_OFFSET -4
12732 + jmp csum_partial_copy_generic
12733 +
12734 +ENTRY(csum_partial_copy_generic_from_user)
12735 + pushl $(__USER_DS)
12736 + CFI_ADJUST_CFA_OFFSET 4
12737 + popl %ds
12738 + CFI_ADJUST_CFA_OFFSET -4
12739 +
12740 +ENTRY(csum_partial_copy_generic)
12741 subl $4,%esp
12742 CFI_ADJUST_CFA_OFFSET 4
12743 pushl %edi
12744 @@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
12745 jmp 4f
12746 SRC(1: movw (%esi), %bx )
12747 addl $2, %esi
12748 -DST( movw %bx, (%edi) )
12749 +DST( movw %bx, %es:(%edi) )
12750 addl $2, %edi
12751 addw %bx, %ax
12752 adcl $0, %eax
12753 @@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
12754 SRC(1: movl (%esi), %ebx )
12755 SRC( movl 4(%esi), %edx )
12756 adcl %ebx, %eax
12757 -DST( movl %ebx, (%edi) )
12758 +DST( movl %ebx, %es:(%edi) )
12759 adcl %edx, %eax
12760 -DST( movl %edx, 4(%edi) )
12761 +DST( movl %edx, %es:4(%edi) )
12762
12763 SRC( movl 8(%esi), %ebx )
12764 SRC( movl 12(%esi), %edx )
12765 adcl %ebx, %eax
12766 -DST( movl %ebx, 8(%edi) )
12767 +DST( movl %ebx, %es:8(%edi) )
12768 adcl %edx, %eax
12769 -DST( movl %edx, 12(%edi) )
12770 +DST( movl %edx, %es:12(%edi) )
12771
12772 SRC( movl 16(%esi), %ebx )
12773 SRC( movl 20(%esi), %edx )
12774 adcl %ebx, %eax
12775 -DST( movl %ebx, 16(%edi) )
12776 +DST( movl %ebx, %es:16(%edi) )
12777 adcl %edx, %eax
12778 -DST( movl %edx, 20(%edi) )
12779 +DST( movl %edx, %es:20(%edi) )
12780
12781 SRC( movl 24(%esi), %ebx )
12782 SRC( movl 28(%esi), %edx )
12783 adcl %ebx, %eax
12784 -DST( movl %ebx, 24(%edi) )
12785 +DST( movl %ebx, %es:24(%edi) )
12786 adcl %edx, %eax
12787 -DST( movl %edx, 28(%edi) )
12788 +DST( movl %edx, %es:28(%edi) )
12789
12790 lea 32(%esi), %esi
12791 lea 32(%edi), %edi
12792 @@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
12793 shrl $2, %edx # This clears CF
12794 SRC(3: movl (%esi), %ebx )
12795 adcl %ebx, %eax
12796 -DST( movl %ebx, (%edi) )
12797 +DST( movl %ebx, %es:(%edi) )
12798 lea 4(%esi), %esi
12799 lea 4(%edi), %edi
12800 dec %edx
12801 @@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
12802 jb 5f
12803 SRC( movw (%esi), %cx )
12804 leal 2(%esi), %esi
12805 -DST( movw %cx, (%edi) )
12806 +DST( movw %cx, %es:(%edi) )
12807 leal 2(%edi), %edi
12808 je 6f
12809 shll $16,%ecx
12810 SRC(5: movb (%esi), %cl )
12811 -DST( movb %cl, (%edi) )
12812 +DST( movb %cl, %es:(%edi) )
12813 6: addl %ecx, %eax
12814 adcl $0, %eax
12815 7:
12816 @@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
12817
12818 6001:
12819 movl ARGBASE+20(%esp), %ebx # src_err_ptr
12820 - movl $-EFAULT, (%ebx)
12821 + movl $-EFAULT, %ss:(%ebx)
12822
12823 # zero the complete destination - computing the rest
12824 # is too much work
12825 @@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
12826
12827 6002:
12828 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
12829 - movl $-EFAULT,(%ebx)
12830 + movl $-EFAULT,%ss:(%ebx)
12831 jmp 5000b
12832
12833 .previous
12834
12835 + pushl %ss
12836 + CFI_ADJUST_CFA_OFFSET 4
12837 + popl %ds
12838 + CFI_ADJUST_CFA_OFFSET -4
12839 + pushl %ss
12840 + CFI_ADJUST_CFA_OFFSET 4
12841 + popl %es
12842 + CFI_ADJUST_CFA_OFFSET -4
12843 popl %ebx
12844 CFI_ADJUST_CFA_OFFSET -4
12845 CFI_RESTORE ebx
12846 @@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
12847 CFI_ADJUST_CFA_OFFSET -4
12848 ret
12849 CFI_ENDPROC
12850 -ENDPROC(csum_partial_copy_generic)
12851 +ENDPROC(csum_partial_copy_generic_to_user)
12852
12853 #else
12854
12855 /* Version for PentiumII/PPro */
12856
12857 #define ROUND1(x) \
12858 + nop; nop; nop; \
12859 SRC(movl x(%esi), %ebx ) ; \
12860 addl %ebx, %eax ; \
12861 - DST(movl %ebx, x(%edi) ) ;
12862 + DST(movl %ebx, %es:x(%edi)) ;
12863
12864 #define ROUND(x) \
12865 + nop; nop; nop; \
12866 SRC(movl x(%esi), %ebx ) ; \
12867 adcl %ebx, %eax ; \
12868 - DST(movl %ebx, x(%edi) ) ;
12869 + DST(movl %ebx, %es:x(%edi)) ;
12870
12871 #define ARGBASE 12
12872 -
12873 -ENTRY(csum_partial_copy_generic)
12874 +
12875 +ENTRY(csum_partial_copy_generic_to_user)
12876 CFI_STARTPROC
12877 + pushl $(__USER_DS)
12878 + CFI_ADJUST_CFA_OFFSET 4
12879 + popl %es
12880 + CFI_ADJUST_CFA_OFFSET -4
12881 + jmp csum_partial_copy_generic
12882 +
12883 +ENTRY(csum_partial_copy_generic_from_user)
12884 + pushl $(__USER_DS)
12885 + CFI_ADJUST_CFA_OFFSET 4
12886 + popl %ds
12887 + CFI_ADJUST_CFA_OFFSET -4
12888 +
12889 +ENTRY(csum_partial_copy_generic)
12890 pushl %ebx
12891 CFI_ADJUST_CFA_OFFSET 4
12892 CFI_REL_OFFSET ebx, 0
12893 @@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
12894 subl %ebx, %edi
12895 lea -1(%esi),%edx
12896 andl $-32,%edx
12897 - lea 3f(%ebx,%ebx), %ebx
12898 + lea 3f(%ebx,%ebx,2), %ebx
12899 testl %esi, %esi
12900 jmp *%ebx
12901 1: addl $64,%esi
12902 @@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
12903 jb 5f
12904 SRC( movw (%esi), %dx )
12905 leal 2(%esi), %esi
12906 -DST( movw %dx, (%edi) )
12907 +DST( movw %dx, %es:(%edi) )
12908 leal 2(%edi), %edi
12909 je 6f
12910 shll $16,%edx
12911 5:
12912 SRC( movb (%esi), %dl )
12913 -DST( movb %dl, (%edi) )
12914 +DST( movb %dl, %es:(%edi) )
12915 6: addl %edx, %eax
12916 adcl $0, %eax
12917 7:
12918 .section .fixup, "ax"
12919 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
12920 - movl $-EFAULT, (%ebx)
12921 + movl $-EFAULT, %ss:(%ebx)
12922 # zero the complete destination (computing the rest is too much work)
12923 movl ARGBASE+8(%esp),%edi # dst
12924 movl ARGBASE+12(%esp),%ecx # len
12925 @@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
12926 rep; stosb
12927 jmp 7b
12928 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
12929 - movl $-EFAULT, (%ebx)
12930 + movl $-EFAULT, %ss:(%ebx)
12931 jmp 7b
12932 .previous
12933
12934 + pushl %ss
12935 + CFI_ADJUST_CFA_OFFSET 4
12936 + popl %ds
12937 + CFI_ADJUST_CFA_OFFSET -4
12938 + pushl %ss
12939 + CFI_ADJUST_CFA_OFFSET 4
12940 + popl %es
12941 + CFI_ADJUST_CFA_OFFSET -4
12942 popl %esi
12943 CFI_ADJUST_CFA_OFFSET -4
12944 CFI_RESTORE esi
12945 @@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
12946 CFI_RESTORE ebx
12947 ret
12948 CFI_ENDPROC
12949 -ENDPROC(csum_partial_copy_generic)
12950 +ENDPROC(csum_partial_copy_generic_to_user)
12951
12952 #undef ROUND
12953 #undef ROUND1
12954 diff -urNp linux-2.6.31.1/arch/x86/lib/clear_page_64.S linux-2.6.31.1/arch/x86/lib/clear_page_64.S
12955 --- linux-2.6.31.1/arch/x86/lib/clear_page_64.S 2009-09-24 11:45:25.000000000 -0400
12956 +++ linux-2.6.31.1/arch/x86/lib/clear_page_64.S 2009-10-01 20:12:42.000000000 -0400
12957 @@ -43,7 +43,7 @@ ENDPROC(clear_page)
12958
12959 #include <asm/cpufeature.h>
12960
12961 - .section .altinstr_replacement,"ax"
12962 + .section .altinstr_replacement,"a"
12963 1: .byte 0xeb /* jmp <disp8> */
12964 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
12965 2:
12966 diff -urNp linux-2.6.31.1/arch/x86/lib/copy_page_64.S linux-2.6.31.1/arch/x86/lib/copy_page_64.S
12967 --- linux-2.6.31.1/arch/x86/lib/copy_page_64.S 2009-09-24 11:45:25.000000000 -0400
12968 +++ linux-2.6.31.1/arch/x86/lib/copy_page_64.S 2009-10-01 20:12:42.000000000 -0400
12969 @@ -104,7 +104,7 @@ ENDPROC(copy_page)
12970
12971 #include <asm/cpufeature.h>
12972
12973 - .section .altinstr_replacement,"ax"
12974 + .section .altinstr_replacement,"a"
12975 1: .byte 0xeb /* jmp <disp8> */
12976 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
12977 2:
12978 diff -urNp linux-2.6.31.1/arch/x86/lib/copy_user_64.S linux-2.6.31.1/arch/x86/lib/copy_user_64.S
12979 --- linux-2.6.31.1/arch/x86/lib/copy_user_64.S 2009-09-24 11:45:25.000000000 -0400
12980 +++ linux-2.6.31.1/arch/x86/lib/copy_user_64.S 2009-10-01 20:12:42.000000000 -0400
12981 @@ -21,7 +21,7 @@
12982 .byte 0xe9 /* 32bit jump */
12983 .long \orig-1f /* by default jump to orig */
12984 1:
12985 - .section .altinstr_replacement,"ax"
12986 + .section .altinstr_replacement,"a"
12987 2: .byte 0xe9 /* near jump with 32bit immediate */
12988 .long \alt-1b /* offset */ /* or alternatively to alt */
12989 .previous
12990 @@ -64,32 +64,6 @@
12991 #endif
12992 .endm
12993
12994 -/* Standard copy_to_user with segment limit checking */
12995 -ENTRY(copy_to_user)
12996 - CFI_STARTPROC
12997 - GET_THREAD_INFO(%rax)
12998 - movq %rdi,%rcx
12999 - addq %rdx,%rcx
13000 - jc bad_to_user
13001 - cmpq TI_addr_limit(%rax),%rcx
13002 - jae bad_to_user
13003 - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
13004 - CFI_ENDPROC
13005 -ENDPROC(copy_to_user)
13006 -
13007 -/* Standard copy_from_user with segment limit checking */
13008 -ENTRY(copy_from_user)
13009 - CFI_STARTPROC
13010 - GET_THREAD_INFO(%rax)
13011 - movq %rsi,%rcx
13012 - addq %rdx,%rcx
13013 - jc bad_from_user
13014 - cmpq TI_addr_limit(%rax),%rcx
13015 - jae bad_from_user
13016 - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
13017 - CFI_ENDPROC
13018 -ENDPROC(copy_from_user)
13019 -
13020 ENTRY(copy_user_generic)
13021 CFI_STARTPROC
13022 ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
13023 @@ -107,6 +81,8 @@ ENDPROC(__copy_from_user_inatomic)
13024 ENTRY(bad_from_user)
13025 bad_from_user:
13026 CFI_STARTPROC
13027 + testl %edx,%edx
13028 + js bad_to_user
13029 movl %edx,%ecx
13030 xorl %eax,%eax
13031 rep
13032 diff -urNp linux-2.6.31.1/arch/x86/lib/getuser.S linux-2.6.31.1/arch/x86/lib/getuser.S
13033 --- linux-2.6.31.1/arch/x86/lib/getuser.S 2009-09-24 11:45:25.000000000 -0400
13034 +++ linux-2.6.31.1/arch/x86/lib/getuser.S 2009-10-01 20:12:42.000000000 -0400
13035 @@ -33,6 +33,7 @@
13036 #include <asm/asm-offsets.h>
13037 #include <asm/thread_info.h>
13038 #include <asm/asm.h>
13039 +#include <asm/segment.h>
13040
13041 .text
13042 ENTRY(__get_user_1)
13043 @@ -40,7 +41,19 @@ ENTRY(__get_user_1)
13044 GET_THREAD_INFO(%_ASM_DX)
13045 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
13046 jae bad_get_user
13047 +
13048 +#ifdef CONFIG_X86_32
13049 + pushl $(__USER_DS)
13050 + popl %ds
13051 +#endif
13052 +
13053 1: movzb (%_ASM_AX),%edx
13054 +
13055 +#ifdef CONFIG_X86_32
13056 + pushl %ss
13057 + pop %ds
13058 +#endif
13059 +
13060 xor %eax,%eax
13061 ret
13062 CFI_ENDPROC
13063 @@ -53,7 +66,19 @@ ENTRY(__get_user_2)
13064 GET_THREAD_INFO(%_ASM_DX)
13065 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
13066 jae bad_get_user
13067 +
13068 +#ifdef CONFIG_X86_32
13069 + pushl $(__USER_DS)
13070 + popl %ds
13071 +#endif
13072 +
13073 2: movzwl -1(%_ASM_AX),%edx
13074 +
13075 +#ifdef CONFIG_X86_32
13076 + pushl %ss
13077 + pop %ds
13078 +#endif
13079 +
13080 xor %eax,%eax
13081 ret
13082 CFI_ENDPROC
13083 @@ -66,7 +91,19 @@ ENTRY(__get_user_4)
13084 GET_THREAD_INFO(%_ASM_DX)
13085 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
13086 jae bad_get_user
13087 +
13088 +#ifdef CONFIG_X86_32
13089 + pushl $(__USER_DS)
13090 + popl %ds
13091 +#endif
13092 +
13093 3: mov -3(%_ASM_AX),%edx
13094 +
13095 +#ifdef CONFIG_X86_32
13096 + pushl %ss
13097 + pop %ds
13098 +#endif
13099 +
13100 xor %eax,%eax
13101 ret
13102 CFI_ENDPROC
13103 @@ -89,6 +126,12 @@ ENDPROC(__get_user_8)
13104
13105 bad_get_user:
13106 CFI_STARTPROC
13107 +
13108 +#ifdef CONFIG_X86_32
13109 + pushl %ss
13110 + pop %ds
13111 +#endif
13112 +
13113 xor %edx,%edx
13114 mov $(-EFAULT),%_ASM_AX
13115 ret
13116 diff -urNp linux-2.6.31.1/arch/x86/lib/memcpy_64.S linux-2.6.31.1/arch/x86/lib/memcpy_64.S
13117 --- linux-2.6.31.1/arch/x86/lib/memcpy_64.S 2009-09-24 11:45:25.000000000 -0400
13118 +++ linux-2.6.31.1/arch/x86/lib/memcpy_64.S 2009-10-01 20:12:42.000000000 -0400
13119 @@ -128,7 +128,7 @@ ENDPROC(__memcpy)
13120 * It is also a lot simpler. Use this when possible:
13121 */
13122
13123 - .section .altinstr_replacement, "ax"
13124 + .section .altinstr_replacement, "a"
13125 1: .byte 0xeb /* jmp <disp8> */
13126 .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
13127 2:
13128 diff -urNp linux-2.6.31.1/arch/x86/lib/memset_64.S linux-2.6.31.1/arch/x86/lib/memset_64.S
13129 --- linux-2.6.31.1/arch/x86/lib/memset_64.S 2009-09-24 11:45:25.000000000 -0400
13130 +++ linux-2.6.31.1/arch/x86/lib/memset_64.S 2009-10-01 20:12:42.000000000 -0400
13131 @@ -118,7 +118,7 @@ ENDPROC(__memset)
13132
13133 #include <asm/cpufeature.h>
13134
13135 - .section .altinstr_replacement,"ax"
13136 + .section .altinstr_replacement,"a"
13137 1: .byte 0xeb /* jmp <disp8> */
13138 .byte (memset_c - memset) - (2f - 1b) /* offset */
13139 2:
13140 diff -urNp linux-2.6.31.1/arch/x86/lib/mmx_32.c linux-2.6.31.1/arch/x86/lib/mmx_32.c
13141 --- linux-2.6.31.1/arch/x86/lib/mmx_32.c 2009-09-24 11:45:25.000000000 -0400
13142 +++ linux-2.6.31.1/arch/x86/lib/mmx_32.c 2009-10-01 20:12:42.000000000 -0400
13143 @@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
13144 {
13145 void *p;
13146 int i;
13147 + unsigned long cr0;
13148
13149 if (unlikely(in_interrupt()))
13150 return __memcpy(to, from, len);
13151 @@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
13152 kernel_fpu_begin();
13153
13154 __asm__ __volatile__ (
13155 - "1: prefetch (%0)\n" /* This set is 28 bytes */
13156 - " prefetch 64(%0)\n"
13157 - " prefetch 128(%0)\n"
13158 - " prefetch 192(%0)\n"
13159 - " prefetch 256(%0)\n"
13160 + "1: prefetch (%1)\n" /* This set is 28 bytes */
13161 + " prefetch 64(%1)\n"
13162 + " prefetch 128(%1)\n"
13163 + " prefetch 192(%1)\n"
13164 + " prefetch 256(%1)\n"
13165 "2: \n"
13166 ".section .fixup, \"ax\"\n"
13167 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13168 + "3: \n"
13169 +
13170 +#ifdef CONFIG_PAX_KERNEXEC
13171 + " movl %%cr0, %0\n"
13172 + " movl %0, %%eax\n"
13173 + " andl $0xFFFEFFFF, %%eax\n"
13174 + " movl %%eax, %%cr0\n"
13175 +#endif
13176 +
13177 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13178 +
13179 +#ifdef CONFIG_PAX_KERNEXEC
13180 + " movl %0, %%cr0\n"
13181 +#endif
13182 +
13183 " jmp 2b\n"
13184 ".previous\n"
13185 _ASM_EXTABLE(1b, 3b)
13186 - : : "r" (from));
13187 + : "=&r" (cr0) : "r" (from) : "ax");
13188
13189 for ( ; i > 5; i--) {
13190 __asm__ __volatile__ (
13191 - "1: prefetch 320(%0)\n"
13192 - "2: movq (%0), %%mm0\n"
13193 - " movq 8(%0), %%mm1\n"
13194 - " movq 16(%0), %%mm2\n"
13195 - " movq 24(%0), %%mm3\n"
13196 - " movq %%mm0, (%1)\n"
13197 - " movq %%mm1, 8(%1)\n"
13198 - " movq %%mm2, 16(%1)\n"
13199 - " movq %%mm3, 24(%1)\n"
13200 - " movq 32(%0), %%mm0\n"
13201 - " movq 40(%0), %%mm1\n"
13202 - " movq 48(%0), %%mm2\n"
13203 - " movq 56(%0), %%mm3\n"
13204 - " movq %%mm0, 32(%1)\n"
13205 - " movq %%mm1, 40(%1)\n"
13206 - " movq %%mm2, 48(%1)\n"
13207 - " movq %%mm3, 56(%1)\n"
13208 + "1: prefetch 320(%1)\n"
13209 + "2: movq (%1), %%mm0\n"
13210 + " movq 8(%1), %%mm1\n"
13211 + " movq 16(%1), %%mm2\n"
13212 + " movq 24(%1), %%mm3\n"
13213 + " movq %%mm0, (%2)\n"
13214 + " movq %%mm1, 8(%2)\n"
13215 + " movq %%mm2, 16(%2)\n"
13216 + " movq %%mm3, 24(%2)\n"
13217 + " movq 32(%1), %%mm0\n"
13218 + " movq 40(%1), %%mm1\n"
13219 + " movq 48(%1), %%mm2\n"
13220 + " movq 56(%1), %%mm3\n"
13221 + " movq %%mm0, 32(%2)\n"
13222 + " movq %%mm1, 40(%2)\n"
13223 + " movq %%mm2, 48(%2)\n"
13224 + " movq %%mm3, 56(%2)\n"
13225 ".section .fixup, \"ax\"\n"
13226 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13227 + "3:\n"
13228 +
13229 +#ifdef CONFIG_PAX_KERNEXEC
13230 + " movl %%cr0, %0\n"
13231 + " movl %0, %%eax\n"
13232 + " andl $0xFFFEFFFF, %%eax\n"
13233 + " movl %%eax, %%cr0\n"
13234 +#endif
13235 +
13236 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13237 +
13238 +#ifdef CONFIG_PAX_KERNEXEC
13239 + " movl %0, %%cr0\n"
13240 +#endif
13241 +
13242 " jmp 2b\n"
13243 ".previous\n"
13244 _ASM_EXTABLE(1b, 3b)
13245 - : : "r" (from), "r" (to) : "memory");
13246 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
13247
13248 from += 64;
13249 to += 64;
13250 @@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
13251 static void fast_copy_page(void *to, void *from)
13252 {
13253 int i;
13254 + unsigned long cr0;
13255
13256 kernel_fpu_begin();
13257
13258 @@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
13259 * but that is for later. -AV
13260 */
13261 __asm__ __volatile__(
13262 - "1: prefetch (%0)\n"
13263 - " prefetch 64(%0)\n"
13264 - " prefetch 128(%0)\n"
13265 - " prefetch 192(%0)\n"
13266 - " prefetch 256(%0)\n"
13267 + "1: prefetch (%1)\n"
13268 + " prefetch 64(%1)\n"
13269 + " prefetch 128(%1)\n"
13270 + " prefetch 192(%1)\n"
13271 + " prefetch 256(%1)\n"
13272 "2: \n"
13273 ".section .fixup, \"ax\"\n"
13274 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13275 + "3: \n"
13276 +
13277 +#ifdef CONFIG_PAX_KERNEXEC
13278 + " movl %%cr0, %0\n"
13279 + " movl %0, %%eax\n"
13280 + " andl $0xFFFEFFFF, %%eax\n"
13281 + " movl %%eax, %%cr0\n"
13282 +#endif
13283 +
13284 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13285 +
13286 +#ifdef CONFIG_PAX_KERNEXEC
13287 + " movl %0, %%cr0\n"
13288 +#endif
13289 +
13290 " jmp 2b\n"
13291 ".previous\n"
13292 - _ASM_EXTABLE(1b, 3b) : : "r" (from));
13293 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
13294
13295 for (i = 0; i < (4096-320)/64; i++) {
13296 __asm__ __volatile__ (
13297 - "1: prefetch 320(%0)\n"
13298 - "2: movq (%0), %%mm0\n"
13299 - " movntq %%mm0, (%1)\n"
13300 - " movq 8(%0), %%mm1\n"
13301 - " movntq %%mm1, 8(%1)\n"
13302 - " movq 16(%0), %%mm2\n"
13303 - " movntq %%mm2, 16(%1)\n"
13304 - " movq 24(%0), %%mm3\n"
13305 - " movntq %%mm3, 24(%1)\n"
13306 - " movq 32(%0), %%mm4\n"
13307 - " movntq %%mm4, 32(%1)\n"
13308 - " movq 40(%0), %%mm5\n"
13309 - " movntq %%mm5, 40(%1)\n"
13310 - " movq 48(%0), %%mm6\n"
13311 - " movntq %%mm6, 48(%1)\n"
13312 - " movq 56(%0), %%mm7\n"
13313 - " movntq %%mm7, 56(%1)\n"
13314 + "1: prefetch 320(%1)\n"
13315 + "2: movq (%1), %%mm0\n"
13316 + " movntq %%mm0, (%2)\n"
13317 + " movq 8(%1), %%mm1\n"
13318 + " movntq %%mm1, 8(%2)\n"
13319 + " movq 16(%1), %%mm2\n"
13320 + " movntq %%mm2, 16(%2)\n"
13321 + " movq 24(%1), %%mm3\n"
13322 + " movntq %%mm3, 24(%2)\n"
13323 + " movq 32(%1), %%mm4\n"
13324 + " movntq %%mm4, 32(%2)\n"
13325 + " movq 40(%1), %%mm5\n"
13326 + " movntq %%mm5, 40(%2)\n"
13327 + " movq 48(%1), %%mm6\n"
13328 + " movntq %%mm6, 48(%2)\n"
13329 + " movq 56(%1), %%mm7\n"
13330 + " movntq %%mm7, 56(%2)\n"
13331 ".section .fixup, \"ax\"\n"
13332 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13333 + "3:\n"
13334 +
13335 +#ifdef CONFIG_PAX_KERNEXEC
13336 + " movl %%cr0, %0\n"
13337 + " movl %0, %%eax\n"
13338 + " andl $0xFFFEFFFF, %%eax\n"
13339 + " movl %%eax, %%cr0\n"
13340 +#endif
13341 +
13342 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13343 +
13344 +#ifdef CONFIG_PAX_KERNEXEC
13345 + " movl %0, %%cr0\n"
13346 +#endif
13347 +
13348 " jmp 2b\n"
13349 ".previous\n"
13350 - _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
13351 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
13352
13353 from += 64;
13354 to += 64;
13355 @@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
13356 static void fast_copy_page(void *to, void *from)
13357 {
13358 int i;
13359 + unsigned long cr0;
13360
13361 kernel_fpu_begin();
13362
13363 __asm__ __volatile__ (
13364 - "1: prefetch (%0)\n"
13365 - " prefetch 64(%0)\n"
13366 - " prefetch 128(%0)\n"
13367 - " prefetch 192(%0)\n"
13368 - " prefetch 256(%0)\n"
13369 + "1: prefetch (%1)\n"
13370 + " prefetch 64(%1)\n"
13371 + " prefetch 128(%1)\n"
13372 + " prefetch 192(%1)\n"
13373 + " prefetch 256(%1)\n"
13374 "2: \n"
13375 ".section .fixup, \"ax\"\n"
13376 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13377 + "3: \n"
13378 +
13379 +#ifdef CONFIG_PAX_KERNEXEC
13380 + " movl %%cr0, %0\n"
13381 + " movl %0, %%eax\n"
13382 + " andl $0xFFFEFFFF, %%eax\n"
13383 + " movl %%eax, %%cr0\n"
13384 +#endif
13385 +
13386 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13387 +
13388 +#ifdef CONFIG_PAX_KERNEXEC
13389 + " movl %0, %%cr0\n"
13390 +#endif
13391 +
13392 " jmp 2b\n"
13393 ".previous\n"
13394 - _ASM_EXTABLE(1b, 3b) : : "r" (from));
13395 + _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
13396
13397 for (i = 0; i < 4096/64; i++) {
13398 __asm__ __volatile__ (
13399 - "1: prefetch 320(%0)\n"
13400 - "2: movq (%0), %%mm0\n"
13401 - " movq 8(%0), %%mm1\n"
13402 - " movq 16(%0), %%mm2\n"
13403 - " movq 24(%0), %%mm3\n"
13404 - " movq %%mm0, (%1)\n"
13405 - " movq %%mm1, 8(%1)\n"
13406 - " movq %%mm2, 16(%1)\n"
13407 - " movq %%mm3, 24(%1)\n"
13408 - " movq 32(%0), %%mm0\n"
13409 - " movq 40(%0), %%mm1\n"
13410 - " movq 48(%0), %%mm2\n"
13411 - " movq 56(%0), %%mm3\n"
13412 - " movq %%mm0, 32(%1)\n"
13413 - " movq %%mm1, 40(%1)\n"
13414 - " movq %%mm2, 48(%1)\n"
13415 - " movq %%mm3, 56(%1)\n"
13416 + "1: prefetch 320(%1)\n"
13417 + "2: movq (%1), %%mm0\n"
13418 + " movq 8(%1), %%mm1\n"
13419 + " movq 16(%1), %%mm2\n"
13420 + " movq 24(%1), %%mm3\n"
13421 + " movq %%mm0, (%2)\n"
13422 + " movq %%mm1, 8(%2)\n"
13423 + " movq %%mm2, 16(%2)\n"
13424 + " movq %%mm3, 24(%2)\n"
13425 + " movq 32(%1), %%mm0\n"
13426 + " movq 40(%1), %%mm1\n"
13427 + " movq 48(%1), %%mm2\n"
13428 + " movq 56(%1), %%mm3\n"
13429 + " movq %%mm0, 32(%2)\n"
13430 + " movq %%mm1, 40(%2)\n"
13431 + " movq %%mm2, 48(%2)\n"
13432 + " movq %%mm3, 56(%2)\n"
13433 ".section .fixup, \"ax\"\n"
13434 - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13435 + "3:\n"
13436 +
13437 +#ifdef CONFIG_PAX_KERNEXEC
13438 + " movl %%cr0, %0\n"
13439 + " movl %0, %%eax\n"
13440 + " andl $0xFFFEFFFF, %%eax\n"
13441 + " movl %%eax, %%cr0\n"
13442 +#endif
13443 +
13444 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13445 +
13446 +#ifdef CONFIG_PAX_KERNEXEC
13447 + " movl %0, %%cr0\n"
13448 +#endif
13449 +
13450 " jmp 2b\n"
13451 ".previous\n"
13452 _ASM_EXTABLE(1b, 3b)
13453 - : : "r" (from), "r" (to) : "memory");
13454 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
13455
13456 from += 64;
13457 to += 64;
13458 diff -urNp linux-2.6.31.1/arch/x86/lib/putuser.S linux-2.6.31.1/arch/x86/lib/putuser.S
13459 --- linux-2.6.31.1/arch/x86/lib/putuser.S 2009-09-24 11:45:25.000000000 -0400
13460 +++ linux-2.6.31.1/arch/x86/lib/putuser.S 2009-10-01 20:12:42.000000000 -0400
13461 @@ -15,6 +15,7 @@
13462 #include <asm/thread_info.h>
13463 #include <asm/errno.h>
13464 #include <asm/asm.h>
13465 +#include <asm/segment.h>
13466
13467
13468 /*
13469 @@ -39,7 +40,19 @@ ENTRY(__put_user_1)
13470 ENTER
13471 cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
13472 jae bad_put_user
13473 +
13474 +#ifdef CONFIG_X86_32
13475 + pushl $(__USER_DS)
13476 + popl %ds
13477 +#endif
13478 +
13479 1: movb %al,(%_ASM_CX)
13480 +
13481 +#ifdef CONFIG_X86_32
13482 + pushl %ss
13483 + popl %ds
13484 +#endif
13485 +
13486 xor %eax,%eax
13487 EXIT
13488 ENDPROC(__put_user_1)
13489 @@ -50,7 +63,19 @@ ENTRY(__put_user_2)
13490 sub $1,%_ASM_BX
13491 cmp %_ASM_BX,%_ASM_CX
13492 jae bad_put_user
13493 +
13494 +#ifdef CONFIG_X86_32
13495 + pushl $(__USER_DS)
13496 + popl %ds
13497 +#endif
13498 +
13499 2: movw %ax,(%_ASM_CX)
13500 +
13501 +#ifdef CONFIG_X86_32
13502 + pushl %ss
13503 + popl %ds
13504 +#endif
13505 +
13506 xor %eax,%eax
13507 EXIT
13508 ENDPROC(__put_user_2)
13509 @@ -61,7 +86,19 @@ ENTRY(__put_user_4)
13510 sub $3,%_ASM_BX
13511 cmp %_ASM_BX,%_ASM_CX
13512 jae bad_put_user
13513 +
13514 +#ifdef CONFIG_X86_32
13515 + pushl $(__USER_DS)
13516 + popl %ds
13517 +#endif
13518 +
13519 3: movl %eax,(%_ASM_CX)
13520 +
13521 +#ifdef CONFIG_X86_32
13522 + pushl %ss
13523 + popl %ds
13524 +#endif
13525 +
13526 xor %eax,%eax
13527 EXIT
13528 ENDPROC(__put_user_4)
13529 @@ -72,16 +109,34 @@ ENTRY(__put_user_8)
13530 sub $7,%_ASM_BX
13531 cmp %_ASM_BX,%_ASM_CX
13532 jae bad_put_user
13533 +
13534 +#ifdef CONFIG_X86_32
13535 + pushl $(__USER_DS)
13536 + popl %ds
13537 +#endif
13538 +
13539 4: mov %_ASM_AX,(%_ASM_CX)
13540 #ifdef CONFIG_X86_32
13541 5: movl %edx,4(%_ASM_CX)
13542 #endif
13543 +
13544 +#ifdef CONFIG_X86_32
13545 + pushl %ss
13546 + popl %ds
13547 +#endif
13548 +
13549 xor %eax,%eax
13550 EXIT
13551 ENDPROC(__put_user_8)
13552
13553 bad_put_user:
13554 CFI_STARTPROC
13555 +
13556 +#ifdef CONFIG_X86_32
13557 + pushl %ss
13558 + popl %ds
13559 +#endif
13560 +
13561 movl $-EFAULT,%eax
13562 EXIT
13563 END(bad_put_user)
13564 diff -urNp linux-2.6.31.1/arch/x86/lib/usercopy_32.c linux-2.6.31.1/arch/x86/lib/usercopy_32.c
13565 --- linux-2.6.31.1/arch/x86/lib/usercopy_32.c 2009-09-24 11:45:25.000000000 -0400
13566 +++ linux-2.6.31.1/arch/x86/lib/usercopy_32.c 2009-10-01 20:12:42.000000000 -0400
13567 @@ -36,31 +36,38 @@ static inline int __movsl_is_ok(unsigned
13568 * Copy a null terminated string from userspace.
13569 */
13570
13571 -#define __do_strncpy_from_user(dst, src, count, res) \
13572 -do { \
13573 - int __d0, __d1, __d2; \
13574 - might_fault(); \
13575 - __asm__ __volatile__( \
13576 - " testl %1,%1\n" \
13577 - " jz 2f\n" \
13578 - "0: lodsb\n" \
13579 - " stosb\n" \
13580 - " testb %%al,%%al\n" \
13581 - " jz 1f\n" \
13582 - " decl %1\n" \
13583 - " jnz 0b\n" \
13584 - "1: subl %1,%0\n" \
13585 - "2:\n" \
13586 - ".section .fixup,\"ax\"\n" \
13587 - "3: movl %5,%0\n" \
13588 - " jmp 2b\n" \
13589 - ".previous\n" \
13590 - _ASM_EXTABLE(0b,3b) \
13591 - : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \
13592 - "=&D" (__d2) \
13593 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
13594 - : "memory"); \
13595 -} while (0)
13596 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
13597 +{
13598 + int __d0, __d1, __d2;
13599 + long res = -EFAULT;
13600 +
13601 + might_fault();
13602 + __asm__ __volatile__(
13603 + " movw %w10,%%ds\n"
13604 + " testl %1,%1\n"
13605 + " jz 2f\n"
13606 + "0: lodsb\n"
13607 + " stosb\n"
13608 + " testb %%al,%%al\n"
13609 + " jz 1f\n"
13610 + " decl %1\n"
13611 + " jnz 0b\n"
13612 + "1: subl %1,%0\n"
13613 + "2:\n"
13614 + " pushl %%ss\n"
13615 + " popl %%ds\n"
13616 + ".section .fixup,\"ax\"\n"
13617 + "3: movl %5,%0\n"
13618 + " jmp 2b\n"
13619 + ".previous\n"
13620 + _ASM_EXTABLE(0b,3b)
13621 + : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),
13622 + "=&D" (__d2)
13623 + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
13624 + "r"(__USER_DS)
13625 + : "memory");
13626 + return res;
13627 +}
13628
13629 /**
13630 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
13631 @@ -85,9 +92,7 @@ do { \
13632 long
13633 __strncpy_from_user(char *dst, const char __user *src, long count)
13634 {
13635 - long res;
13636 - __do_strncpy_from_user(dst, src, count, res);
13637 - return res;
13638 + return __do_strncpy_from_user(dst, src, count);
13639 }
13640 EXPORT_SYMBOL(__strncpy_from_user);
13641
13642 @@ -114,7 +119,7 @@ strncpy_from_user(char *dst, const char
13643 {
13644 long res = -EFAULT;
13645 if (access_ok(VERIFY_READ, src, 1))
13646 - __do_strncpy_from_user(dst, src, count, res);
13647 + res = __do_strncpy_from_user(dst, src, count);
13648 return res;
13649 }
13650 EXPORT_SYMBOL(strncpy_from_user);
13651 @@ -123,24 +128,30 @@ EXPORT_SYMBOL(strncpy_from_user);
13652 * Zero Userspace
13653 */
13654
13655 -#define __do_clear_user(addr,size) \
13656 -do { \
13657 - int __d0; \
13658 - might_fault(); \
13659 - __asm__ __volatile__( \
13660 - "0: rep; stosl\n" \
13661 - " movl %2,%0\n" \
13662 - "1: rep; stosb\n" \
13663 - "2:\n" \
13664 - ".section .fixup,\"ax\"\n" \
13665 - "3: lea 0(%2,%0,4),%0\n" \
13666 - " jmp 2b\n" \
13667 - ".previous\n" \
13668 - _ASM_EXTABLE(0b,3b) \
13669 - _ASM_EXTABLE(1b,2b) \
13670 - : "=&c"(size), "=&D" (__d0) \
13671 - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
13672 -} while (0)
13673 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
13674 +{
13675 + int __d0;
13676 +
13677 + might_fault();
13678 + __asm__ __volatile__(
13679 + " movw %w6,%%es\n"
13680 + "0: rep; stosl\n"
13681 + " movl %2,%0\n"
13682 + "1: rep; stosb\n"
13683 + "2:\n"
13684 + " pushl %%ss\n"
13685 + " popl %%es\n"
13686 + ".section .fixup,\"ax\"\n"
13687 + "3: lea 0(%2,%0,4),%0\n"
13688 + " jmp 2b\n"
13689 + ".previous\n"
13690 + _ASM_EXTABLE(0b,3b)
13691 + _ASM_EXTABLE(1b,2b)
13692 + : "=&c"(size), "=&D" (__d0)
13693 + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
13694 + "r"(__USER_DS));
13695 + return size;
13696 +}
13697
13698 /**
13699 * clear_user: - Zero a block of memory in user space.
13700 @@ -157,7 +168,7 @@ clear_user(void __user *to, unsigned lon
13701 {
13702 might_fault();
13703 if (access_ok(VERIFY_WRITE, to, n))
13704 - __do_clear_user(to, n);
13705 + n = __do_clear_user(to, n);
13706 return n;
13707 }
13708 EXPORT_SYMBOL(clear_user);
13709 @@ -176,8 +187,7 @@ EXPORT_SYMBOL(clear_user);
13710 unsigned long
13711 __clear_user(void __user *to, unsigned long n)
13712 {
13713 - __do_clear_user(to, n);
13714 - return n;
13715 + return __do_clear_user(to, n);
13716 }
13717 EXPORT_SYMBOL(__clear_user);
13718
13719 @@ -200,14 +210,17 @@ long strnlen_user(const char __user *s,
13720 might_fault();
13721
13722 __asm__ __volatile__(
13723 + " movw %w8,%%es\n"
13724 " testl %0, %0\n"
13725 " jz 3f\n"
13726 - " andl %0,%%ecx\n"
13727 + " movl %0,%%ecx\n"
13728 "0: repne; scasb\n"
13729 " setne %%al\n"
13730 " subl %%ecx,%0\n"
13731 " addl %0,%%eax\n"
13732 "1:\n"
13733 + " pushl %%ss\n"
13734 + " popl %%es\n"
13735 ".section .fixup,\"ax\"\n"
13736 "2: xorl %%eax,%%eax\n"
13737 " jmp 1b\n"
13738 @@ -219,7 +232,7 @@ long strnlen_user(const char __user *s,
13739 " .long 0b,2b\n"
13740 ".previous"
13741 :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp)
13742 - :"0" (n), "1" (s), "2" (0), "3" (mask)
13743 + :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
13744 :"cc");
13745 return res & mask;
13746 }
13747 @@ -227,10 +240,121 @@ EXPORT_SYMBOL(strnlen_user);
13748
13749 #ifdef CONFIG_X86_INTEL_USERCOPY
13750 static unsigned long
13751 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
13752 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
13753 +{
13754 + int d0, d1;
13755 + __asm__ __volatile__(
13756 + " movw %w6, %%es\n"
13757 + " .align 2,0x90\n"
13758 + "1: movl 32(%4), %%eax\n"
13759 + " cmpl $67, %0\n"
13760 + " jbe 3f\n"
13761 + "2: movl 64(%4), %%eax\n"
13762 + " .align 2,0x90\n"
13763 + "3: movl 0(%4), %%eax\n"
13764 + "4: movl 4(%4), %%edx\n"
13765 + "5: movl %%eax, %%es:0(%3)\n"
13766 + "6: movl %%edx, %%es:4(%3)\n"
13767 + "7: movl 8(%4), %%eax\n"
13768 + "8: movl 12(%4),%%edx\n"
13769 + "9: movl %%eax, %%es:8(%3)\n"
13770 + "10: movl %%edx, %%es:12(%3)\n"
13771 + "11: movl 16(%4), %%eax\n"
13772 + "12: movl 20(%4), %%edx\n"
13773 + "13: movl %%eax, %%es:16(%3)\n"
13774 + "14: movl %%edx, %%es:20(%3)\n"
13775 + "15: movl 24(%4), %%eax\n"
13776 + "16: movl 28(%4), %%edx\n"
13777 + "17: movl %%eax, %%es:24(%3)\n"
13778 + "18: movl %%edx, %%es:28(%3)\n"
13779 + "19: movl 32(%4), %%eax\n"
13780 + "20: movl 36(%4), %%edx\n"
13781 + "21: movl %%eax, %%es:32(%3)\n"
13782 + "22: movl %%edx, %%es:36(%3)\n"
13783 + "23: movl 40(%4), %%eax\n"
13784 + "24: movl 44(%4), %%edx\n"
13785 + "25: movl %%eax, %%es:40(%3)\n"
13786 + "26: movl %%edx, %%es:44(%3)\n"
13787 + "27: movl 48(%4), %%eax\n"
13788 + "28: movl 52(%4), %%edx\n"
13789 + "29: movl %%eax, %%es:48(%3)\n"
13790 + "30: movl %%edx, %%es:52(%3)\n"
13791 + "31: movl 56(%4), %%eax\n"
13792 + "32: movl 60(%4), %%edx\n"
13793 + "33: movl %%eax, %%es:56(%3)\n"
13794 + "34: movl %%edx, %%es:60(%3)\n"
13795 + " addl $-64, %0\n"
13796 + " addl $64, %4\n"
13797 + " addl $64, %3\n"
13798 + " cmpl $63, %0\n"
13799 + " ja 1b\n"
13800 + "35: movl %0, %%eax\n"
13801 + " shrl $2, %0\n"
13802 + " andl $3, %%eax\n"
13803 + " cld\n"
13804 + "99: rep; movsl\n"
13805 + "36: movl %%eax, %0\n"
13806 + "37: rep; movsb\n"
13807 + "100:\n"
13808 + " pushl %%ss\n"
13809 + " popl %%es\n"
13810 + ".section .fixup,\"ax\"\n"
13811 + "101: lea 0(%%eax,%0,4),%0\n"
13812 + " jmp 100b\n"
13813 + ".previous\n"
13814 + ".section __ex_table,\"a\"\n"
13815 + " .align 4\n"
13816 + " .long 1b,100b\n"
13817 + " .long 2b,100b\n"
13818 + " .long 3b,100b\n"
13819 + " .long 4b,100b\n"
13820 + " .long 5b,100b\n"
13821 + " .long 6b,100b\n"
13822 + " .long 7b,100b\n"
13823 + " .long 8b,100b\n"
13824 + " .long 9b,100b\n"
13825 + " .long 10b,100b\n"
13826 + " .long 11b,100b\n"
13827 + " .long 12b,100b\n"
13828 + " .long 13b,100b\n"
13829 + " .long 14b,100b\n"
13830 + " .long 15b,100b\n"
13831 + " .long 16b,100b\n"
13832 + " .long 17b,100b\n"
13833 + " .long 18b,100b\n"
13834 + " .long 19b,100b\n"
13835 + " .long 20b,100b\n"
13836 + " .long 21b,100b\n"
13837 + " .long 22b,100b\n"
13838 + " .long 23b,100b\n"
13839 + " .long 24b,100b\n"
13840 + " .long 25b,100b\n"
13841 + " .long 26b,100b\n"
13842 + " .long 27b,100b\n"
13843 + " .long 28b,100b\n"
13844 + " .long 29b,100b\n"
13845 + " .long 30b,100b\n"
13846 + " .long 31b,100b\n"
13847 + " .long 32b,100b\n"
13848 + " .long 33b,100b\n"
13849 + " .long 34b,100b\n"
13850 + " .long 35b,100b\n"
13851 + " .long 36b,100b\n"
13852 + " .long 37b,100b\n"
13853 + " .long 99b,101b\n"
13854 + ".previous"
13855 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
13856 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
13857 + : "eax", "edx", "memory");
13858 + return size;
13859 +}
13860 +
13861 +static unsigned long
13862 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
13863 {
13864 int d0, d1;
13865 __asm__ __volatile__(
13866 + " movw %w6, %%ds\n"
13867 " .align 2,0x90\n"
13868 "1: movl 32(%4), %%eax\n"
13869 " cmpl $67, %0\n"
13870 @@ -239,36 +363,36 @@ __copy_user_intel(void __user *to, const
13871 " .align 2,0x90\n"
13872 "3: movl 0(%4), %%eax\n"
13873 "4: movl 4(%4), %%edx\n"
13874 - "5: movl %%eax, 0(%3)\n"
13875 - "6: movl %%edx, 4(%3)\n"
13876 + "5: movl %%eax, %%es:0(%3)\n"
13877 + "6: movl %%edx, %%es:4(%3)\n"
13878 "7: movl 8(%4), %%eax\n"
13879 "8: movl 12(%4),%%edx\n"
13880 - "9: movl %%eax, 8(%3)\n"
13881 - "10: movl %%edx, 12(%3)\n"
13882 + "9: movl %%eax, %%es:8(%3)\n"
13883 + "10: movl %%edx, %%es:12(%3)\n"
13884 "11: movl 16(%4), %%eax\n"
13885 "12: movl 20(%4), %%edx\n"
13886 - "13: movl %%eax, 16(%3)\n"
13887 - "14: movl %%edx, 20(%3)\n"
13888 + "13: movl %%eax, %%es:16(%3)\n"
13889 + "14: movl %%edx, %%es:20(%3)\n"
13890 "15: movl 24(%4), %%eax\n"
13891 "16: movl 28(%4), %%edx\n"
13892 - "17: movl %%eax, 24(%3)\n"
13893 - "18: movl %%edx, 28(%3)\n"
13894 + "17: movl %%eax, %%es:24(%3)\n"
13895 + "18: movl %%edx, %%es:28(%3)\n"
13896 "19: movl 32(%4), %%eax\n"
13897 "20: movl 36(%4), %%edx\n"
13898 - "21: movl %%eax, 32(%3)\n"
13899 - "22: movl %%edx, 36(%3)\n"
13900 + "21: movl %%eax, %%es:32(%3)\n"
13901 + "22: movl %%edx, %%es:36(%3)\n"
13902 "23: movl 40(%4), %%eax\n"
13903 "24: movl 44(%4), %%edx\n"
13904 - "25: movl %%eax, 40(%3)\n"
13905 - "26: movl %%edx, 44(%3)\n"
13906 + "25: movl %%eax, %%es:40(%3)\n"
13907 + "26: movl %%edx, %%es:44(%3)\n"
13908 "27: movl 48(%4), %%eax\n"
13909 "28: movl 52(%4), %%edx\n"
13910 - "29: movl %%eax, 48(%3)\n"
13911 - "30: movl %%edx, 52(%3)\n"
13912 + "29: movl %%eax, %%es:48(%3)\n"
13913 + "30: movl %%edx, %%es:52(%3)\n"
13914 "31: movl 56(%4), %%eax\n"
13915 "32: movl 60(%4), %%edx\n"
13916 - "33: movl %%eax, 56(%3)\n"
13917 - "34: movl %%edx, 60(%3)\n"
13918 + "33: movl %%eax, %%es:56(%3)\n"
13919 + "34: movl %%edx, %%es:60(%3)\n"
13920 " addl $-64, %0\n"
13921 " addl $64, %4\n"
13922 " addl $64, %3\n"
13923 @@ -282,6 +406,8 @@ __copy_user_intel(void __user *to, const
13924 "36: movl %%eax, %0\n"
13925 "37: rep; movsb\n"
13926 "100:\n"
13927 + " pushl %%ss\n"
13928 + " popl %%ds\n"
13929 ".section .fixup,\"ax\"\n"
13930 "101: lea 0(%%eax,%0,4),%0\n"
13931 " jmp 100b\n"
13932 @@ -328,7 +454,7 @@ __copy_user_intel(void __user *to, const
13933 " .long 99b,101b\n"
13934 ".previous"
13935 : "=&c"(size), "=&D" (d0), "=&S" (d1)
13936 - : "1"(to), "2"(from), "0"(size)
13937 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
13938 : "eax", "edx", "memory");
13939 return size;
13940 }
13941 @@ -338,6 +464,7 @@ __copy_user_zeroing_intel(void *to, cons
13942 {
13943 int d0, d1;
13944 __asm__ __volatile__(
13945 + " movw %w6, %%ds\n"
13946 " .align 2,0x90\n"
13947 "0: movl 32(%4), %%eax\n"
13948 " cmpl $67, %0\n"
13949 @@ -346,36 +473,36 @@ __copy_user_zeroing_intel(void *to, cons
13950 " .align 2,0x90\n"
13951 "2: movl 0(%4), %%eax\n"
13952 "21: movl 4(%4), %%edx\n"
13953 - " movl %%eax, 0(%3)\n"
13954 - " movl %%edx, 4(%3)\n"
13955 + " movl %%eax, %%es:0(%3)\n"
13956 + " movl %%edx, %%es:4(%3)\n"
13957 "3: movl 8(%4), %%eax\n"
13958 "31: movl 12(%4),%%edx\n"
13959 - " movl %%eax, 8(%3)\n"
13960 - " movl %%edx, 12(%3)\n"
13961 + " movl %%eax, %%es:8(%3)\n"
13962 + " movl %%edx, %%es:12(%3)\n"
13963 "4: movl 16(%4), %%eax\n"
13964 "41: movl 20(%4), %%edx\n"
13965 - " movl %%eax, 16(%3)\n"
13966 - " movl %%edx, 20(%3)\n"
13967 + " movl %%eax, %%es:16(%3)\n"
13968 + " movl %%edx, %%es:20(%3)\n"
13969 "10: movl 24(%4), %%eax\n"
13970 "51: movl 28(%4), %%edx\n"
13971 - " movl %%eax, 24(%3)\n"
13972 - " movl %%edx, 28(%3)\n"
13973 + " movl %%eax, %%es:24(%3)\n"
13974 + " movl %%edx, %%es:28(%3)\n"
13975 "11: movl 32(%4), %%eax\n"
13976 "61: movl 36(%4), %%edx\n"
13977 - " movl %%eax, 32(%3)\n"
13978 - " movl %%edx, 36(%3)\n"
13979 + " movl %%eax, %%es:32(%3)\n"
13980 + " movl %%edx, %%es:36(%3)\n"
13981 "12: movl 40(%4), %%eax\n"
13982 "71: movl 44(%4), %%edx\n"
13983 - " movl %%eax, 40(%3)\n"
13984 - " movl %%edx, 44(%3)\n"
13985 + " movl %%eax, %%es:40(%3)\n"
13986 + " movl %%edx, %%es:44(%3)\n"
13987 "13: movl 48(%4), %%eax\n"
13988 "81: movl 52(%4), %%edx\n"
13989 - " movl %%eax, 48(%3)\n"
13990 - " movl %%edx, 52(%3)\n"
13991 + " movl %%eax, %%es:48(%3)\n"
13992 + " movl %%edx, %%es:52(%3)\n"
13993 "14: movl 56(%4), %%eax\n"
13994 "91: movl 60(%4), %%edx\n"
13995 - " movl %%eax, 56(%3)\n"
13996 - " movl %%edx, 60(%3)\n"
13997 + " movl %%eax, %%es:56(%3)\n"
13998 + " movl %%edx, %%es:60(%3)\n"
13999 " addl $-64, %0\n"
14000 " addl $64, %4\n"
14001 " addl $64, %3\n"
14002 @@ -389,6 +516,8 @@ __copy_user_zeroing_intel(void *to, cons
14003 " movl %%eax,%0\n"
14004 "7: rep; movsb\n"
14005 "8:\n"
14006 + " pushl %%ss\n"
14007 + " popl %%ds\n"
14008 ".section .fixup,\"ax\"\n"
14009 "9: lea 0(%%eax,%0,4),%0\n"
14010 "16: pushl %0\n"
14011 @@ -423,7 +552,7 @@ __copy_user_zeroing_intel(void *to, cons
14012 " .long 7b,16b\n"
14013 ".previous"
14014 : "=&c"(size), "=&D" (d0), "=&S" (d1)
14015 - : "1"(to), "2"(from), "0"(size)
14016 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14017 : "eax", "edx", "memory");
14018 return size;
14019 }
14020 @@ -439,6 +568,7 @@ static unsigned long __copy_user_zeroing
14021 int d0, d1;
14022
14023 __asm__ __volatile__(
14024 + " movw %w6, %%ds\n"
14025 " .align 2,0x90\n"
14026 "0: movl 32(%4), %%eax\n"
14027 " cmpl $67, %0\n"
14028 @@ -447,36 +577,36 @@ static unsigned long __copy_user_zeroing
14029 " .align 2,0x90\n"
14030 "2: movl 0(%4), %%eax\n"
14031 "21: movl 4(%4), %%edx\n"
14032 - " movnti %%eax, 0(%3)\n"
14033 - " movnti %%edx, 4(%3)\n"
14034 + " movnti %%eax, %%es:0(%3)\n"
14035 + " movnti %%edx, %%es:4(%3)\n"
14036 "3: movl 8(%4), %%eax\n"
14037 "31: movl 12(%4),%%edx\n"
14038 - " movnti %%eax, 8(%3)\n"
14039 - " movnti %%edx, 12(%3)\n"
14040 + " movnti %%eax, %%es:8(%3)\n"
14041 + " movnti %%edx, %%es:12(%3)\n"
14042 "4: movl 16(%4), %%eax\n"
14043 "41: movl 20(%4), %%edx\n"
14044 - " movnti %%eax, 16(%3)\n"
14045 - " movnti %%edx, 20(%3)\n"
14046 + " movnti %%eax, %%es:16(%3)\n"
14047 + " movnti %%edx, %%es:20(%3)\n"
14048 "10: movl 24(%4), %%eax\n"
14049 "51: movl 28(%4), %%edx\n"
14050 - " movnti %%eax, 24(%3)\n"
14051 - " movnti %%edx, 28(%3)\n"
14052 + " movnti %%eax, %%es:24(%3)\n"
14053 + " movnti %%edx, %%es:28(%3)\n"
14054 "11: movl 32(%4), %%eax\n"
14055 "61: movl 36(%4), %%edx\n"
14056 - " movnti %%eax, 32(%3)\n"
14057 - " movnti %%edx, 36(%3)\n"
14058 + " movnti %%eax, %%es:32(%3)\n"
14059 + " movnti %%edx, %%es:36(%3)\n"
14060 "12: movl 40(%4), %%eax\n"
14061 "71: movl 44(%4), %%edx\n"
14062 - " movnti %%eax, 40(%3)\n"
14063 - " movnti %%edx, 44(%3)\n"
14064 + " movnti %%eax, %%es:40(%3)\n"
14065 + " movnti %%edx, %%es:44(%3)\n"
14066 "13: movl 48(%4), %%eax\n"
14067 "81: movl 52(%4), %%edx\n"
14068 - " movnti %%eax, 48(%3)\n"
14069 - " movnti %%edx, 52(%3)\n"
14070 + " movnti %%eax, %%es:48(%3)\n"
14071 + " movnti %%edx, %%es:52(%3)\n"
14072 "14: movl 56(%4), %%eax\n"
14073 "91: movl 60(%4), %%edx\n"
14074 - " movnti %%eax, 56(%3)\n"
14075 - " movnti %%edx, 60(%3)\n"
14076 + " movnti %%eax, %%es:56(%3)\n"
14077 + " movnti %%edx, %%es:60(%3)\n"
14078 " addl $-64, %0\n"
14079 " addl $64, %4\n"
14080 " addl $64, %3\n"
14081 @@ -491,6 +621,8 @@ static unsigned long __copy_user_zeroing
14082 " movl %%eax,%0\n"
14083 "7: rep; movsb\n"
14084 "8:\n"
14085 + " pushl %%ss\n"
14086 + " popl %%ds\n"
14087 ".section .fixup,\"ax\"\n"
14088 "9: lea 0(%%eax,%0,4),%0\n"
14089 "16: pushl %0\n"
14090 @@ -525,7 +657,7 @@ static unsigned long __copy_user_zeroing
14091 " .long 7b,16b\n"
14092 ".previous"
14093 : "=&c"(size), "=&D" (d0), "=&S" (d1)
14094 - : "1"(to), "2"(from), "0"(size)
14095 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14096 : "eax", "edx", "memory");
14097 return size;
14098 }
14099 @@ -536,6 +668,7 @@ static unsigned long __copy_user_intel_n
14100 int d0, d1;
14101
14102 __asm__ __volatile__(
14103 + " movw %w6, %%ds\n"
14104 " .align 2,0x90\n"
14105 "0: movl 32(%4), %%eax\n"
14106 " cmpl $67, %0\n"
14107 @@ -544,36 +677,36 @@ static unsigned long __copy_user_intel_n
14108 " .align 2,0x90\n"
14109 "2: movl 0(%4), %%eax\n"
14110 "21: movl 4(%4), %%edx\n"
14111 - " movnti %%eax, 0(%3)\n"
14112 - " movnti %%edx, 4(%3)\n"
14113 + " movnti %%eax, %%es:0(%3)\n"
14114 + " movnti %%edx, %%es:4(%3)\n"
14115 "3: movl 8(%4), %%eax\n"
14116 "31: movl 12(%4),%%edx\n"
14117 - " movnti %%eax, 8(%3)\n"
14118 - " movnti %%edx, 12(%3)\n"
14119 + " movnti %%eax, %%es:8(%3)\n"
14120 + " movnti %%edx, %%es:12(%3)\n"
14121 "4: movl 16(%4), %%eax\n"
14122 "41: movl 20(%4), %%edx\n"
14123 - " movnti %%eax, 16(%3)\n"
14124 - " movnti %%edx, 20(%3)\n"
14125 + " movnti %%eax, %%es:16(%3)\n"
14126 + " movnti %%edx, %%es:20(%3)\n"
14127 "10: movl 24(%4), %%eax\n"
14128 "51: movl 28(%4), %%edx\n"
14129 - " movnti %%eax, 24(%3)\n"
14130 - " movnti %%edx, 28(%3)\n"
14131 + " movnti %%eax, %%es:24(%3)\n"
14132 + " movnti %%edx, %%es:28(%3)\n"
14133 "11: movl 32(%4), %%eax\n"
14134 "61: movl 36(%4), %%edx\n"
14135 - " movnti %%eax, 32(%3)\n"
14136 - " movnti %%edx, 36(%3)\n"
14137 + " movnti %%eax, %%es:32(%3)\n"
14138 + " movnti %%edx, %%es:36(%3)\n"
14139 "12: movl 40(%4), %%eax\n"
14140 "71: movl 44(%4), %%edx\n"
14141 - " movnti %%eax, 40(%3)\n"
14142 - " movnti %%edx, 44(%3)\n"
14143 + " movnti %%eax, %%es:40(%3)\n"
14144 + " movnti %%edx, %%es:44(%3)\n"
14145 "13: movl 48(%4), %%eax\n"
14146 "81: movl 52(%4), %%edx\n"
14147 - " movnti %%eax, 48(%3)\n"
14148 - " movnti %%edx, 52(%3)\n"
14149 + " movnti %%eax, %%es:48(%3)\n"
14150 + " movnti %%edx, %%es:52(%3)\n"
14151 "14: movl 56(%4), %%eax\n"
14152 "91: movl 60(%4), %%edx\n"
14153 - " movnti %%eax, 56(%3)\n"
14154 - " movnti %%edx, 60(%3)\n"
14155 + " movnti %%eax, %%es:56(%3)\n"
14156 + " movnti %%edx, %%es:60(%3)\n"
14157 " addl $-64, %0\n"
14158 " addl $64, %4\n"
14159 " addl $64, %3\n"
14160 @@ -588,6 +721,8 @@ static unsigned long __copy_user_intel_n
14161 " movl %%eax,%0\n"
14162 "7: rep; movsb\n"
14163 "8:\n"
14164 + " pushl %%ss\n"
14165 + " popl %%ds\n"
14166 ".section .fixup,\"ax\"\n"
14167 "9: lea 0(%%eax,%0,4),%0\n"
14168 "16: jmp 8b\n"
14169 @@ -616,7 +751,7 @@ static unsigned long __copy_user_intel_n
14170 " .long 7b,16b\n"
14171 ".previous"
14172 : "=&c"(size), "=&D" (d0), "=&S" (d1)
14173 - : "1"(to), "2"(from), "0"(size)
14174 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14175 : "eax", "edx", "memory");
14176 return size;
14177 }
14178 @@ -629,90 +764,146 @@ static unsigned long __copy_user_intel_n
14179 */
14180 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
14181 unsigned long size);
14182 -unsigned long __copy_user_intel(void __user *to, const void *from,
14183 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
14184 + unsigned long size);
14185 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
14186 unsigned long size);
14187 unsigned long __copy_user_zeroing_intel_nocache(void *to,
14188 const void __user *from, unsigned long size);
14189 #endif /* CONFIG_X86_INTEL_USERCOPY */
14190
14191 /* Generic arbitrary sized copy. */
14192 -#define __copy_user(to, from, size) \
14193 -do { \
14194 - int __d0, __d1, __d2; \
14195 - __asm__ __volatile__( \
14196 - " cmp $7,%0\n" \
14197 - " jbe 1f\n" \
14198 - " movl %1,%0\n" \
14199 - " negl %0\n" \
14200 - " andl $7,%0\n" \
14201 - " subl %0,%3\n" \
14202 - "4: rep; movsb\n" \
14203 - " movl %3,%0\n" \
14204 - " shrl $2,%0\n" \
14205 - " andl $3,%3\n" \
14206 - " .align 2,0x90\n" \
14207 - "0: rep; movsl\n" \
14208 - " movl %3,%0\n" \
14209 - "1: rep; movsb\n" \
14210 - "2:\n" \
14211 - ".section .fixup,\"ax\"\n" \
14212 - "5: addl %3,%0\n" \
14213 - " jmp 2b\n" \
14214 - "3: lea 0(%3,%0,4),%0\n" \
14215 - " jmp 2b\n" \
14216 - ".previous\n" \
14217 - ".section __ex_table,\"a\"\n" \
14218 - " .align 4\n" \
14219 - " .long 4b,5b\n" \
14220 - " .long 0b,3b\n" \
14221 - " .long 1b,2b\n" \
14222 - ".previous" \
14223 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
14224 - : "3"(size), "0"(size), "1"(to), "2"(from) \
14225 - : "memory"); \
14226 -} while (0)
14227 -
14228 -#define __copy_user_zeroing(to, from, size) \
14229 -do { \
14230 - int __d0, __d1, __d2; \
14231 - __asm__ __volatile__( \
14232 - " cmp $7,%0\n" \
14233 - " jbe 1f\n" \
14234 - " movl %1,%0\n" \
14235 - " negl %0\n" \
14236 - " andl $7,%0\n" \
14237 - " subl %0,%3\n" \
14238 - "4: rep; movsb\n" \
14239 - " movl %3,%0\n" \
14240 - " shrl $2,%0\n" \
14241 - " andl $3,%3\n" \
14242 - " .align 2,0x90\n" \
14243 - "0: rep; movsl\n" \
14244 - " movl %3,%0\n" \
14245 - "1: rep; movsb\n" \
14246 - "2:\n" \
14247 - ".section .fixup,\"ax\"\n" \
14248 - "5: addl %3,%0\n" \
14249 - " jmp 6f\n" \
14250 - "3: lea 0(%3,%0,4),%0\n" \
14251 - "6: pushl %0\n" \
14252 - " pushl %%eax\n" \
14253 - " xorl %%eax,%%eax\n" \
14254 - " rep; stosb\n" \
14255 - " popl %%eax\n" \
14256 - " popl %0\n" \
14257 - " jmp 2b\n" \
14258 - ".previous\n" \
14259 - ".section __ex_table,\"a\"\n" \
14260 - " .align 4\n" \
14261 - " .long 4b,5b\n" \
14262 - " .long 0b,3b\n" \
14263 - " .long 1b,6b\n" \
14264 - ".previous" \
14265 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
14266 - : "3"(size), "0"(size), "1"(to), "2"(from) \
14267 - : "memory"); \
14268 -} while (0)
14269 +static unsigned long
14270 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
14271 +{
14272 + int __d0, __d1, __d2;
14273 +
14274 + __asm__ __volatile__(
14275 + " movw %w8,%%es\n"
14276 + " cmp $7,%0\n"
14277 + " jbe 1f\n"
14278 + " movl %1,%0\n"
14279 + " negl %0\n"
14280 + " andl $7,%0\n"
14281 + " subl %0,%3\n"
14282 + "4: rep; movsb\n"
14283 + " movl %3,%0\n"
14284 + " shrl $2,%0\n"
14285 + " andl $3,%3\n"
14286 + " .align 2,0x90\n"
14287 + "0: rep; movsl\n"
14288 + " movl %3,%0\n"
14289 + "1: rep; movsb\n"
14290 + "2:\n"
14291 + " pushl %%ss\n"
14292 + " popl %%es\n"
14293 + ".section .fixup,\"ax\"\n"
14294 + "5: addl %3,%0\n"
14295 + " jmp 2b\n"
14296 + "3: lea 0(%3,%0,4),%0\n"
14297 + " jmp 2b\n"
14298 + ".previous\n"
14299 + ".section __ex_table,\"a\"\n"
14300 + " .align 4\n"
14301 + " .long 4b,5b\n"
14302 + " .long 0b,3b\n"
14303 + " .long 1b,2b\n"
14304 + ".previous"
14305 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
14306 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
14307 + : "memory");
14308 + return size;
14309 +}
14310 +
14311 +static unsigned long
14312 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
14313 +{
14314 + int __d0, __d1, __d2;
14315 +
14316 + __asm__ __volatile__(
14317 + " movw %w8,%%ds\n"
14318 + " cmp $7,%0\n"
14319 + " jbe 1f\n"
14320 + " movl %1,%0\n"
14321 + " negl %0\n"
14322 + " andl $7,%0\n"
14323 + " subl %0,%3\n"
14324 + "4: rep; movsb\n"
14325 + " movl %3,%0\n"
14326 + " shrl $2,%0\n"
14327 + " andl $3,%3\n"
14328 + " .align 2,0x90\n"
14329 + "0: rep; movsl\n"
14330 + " movl %3,%0\n"
14331 + "1: rep; movsb\n"
14332 + "2:\n"
14333 + " pushl %%ss\n"
14334 + " popl %%ds\n"
14335 + ".section .fixup,\"ax\"\n"
14336 + "5: addl %3,%0\n"
14337 + " jmp 2b\n"
14338 + "3: lea 0(%3,%0,4),%0\n"
14339 + " jmp 2b\n"
14340 + ".previous\n"
14341 + ".section __ex_table,\"a\"\n"
14342 + " .align 4\n"
14343 + " .long 4b,5b\n"
14344 + " .long 0b,3b\n"
14345 + " .long 1b,2b\n"
14346 + ".previous"
14347 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
14348 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
14349 + : "memory");
14350 + return size;
14351 +}
14352 +
14353 +static unsigned long
14354 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
14355 +{
14356 + int __d0, __d1, __d2;
14357 +
14358 + __asm__ __volatile__(
14359 + " movw %w8,%%ds\n"
14360 + " cmp $7,%0\n"
14361 + " jbe 1f\n"
14362 + " movl %1,%0\n"
14363 + " negl %0\n"
14364 + " andl $7,%0\n"
14365 + " subl %0,%3\n"
14366 + "4: rep; movsb\n"
14367 + " movl %3,%0\n"
14368 + " shrl $2,%0\n"
14369 + " andl $3,%3\n"
14370 + " .align 2,0x90\n"
14371 + "0: rep; movsl\n"
14372 + " movl %3,%0\n"
14373 + "1: rep; movsb\n"
14374 + "2:\n"
14375 + " pushl %%ss\n"
14376 + " popl %%ds\n"
14377 + ".section .fixup,\"ax\"\n"
14378 + "5: addl %3,%0\n"
14379 + " jmp 6f\n"
14380 + "3: lea 0(%3,%0,4),%0\n"
14381 + "6: pushl %0\n"
14382 + " pushl %%eax\n"
14383 + " xorl %%eax,%%eax\n"
14384 + " rep; stosb\n"
14385 + " popl %%eax\n"
14386 + " popl %0\n"
14387 + " jmp 2b\n"
14388 + ".previous\n"
14389 + ".section __ex_table,\"a\"\n"
14390 + " .align 4\n"
14391 + " .long 4b,5b\n"
14392 + " .long 0b,3b\n"
14393 + " .long 1b,6b\n"
14394 + ".previous"
14395 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
14396 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
14397 + : "memory");
14398 + return size;
14399 +}
14400
14401 unsigned long __copy_to_user_ll(void __user *to, const void *from,
14402 unsigned long n)
14403 @@ -775,9 +966,9 @@ survive:
14404 }
14405 #endif
14406 if (movsl_is_ok(to, from, n))
14407 - __copy_user(to, from, n);
14408 + n = __generic_copy_to_user(to, from, n);
14409 else
14410 - n = __copy_user_intel(to, from, n);
14411 + n = __generic_copy_to_user_intel(to, from, n);
14412 return n;
14413 }
14414 EXPORT_SYMBOL(__copy_to_user_ll);
14415 @@ -786,7 +977,7 @@ unsigned long __copy_from_user_ll(void *
14416 unsigned long n)
14417 {
14418 if (movsl_is_ok(to, from, n))
14419 - __copy_user_zeroing(to, from, n);
14420 + n = __copy_user_zeroing(to, from, n);
14421 else
14422 n = __copy_user_zeroing_intel(to, from, n);
14423 return n;
14424 @@ -797,10 +988,9 @@ unsigned long __copy_from_user_ll_nozero
14425 unsigned long n)
14426 {
14427 if (movsl_is_ok(to, from, n))
14428 - __copy_user(to, from, n);
14429 + n = __generic_copy_from_user(to, from, n);
14430 else
14431 - n = __copy_user_intel((void __user *)to,
14432 - (const void *)from, n);
14433 + n = __generic_copy_from_user_intel(to, from, n);
14434 return n;
14435 }
14436 EXPORT_SYMBOL(__copy_from_user_ll_nozero);
14437 @@ -812,9 +1002,9 @@ unsigned long __copy_from_user_ll_nocach
14438 if (n > 64 && cpu_has_xmm2)
14439 n = __copy_user_zeroing_intel_nocache(to, from, n);
14440 else
14441 - __copy_user_zeroing(to, from, n);
14442 + n = __copy_user_zeroing(to, from, n);
14443 #else
14444 - __copy_user_zeroing(to, from, n);
14445 + n = __copy_user_zeroing(to, from, n);
14446 #endif
14447 return n;
14448 }
14449 @@ -827,59 +1017,37 @@ unsigned long __copy_from_user_ll_nocach
14450 if (n > 64 && cpu_has_xmm2)
14451 n = __copy_user_intel_nocache(to, from, n);
14452 else
14453 - __copy_user(to, from, n);
14454 + n = __generic_copy_from_user(to, from, n);
14455 #else
14456 - __copy_user(to, from, n);
14457 + n = __generic_copy_from_user(to, from, n);
14458 #endif
14459 return n;
14460 }
14461 EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero);
14462
14463 -/**
14464 - * copy_to_user: - Copy a block of data into user space.
14465 - * @to: Destination address, in user space.
14466 - * @from: Source address, in kernel space.
14467 - * @n: Number of bytes to copy.
14468 - *
14469 - * Context: User context only. This function may sleep.
14470 - *
14471 - * Copy data from kernel space to user space.
14472 - *
14473 - * Returns number of bytes that could not be copied.
14474 - * On success, this will be zero.
14475 - */
14476 -unsigned long
14477 -copy_to_user(void __user *to, const void *from, unsigned long n)
14478 +#ifdef CONFIG_PAX_MEMORY_UDEREF
14479 +void __set_fs(mm_segment_t x, int cpu)
14480 {
14481 - if (access_ok(VERIFY_WRITE, to, n))
14482 - n = __copy_to_user(to, from, n);
14483 - return n;
14484 + unsigned long limit = x.seg;
14485 + struct desc_struct d;
14486 +
14487 + current_thread_info()->addr_limit = x;
14488 + if (likely(limit))
14489 + limit = (limit - 1UL) >> PAGE_SHIFT;
14490 + pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
14491 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
14492 }
14493 -EXPORT_SYMBOL(copy_to_user);
14494
14495 -/**
14496 - * copy_from_user: - Copy a block of data from user space.
14497 - * @to: Destination address, in kernel space.
14498 - * @from: Source address, in user space.
14499 - * @n: Number of bytes to copy.
14500 - *
14501 - * Context: User context only. This function may sleep.
14502 - *
14503 - * Copy data from user space to kernel space.
14504 - *
14505 - * Returns number of bytes that could not be copied.
14506 - * On success, this will be zero.
14507 - *
14508 - * If some data could not be copied, this function will pad the copied
14509 - * data to the requested size using zero bytes.
14510 - */
14511 -unsigned long
14512 -copy_from_user(void *to, const void __user *from, unsigned long n)
14513 +void set_fs(mm_segment_t x)
14514 {
14515 - if (access_ok(VERIFY_READ, from, n))
14516 - n = __copy_from_user(to, from, n);
14517 - else
14518 - memset(to, 0, n);
14519 - return n;
14520 + __set_fs(x, get_cpu());
14521 + put_cpu();
14522 }
14523 -EXPORT_SYMBOL(copy_from_user);
14524 +#else
14525 +void set_fs(mm_segment_t x)
14526 +{
14527 + current_thread_info()->addr_limit = x;
14528 +}
14529 +#endif
14530 +
14531 +EXPORT_SYMBOL(set_fs);
14532 diff -urNp linux-2.6.31.1/arch/x86/Makefile linux-2.6.31.1/arch/x86/Makefile
14533 --- linux-2.6.31.1/arch/x86/Makefile 2009-09-24 11:45:25.000000000 -0400
14534 +++ linux-2.6.31.1/arch/x86/Makefile 2009-10-01 20:12:42.000000000 -0400
14535 @@ -188,3 +188,12 @@ define archhelp
14536 echo ' FDARGS="..." arguments for the booted kernel'
14537 echo ' FDINITRD=file initrd for the booted kernel'
14538 endef
14539 +
14540 +define OLD_LD
14541 +
14542 +*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
14543 +*** Please upgrade your binutils to 2.18 or newer
14544 +endef
14545 +
14546 +archprepare:
14547 + $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
14548 diff -urNp linux-2.6.31.1/arch/x86/mm/extable.c linux-2.6.31.1/arch/x86/mm/extable.c
14549 --- linux-2.6.31.1/arch/x86/mm/extable.c 2009-09-24 11:45:25.000000000 -0400
14550 +++ linux-2.6.31.1/arch/x86/mm/extable.c 2009-10-01 20:12:42.000000000 -0400
14551 @@ -1,14 +1,81 @@
14552 #include <linux/module.h>
14553 #include <linux/spinlock.h>
14554 +#include <linux/sort.h>
14555 #include <asm/uaccess.h>
14556
14557 +/*
14558 + * The exception table needs to be sorted so that the binary
14559 + * search that we use to find entries in it works properly.
14560 + * This is used both for the kernel exception table and for
14561 + * the exception tables of modules that get loaded.
14562 + */
14563 +static int cmp_ex(const void *a, const void *b)
14564 +{
14565 + const struct exception_table_entry *x = a, *y = b;
14566 +
14567 + /* avoid overflow */
14568 + if (x->insn > y->insn)
14569 + return 1;
14570 + if (x->insn < y->insn)
14571 + return -1;
14572 + return 0;
14573 +}
14574 +
14575 +static void swap_ex(void *a, void *b, int size)
14576 +{
14577 + struct exception_table_entry t, *x = a, *y = b;
14578 +
14579 +#ifdef CONFIG_PAX_KERNEXEC
14580 + unsigned long cr0;
14581 +#endif
14582 +
14583 + t = *x;
14584 +
14585 +#ifdef CONFIG_PAX_KERNEXEC
14586 + pax_open_kernel(cr0);
14587 +#endif
14588 +
14589 + *x = *y;
14590 + *y = t;
14591 +
14592 +#ifdef CONFIG_PAX_KERNEXEC
14593 + pax_close_kernel(cr0);
14594 +#endif
14595 +
14596 +}
14597 +
14598 +void sort_extable(struct exception_table_entry *start,
14599 + struct exception_table_entry *finish)
14600 +{
14601 + sort(start, finish - start, sizeof(struct exception_table_entry),
14602 + cmp_ex, swap_ex);
14603 +}
14604 +
14605 +#ifdef CONFIG_MODULES
14606 +/*
14607 + * If the exception table is sorted, any referring to the module init
14608 + * will be at the beginning or the end.
14609 + */
14610 +void trim_init_extable(struct module *m)
14611 +{
14612 + /*trim the beginning*/
14613 + while (m->num_exentries && within_module_init(m->extable[0].insn, m)) {
14614 + m->extable++;
14615 + m->num_exentries--;
14616 + }
14617 + /*trim the end*/
14618 + while (m->num_exentries &&
14619 + within_module_init(m->extable[m->num_exentries-1].insn, m))
14620 + m->num_exentries--;
14621 +}
14622 +#endif /* CONFIG_MODULES */
14623
14624 int fixup_exception(struct pt_regs *regs)
14625 {
14626 const struct exception_table_entry *fixup;
14627
14628 #ifdef CONFIG_PNPBIOS
14629 - if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
14630 + if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
14631 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
14632 extern u32 pnp_bios_is_utter_crap;
14633 pnp_bios_is_utter_crap = 1;
14634 diff -urNp linux-2.6.31.1/arch/x86/mm/fault.c linux-2.6.31.1/arch/x86/mm/fault.c
14635 --- linux-2.6.31.1/arch/x86/mm/fault.c 2009-09-24 11:45:25.000000000 -0400
14636 +++ linux-2.6.31.1/arch/x86/mm/fault.c 2009-10-01 20:12:42.000000000 -0400
14637 @@ -11,10 +11,14 @@
14638 #include <linux/kprobes.h> /* __kprobes, ... */
14639 #include <linux/mmiotrace.h> /* kmmio_handler, ... */
14640 #include <linux/perf_counter.h> /* perf_swcounter_event */
14641 +#include <linux/unistd.h>
14642 +#include <linux/compiler.h>
14643
14644 #include <asm/traps.h> /* dotraplinkage, ... */
14645 #include <asm/pgalloc.h> /* pgd_*(), ... */
14646 #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
14647 +#include <asm/vsyscall.h>
14648 +#include <asm/tlbflush.h>
14649
14650 /*
14651 * Page fault error code bits:
14652 @@ -51,7 +55,7 @@ static inline int notify_page_fault(stru
14653 int ret = 0;
14654
14655 /* kprobe_running() needs smp_processor_id() */
14656 - if (kprobes_built_in() && !user_mode_vm(regs)) {
14657 + if (kprobes_built_in() && !user_mode(regs)) {
14658 preempt_disable();
14659 if (kprobe_running() && kprobe_fault_handler(regs, 14))
14660 ret = 1;
14661 @@ -171,6 +175,30 @@ force_sig_info_fault(int si_signo, int s
14662 force_sig_info(si_signo, &info, tsk);
14663 }
14664
14665 +#ifdef CONFIG_PAX_EMUTRAMP
14666 +static int pax_handle_fetch_fault(struct pt_regs *regs);
14667 +#endif
14668 +
14669 +#ifdef CONFIG_PAX_PAGEEXEC
14670 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
14671 +{
14672 + pgd_t *pgd;
14673 + pud_t *pud;
14674 + pmd_t *pmd;
14675 +
14676 + pgd = pgd_offset(mm, address);
14677 + if (!pgd_present(*pgd))
14678 + return NULL;
14679 + pud = pud_offset(pgd, address);
14680 + if (!pud_present(*pud))
14681 + return NULL;
14682 + pmd = pmd_offset(pud, address);
14683 + if (!pmd_present(*pmd))
14684 + return NULL;
14685 + return pmd;
14686 +}
14687 +#endif
14688 +
14689 DEFINE_SPINLOCK(pgd_lock);
14690 LIST_HEAD(pgd_list);
14691
14692 @@ -543,7 +571,7 @@ static int is_errata93(struct pt_regs *r
14693 static int is_errata100(struct pt_regs *regs, unsigned long address)
14694 {
14695 #ifdef CONFIG_X86_64
14696 - if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && (address >> 32))
14697 + if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) && (address >> 32))
14698 return 1;
14699 #endif
14700 return 0;
14701 @@ -570,7 +598,7 @@ static int is_f00f_bug(struct pt_regs *r
14702 }
14703
14704 static const char nx_warning[] = KERN_CRIT
14705 -"kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n";
14706 +"kernel tried to execute NX-protected page - exploit attempt? (uid: %d, task: %s, pid: %d)\n";
14707
14708 static void
14709 show_fault_oops(struct pt_regs *regs, unsigned long error_code,
14710 @@ -579,15 +607,31 @@ show_fault_oops(struct pt_regs *regs, un
14711 if (!oops_may_print())
14712 return;
14713
14714 - if (error_code & PF_INSTR) {
14715 + if (nx_enabled && (error_code & PF_INSTR)) {
14716 unsigned int level;
14717
14718 pte_t *pte = lookup_address(address, &level);
14719
14720 if (pte && pte_present(*pte) && !pte_exec(*pte))
14721 - printk(nx_warning, current_uid());
14722 + printk(nx_warning, current_uid(), current->comm, task_pid_nr(current));
14723 }
14724
14725 +#ifdef CONFIG_PAX_KERNEXEC
14726 +#if defined(CONFIG_x86_32) && defined(CONFIG_MODULES)
14727 + if (init_mm.start_code <= address && address < (unsigned long)&MODULES_EXEC_END)
14728 +#else
14729 + if (init_mm.start_code <= address && address < init_mm.end_code)
14730 +#endif
14731 + {
14732 + if (current->signal->curr_ip)
14733 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
14734 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current_uid(), current_euid());
14735 + else
14736 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
14737 + current->comm, task_pid_nr(current), current_uid(), current_euid());
14738 + }
14739 +#endif
14740 +
14741 printk(KERN_ALERT "BUG: unable to handle kernel ");
14742 if (address < PAGE_SIZE)
14743 printk(KERN_CONT "NULL pointer dereference");
14744 @@ -712,6 +756,68 @@ __bad_area_nosemaphore(struct pt_regs *r
14745 unsigned long address, int si_code)
14746 {
14747 struct task_struct *tsk = current;
14748 + struct mm_struct *mm = tsk->mm;
14749 +
14750 +#ifdef CONFIG_X86_64
14751 + if (mm && (error_code & PF_INSTR)) {
14752 + if (regs->ip == (unsigned long)vgettimeofday) {
14753 + regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, fallback_gettimeofday);
14754 + return;
14755 + } else if (regs->ip == (unsigned long)vtime) {
14756 + regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, fallback_time);
14757 + return;
14758 + } else if (regs->ip == (unsigned long)vgetcpu) {
14759 + regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, getcpu);
14760 + return;
14761 + }
14762 + }
14763 +#endif
14764 +
14765 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14766 + if (mm && (error_code & PF_USER)) {
14767 + unsigned long ip = regs->ip;
14768 +
14769 + if (v8086_mode(regs))
14770 + ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
14771 +
14772 + /*
14773 + * It's possible to have interrupts off here:
14774 + */
14775 + local_irq_enable();
14776 +
14777 +#ifdef CONFIG_PAX_PAGEEXEC
14778 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
14779 + ((nx_enabled && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && regs->ip == address))) {
14780 +
14781 +#ifdef CONFIG_PAX_EMUTRAMP
14782 + switch (pax_handle_fetch_fault(regs)) {
14783 + case 2:
14784 + return;
14785 + }
14786 +#endif
14787 +
14788 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
14789 + do_group_exit(SIGKILL);
14790 + }
14791 +#endif
14792 +
14793 +#ifdef CONFIG_PAX_SEGMEXEC
14794 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
14795 +
14796 +#ifdef CONFIG_PAX_EMUTRAMP
14797 + switch (pax_handle_fetch_fault(regs)) {
14798 + case 2:
14799 + return;
14800 + }
14801 +#endif
14802 +
14803 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
14804 + do_group_exit(SIGKILL);
14805 + }
14806 +#endif
14807 +
14808 + }
14809 +#endif
14810
14811 /* User mode accesses just cause a SIGSEGV */
14812 if (error_code & PF_USER) {
14813 @@ -846,6 +952,106 @@ static int spurious_fault_check(unsigned
14814 return 1;
14815 }
14816
14817 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
14818 +static int pax_handle_pageexec_fault(struct pt_regs *regs, struct mm_struct *mm, unsigned long address, unsigned long error_code)
14819 +{
14820 + pte_t *pte;
14821 + pmd_t *pmd;
14822 + spinlock_t *ptl;
14823 + unsigned char pte_mask;
14824 +
14825 + if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
14826 + !(mm->pax_flags & MF_PAX_PAGEEXEC))
14827 + return 0;
14828 +
14829 + /* PaX: it's our fault, let's handle it if we can */
14830 +
14831 + /* PaX: take a look at read faults before acquiring any locks */
14832 + if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
14833 + /* instruction fetch attempt from a protected page in user mode */
14834 + up_read(&mm->mmap_sem);
14835 +
14836 +#ifdef CONFIG_PAX_EMUTRAMP
14837 + switch (pax_handle_fetch_fault(regs)) {
14838 + case 2:
14839 + return 1;
14840 + }
14841 +#endif
14842 +
14843 + pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
14844 + do_group_exit(SIGKILL);
14845 + }
14846 +
14847 + pmd = pax_get_pmd(mm, address);
14848 + if (unlikely(!pmd))
14849 + return 0;
14850 +
14851 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
14852 + if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
14853 + pte_unmap_unlock(pte, ptl);
14854 + return 0;
14855 + }
14856 +
14857 + if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
14858 + /* write attempt to a protected page in user mode */
14859 + pte_unmap_unlock(pte, ptl);
14860 + return 0;
14861 + }
14862 +
14863 +#ifdef CONFIG_SMP
14864 + if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
14865 +#else
14866 + if (likely(address > get_limit(regs->cs)))
14867 +#endif
14868 + {
14869 + set_pte(pte, pte_mkread(*pte));
14870 + __flush_tlb_one(address);
14871 + pte_unmap_unlock(pte, ptl);
14872 + up_read(&mm->mmap_sem);
14873 + return 1;
14874 + }
14875 +
14876 + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
14877 +
14878 + /*
14879 + * PaX: fill DTLB with user rights and retry
14880 + */
14881 + __asm__ __volatile__ (
14882 +#ifdef CONFIG_PAX_MEMORY_UDEREF
14883 + "movw %w4,%%es\n"
14884 +#endif
14885 + "orb %2,(%1)\n"
14886 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
14887 +/*
14888 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
14889 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
14890 + * page fault when examined during a TLB load attempt. this is true not only
14891 + * for PTEs holding a non-present entry but also present entries that will
14892 + * raise a page fault (such as those set up by PaX, or the copy-on-write
14893 + * mechanism). in effect it means that we do *not* need to flush the TLBs
14894 + * for our target pages since their PTEs are simply not in the TLBs at all.
14895 +
14896 + * the best thing in omitting it is that we gain around 15-20% speed in the
14897 + * fast path of the page fault handler and can get rid of tracing since we
14898 + * can no longer flush unintended entries.
14899 + */
14900 + "invlpg (%0)\n"
14901 +#endif
14902 + "testb $0,%%es:(%0)\n"
14903 + "xorb %3,(%1)\n"
14904 +#ifdef CONFIG_PAX_MEMORY_UDEREF
14905 + "pushl %%ss\n"
14906 + "popl %%es\n"
14907 +#endif
14908 + :
14909 + : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
14910 + : "memory", "cc");
14911 + pte_unmap_unlock(pte, ptl);
14912 + up_read(&mm->mmap_sem);
14913 + return 1;
14914 +}
14915 +#endif
14916 +
14917 /*
14918 * Handle a spurious fault caused by a stale TLB entry.
14919 *
14920 @@ -912,6 +1118,9 @@ int show_unhandled_signals = 1;
14921 static inline int
14922 access_error(unsigned long error_code, int write, struct vm_area_struct *vma)
14923 {
14924 + if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
14925 + return 1;
14926 +
14927 if (write) {
14928 /* write, present and write, not present: */
14929 if (unlikely(!(vma->vm_flags & VM_WRITE)))
14930 @@ -945,17 +1154,16 @@ do_page_fault(struct pt_regs *regs, unsi
14931 {
14932 struct vm_area_struct *vma;
14933 struct task_struct *tsk;
14934 - unsigned long address;
14935 struct mm_struct *mm;
14936 int write;
14937 int fault;
14938
14939 + /* Get the faulting address: */
14940 + const unsigned long address = read_cr2();
14941 +
14942 tsk = current;
14943 mm = tsk->mm;
14944
14945 - /* Get the faulting address: */
14946 - address = read_cr2();
14947 -
14948 /*
14949 * Detect and handle instructions that would cause a page fault for
14950 * both a tracked kernel page and a userspace page.
14951 @@ -1015,7 +1223,7 @@ do_page_fault(struct pt_regs *regs, unsi
14952 * User-mode registers count as a user access even for any
14953 * potential system fault or CPU buglet:
14954 */
14955 - if (user_mode_vm(regs)) {
14956 + if (user_mode(regs)) {
14957 local_irq_enable();
14958 error_code |= PF_USER;
14959 } else {
14960 @@ -1069,6 +1277,11 @@ do_page_fault(struct pt_regs *regs, unsi
14961 might_sleep();
14962 }
14963
14964 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
14965 + if (pax_handle_pageexec_fault(regs, mm, address, error_code))
14966 + return;
14967 +#endif
14968 +
14969 vma = find_vma(mm, address);
14970 if (unlikely(!vma)) {
14971 bad_area(regs, error_code, address);
14972 @@ -1080,18 +1293,24 @@ do_page_fault(struct pt_regs *regs, unsi
14973 bad_area(regs, error_code, address);
14974 return;
14975 }
14976 - if (error_code & PF_USER) {
14977 - /*
14978 - * Accessing the stack below %sp is always a bug.
14979 - * The large cushion allows instructions like enter
14980 - * and pusha to work. ("enter $65535, $31" pushes
14981 - * 32 pointers and then decrements %sp by 65535.)
14982 - */
14983 - if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
14984 - bad_area(regs, error_code, address);
14985 - return;
14986 - }
14987 + /*
14988 + * Accessing the stack below %sp is always a bug.
14989 + * The large cushion allows instructions like enter
14990 + * and pusha to work. ("enter $65535, $31" pushes
14991 + * 32 pointers and then decrements %sp by 65535.)
14992 + */
14993 + if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < task_pt_regs(tsk)->sp)) {
14994 + bad_area(regs, error_code, address);
14995 + return;
14996 + }
14997 +
14998 +#ifdef CONFIG_PAX_SEGMEXEC
14999 + if (unlikely((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)) {
15000 + bad_area(regs, error_code, address);
15001 + return;
15002 }
15003 +#endif
15004 +
15005 if (unlikely(expand_stack(vma, address))) {
15006 bad_area(regs, error_code, address);
15007 return;
15008 @@ -1135,3 +1354,174 @@ good_area:
15009
15010 up_read(&mm->mmap_sem);
15011 }
15012 +
15013 +#ifdef CONFIG_PAX_EMUTRAMP
15014 +static int pax_handle_fetch_fault_32(struct pt_regs *regs)
15015 +{
15016 + int err;
15017 +
15018 + do { /* PaX: gcc trampoline emulation #1 */
15019 + unsigned char mov1, mov2;
15020 + unsigned short jmp;
15021 + unsigned int addr1, addr2;
15022 +
15023 +#ifdef CONFIG_X86_64
15024 + if ((regs->ip + 11) >> 32)
15025 + break;
15026 +#endif
15027 +
15028 + err = get_user(mov1, (unsigned char __user *)regs->ip);
15029 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
15030 + err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
15031 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
15032 + err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
15033 +
15034 + if (err)
15035 + break;
15036 +
15037 + if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
15038 + regs->cx = addr1;
15039 + regs->ax = addr2;
15040 + regs->ip = addr2;
15041 + return 2;
15042 + }
15043 + } while (0);
15044 +
15045 + do { /* PaX: gcc trampoline emulation #2 */
15046 + unsigned char mov, jmp;
15047 + unsigned int addr1, addr2;
15048 +
15049 +#ifdef CONFIG_X86_64
15050 + if ((regs->ip + 9) >> 32)
15051 + break;
15052 +#endif
15053 +
15054 + err = get_user(mov, (unsigned char __user *)regs->ip);
15055 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
15056 + err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
15057 + err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
15058 +
15059 + if (err)
15060 + break;
15061 +
15062 + if (mov == 0xB9 && jmp == 0xE9) {
15063 + regs->cx = addr1;
15064 + regs->ip = (unsigned int)(regs->ip + addr2 + 10);
15065 + return 2;
15066 + }
15067 + } while (0);
15068 +
15069 + return 1; /* PaX in action */
15070 +}
15071 +
15072 +#ifdef CONFIG_X86_64
15073 +static int pax_handle_fetch_fault_64(struct pt_regs *regs)
15074 +{
15075 + int err;
15076 +
15077 + do { /* PaX: gcc trampoline emulation #1 */
15078 + unsigned short mov1, mov2, jmp1;
15079 + unsigned char jmp2;
15080 + unsigned int addr1;
15081 + unsigned long addr2;
15082 +
15083 + err = get_user(mov1, (unsigned short __user *)regs->ip);
15084 + err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
15085 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
15086 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
15087 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
15088 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
15089 +
15090 + if (err)
15091 + break;
15092 +
15093 + if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
15094 + regs->r11 = addr1;
15095 + regs->r10 = addr2;
15096 + regs->ip = addr1;
15097 + return 2;
15098 + }
15099 + } while (0);
15100 +
15101 + do { /* PaX: gcc trampoline emulation #2 */
15102 + unsigned short mov1, mov2, jmp1;
15103 + unsigned char jmp2;
15104 + unsigned long addr1, addr2;
15105 +
15106 + err = get_user(mov1, (unsigned short __user *)regs->ip);
15107 + err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
15108 + err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
15109 + err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
15110 + err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
15111 + err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
15112 +
15113 + if (err)
15114 + break;
15115 +
15116 + if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
15117 + regs->r11 = addr1;
15118 + regs->r10 = addr2;
15119 + regs->ip = addr1;
15120 + return 2;
15121 + }
15122 + } while (0);
15123 +
15124 + return 1; /* PaX in action */
15125 +}
15126 +#endif
15127 +
15128 +/*
15129 + * PaX: decide what to do with offenders (regs->ip = fault address)
15130 + *
15131 + * returns 1 when task should be killed
15132 + * 2 when gcc trampoline was detected
15133 + */
15134 +static int pax_handle_fetch_fault(struct pt_regs *regs)
15135 +{
15136 + if (v8086_mode(regs))
15137 + return 1;
15138 +
15139 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
15140 + return 1;
15141 +
15142 +#ifdef CONFIG_X86_32
15143 + return pax_handle_fetch_fault_32(regs);
15144 +#else
15145 + if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
15146 + return pax_handle_fetch_fault_32(regs);
15147 + else
15148 + return pax_handle_fetch_fault_64(regs);
15149 +#endif
15150 +}
15151 +#endif
15152 +
15153 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15154 +void pax_report_insns(void *pc, void *sp)
15155 +{
15156 + long i;
15157 +
15158 + printk(KERN_ERR "PAX: bytes at PC: ");
15159 + for (i = 0; i < 20; i++) {
15160 + unsigned char c;
15161 + if (get_user(c, (unsigned char __user *)pc+i))
15162 + printk(KERN_CONT "?? ");
15163 + else
15164 + printk(KERN_CONT "%02x ", c);
15165 + }
15166 + printk("\n");
15167 +
15168 + printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
15169 + for (i = -1; i < 80 / sizeof(long); i++) {
15170 + unsigned long c;
15171 + if (get_user(c, (unsigned long __user *)sp+i))
15172 +#ifdef CONFIG_X86_32
15173 + printk(KERN_CONT "???????? ");
15174 +#else
15175 + printk(KERN_CONT "???????????????? ");
15176 +#endif
15177 + else
15178 + printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
15179 + }
15180 + printk("\n");
15181 +}
15182 +#endif
15183 diff -urNp linux-2.6.31.1/arch/x86/mm/highmem_32.c linux-2.6.31.1/arch/x86/mm/highmem_32.c
15184 --- linux-2.6.31.1/arch/x86/mm/highmem_32.c 2009-09-24 11:45:25.000000000 -0400
15185 +++ linux-2.6.31.1/arch/x86/mm/highmem_32.c 2009-10-01 20:12:42.000000000 -0400
15186 @@ -32,6 +32,10 @@ void *kmap_atomic_prot(struct page *page
15187 enum fixed_addresses idx;
15188 unsigned long vaddr;
15189
15190 +#ifdef CONFIG_PAX_KERNEXEC
15191 + unsigned long cr0;
15192 +#endif
15193 +
15194 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
15195 pagefault_disable();
15196
15197 @@ -43,8 +47,17 @@ void *kmap_atomic_prot(struct page *page
15198 idx = type + KM_TYPE_NR*smp_processor_id();
15199 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
15200 BUG_ON(!pte_none(*(kmap_pte-idx)));
15201 +
15202 +#ifdef CONFIG_PAX_KERNEXEC
15203 + pax_open_kernel(cr0);
15204 +#endif
15205 +
15206 set_pte(kmap_pte-idx, mk_pte(page, prot));
15207
15208 +#ifdef CONFIG_PAX_KERNEXEC
15209 + pax_close_kernel(cr0);
15210 +#endif
15211 +
15212 return (void *)vaddr;
15213 }
15214
15215 @@ -58,15 +71,29 @@ void kunmap_atomic(void *kvaddr, enum km
15216 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
15217 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
15218
15219 +#ifdef CONFIG_PAX_KERNEXEC
15220 + unsigned long cr0;
15221 +#endif
15222 +
15223 /*
15224 * Force other mappings to Oops if they'll try to access this pte
15225 * without first remap it. Keeping stale mappings around is a bad idea
15226 * also, in case the page changes cacheability attributes or becomes
15227 * a protected page in a hypervisor.
15228 */
15229 - if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
15230 + if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
15231 +
15232 +#ifdef CONFIG_PAX_KERNEXEC
15233 + pax_open_kernel(cr0);
15234 +#endif
15235 +
15236 kpte_clear_flush(kmap_pte-idx, vaddr);
15237 - else {
15238 +
15239 +#ifdef CONFIG_PAX_KERNEXEC
15240 + pax_close_kernel(cr0);
15241 +#endif
15242 +
15243 + } else {
15244 #ifdef CONFIG_DEBUG_HIGHMEM
15245 BUG_ON(vaddr < PAGE_OFFSET);
15246 BUG_ON(vaddr >= (unsigned long)high_memory);
15247 diff -urNp linux-2.6.31.1/arch/x86/mm/hugetlbpage.c linux-2.6.31.1/arch/x86/mm/hugetlbpage.c
15248 --- linux-2.6.31.1/arch/x86/mm/hugetlbpage.c 2009-09-24 11:45:25.000000000 -0400
15249 +++ linux-2.6.31.1/arch/x86/mm/hugetlbpage.c 2009-10-01 20:12:42.000000000 -0400
15250 @@ -267,13 +267,18 @@ static unsigned long hugetlb_get_unmappe
15251 struct hstate *h = hstate_file(file);
15252 struct mm_struct *mm = current->mm;
15253 struct vm_area_struct *vma;
15254 - unsigned long start_addr;
15255 + unsigned long start_addr, pax_task_size = TASK_SIZE;
15256 +
15257 +#ifdef CONFIG_PAX_SEGMEXEC
15258 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
15259 + pax_task_size = SEGMEXEC_TASK_SIZE;
15260 +#endif
15261
15262 if (len > mm->cached_hole_size) {
15263 - start_addr = mm->free_area_cache;
15264 + start_addr = mm->free_area_cache;
15265 } else {
15266 - start_addr = TASK_UNMAPPED_BASE;
15267 - mm->cached_hole_size = 0;
15268 + start_addr = mm->mmap_base;
15269 + mm->cached_hole_size = 0;
15270 }
15271
15272 full_search:
15273 @@ -281,13 +286,13 @@ full_search:
15274
15275 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
15276 /* At this point: (!vma || addr < vma->vm_end). */
15277 - if (TASK_SIZE - len < addr) {
15278 + if (pax_task_size - len < addr) {
15279 /*
15280 * Start a new search - just in case we missed
15281 * some holes.
15282 */
15283 - if (start_addr != TASK_UNMAPPED_BASE) {
15284 - start_addr = TASK_UNMAPPED_BASE;
15285 + if (start_addr != mm->mmap_base) {
15286 + start_addr = mm->mmap_base;
15287 mm->cached_hole_size = 0;
15288 goto full_search;
15289 }
15290 @@ -310,9 +315,8 @@ static unsigned long hugetlb_get_unmappe
15291 struct hstate *h = hstate_file(file);
15292 struct mm_struct *mm = current->mm;
15293 struct vm_area_struct *vma, *prev_vma;
15294 - unsigned long base = mm->mmap_base, addr = addr0;
15295 + unsigned long base = mm->mmap_base, addr;
15296 unsigned long largest_hole = mm->cached_hole_size;
15297 - int first_time = 1;
15298
15299 /* don't allow allocations above current base */
15300 if (mm->free_area_cache > base)
15301 @@ -322,7 +326,7 @@ static unsigned long hugetlb_get_unmappe
15302 largest_hole = 0;
15303 mm->free_area_cache = base;
15304 }
15305 -try_again:
15306 +
15307 /* make sure it can fit in the remaining address space */
15308 if (mm->free_area_cache < len)
15309 goto fail;
15310 @@ -364,22 +368,26 @@ try_again:
15311
15312 fail:
15313 /*
15314 - * if hint left us with no space for the requested
15315 - * mapping then try again:
15316 - */
15317 - if (first_time) {
15318 - mm->free_area_cache = base;
15319 - largest_hole = 0;
15320 - first_time = 0;
15321 - goto try_again;
15322 - }
15323 - /*
15324 * A failed mmap() very likely causes application failure,
15325 * so fall back to the bottom-up function here. This scenario
15326 * can happen with large stack limits and large mmap()
15327 * allocations.
15328 */
15329 - mm->free_area_cache = TASK_UNMAPPED_BASE;
15330 +
15331 +#ifdef CONFIG_PAX_SEGMEXEC
15332 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
15333 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
15334 + else
15335 +#endif
15336 +
15337 + mm->mmap_base = TASK_UNMAPPED_BASE;
15338 +
15339 +#ifdef CONFIG_PAX_RANDMMAP
15340 + if (mm->pax_flags & MF_PAX_RANDMMAP)
15341 + mm->mmap_base += mm->delta_mmap;
15342 +#endif
15343 +
15344 + mm->free_area_cache = mm->mmap_base;
15345 mm->cached_hole_size = ~0UL;
15346 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
15347 len, pgoff, flags);
15348 @@ -387,6 +395,7 @@ fail:
15349 /*
15350 * Restore the topdown base:
15351 */
15352 + mm->mmap_base = base;
15353 mm->free_area_cache = base;
15354 mm->cached_hole_size = ~0UL;
15355
15356 @@ -400,10 +409,17 @@ hugetlb_get_unmapped_area(struct file *f
15357 struct hstate *h = hstate_file(file);
15358 struct mm_struct *mm = current->mm;
15359 struct vm_area_struct *vma;
15360 + unsigned long pax_task_size = TASK_SIZE;
15361
15362 if (len & ~huge_page_mask(h))
15363 return -EINVAL;
15364 - if (len > TASK_SIZE)
15365 +
15366 +#ifdef CONFIG_PAX_SEGMEXEC
15367 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
15368 + pax_task_size = SEGMEXEC_TASK_SIZE;
15369 +#endif
15370 +
15371 + if (len > pax_task_size)
15372 return -ENOMEM;
15373
15374 if (flags & MAP_FIXED) {
15375 @@ -415,7 +431,7 @@ hugetlb_get_unmapped_area(struct file *f
15376 if (addr) {
15377 addr = ALIGN(addr, huge_page_size(h));
15378 vma = find_vma(mm, addr);
15379 - if (TASK_SIZE - len >= addr &&
15380 + if (pax_task_size - len >= addr &&
15381 (!vma || addr + len <= vma->vm_start))
15382 return addr;
15383 }
15384 diff -urNp linux-2.6.31.1/arch/x86/mm/init_32.c linux-2.6.31.1/arch/x86/mm/init_32.c
15385 --- linux-2.6.31.1/arch/x86/mm/init_32.c 2009-09-24 11:45:25.000000000 -0400
15386 +++ linux-2.6.31.1/arch/x86/mm/init_32.c 2009-10-01 20:12:42.000000000 -0400
15387 @@ -51,6 +51,7 @@
15388 #include <asm/cacheflush.h>
15389 #include <asm/page_types.h>
15390 #include <asm/init.h>
15391 +#include <asm/desc.h>
15392
15393 unsigned long highstart_pfn, highend_pfn;
15394
15395 @@ -72,36 +73,6 @@ static __init void *alloc_low_page(void)
15396 }
15397
15398 /*
15399 - * Creates a middle page table and puts a pointer to it in the
15400 - * given global directory entry. This only returns the gd entry
15401 - * in non-PAE compilation mode, since the middle layer is folded.
15402 - */
15403 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
15404 -{
15405 - pud_t *pud;
15406 - pmd_t *pmd_table;
15407 -
15408 -#ifdef CONFIG_X86_PAE
15409 - if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
15410 - if (after_bootmem)
15411 - pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
15412 - else
15413 - pmd_table = (pmd_t *)alloc_low_page();
15414 - paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
15415 - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
15416 - pud = pud_offset(pgd, 0);
15417 - BUG_ON(pmd_table != pmd_offset(pud, 0));
15418 -
15419 - return pmd_table;
15420 - }
15421 -#endif
15422 - pud = pud_offset(pgd, 0);
15423 - pmd_table = pmd_offset(pud, 0);
15424 -
15425 - return pmd_table;
15426 -}
15427 -
15428 -/*
15429 * Create a page table and place a pointer to it in a middle page
15430 * directory entry:
15431 */
15432 @@ -121,13 +92,28 @@ static pte_t * __init one_page_table_ini
15433 page_table = (pte_t *)alloc_low_page();
15434
15435 paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
15436 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15437 + set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
15438 +#else
15439 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
15440 +#endif
15441 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
15442 }
15443
15444 return pte_offset_kernel(pmd, 0);
15445 }
15446
15447 +static pmd_t * __init one_md_table_init(pgd_t *pgd)
15448 +{
15449 + pud_t *pud;
15450 + pmd_t *pmd_table;
15451 +
15452 + pud = pud_offset(pgd, 0);
15453 + pmd_table = pmd_offset(pud, 0);
15454 +
15455 + return pmd_table;
15456 +}
15457 +
15458 pmd_t * __init populate_extra_pmd(unsigned long vaddr)
15459 {
15460 int pgd_idx = pgd_index(vaddr);
15461 @@ -201,6 +187,7 @@ page_table_range_init(unsigned long star
15462 int pgd_idx, pmd_idx;
15463 unsigned long vaddr;
15464 pgd_t *pgd;
15465 + pud_t *pud;
15466 pmd_t *pmd;
15467 pte_t *pte = NULL;
15468
15469 @@ -210,8 +197,13 @@ page_table_range_init(unsigned long star
15470 pgd = pgd_base + pgd_idx;
15471
15472 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
15473 - pmd = one_md_table_init(pgd);
15474 - pmd = pmd + pmd_index(vaddr);
15475 + pud = pud_offset(pgd, vaddr);
15476 + pmd = pmd_offset(pud, vaddr);
15477 +
15478 +#ifdef CONFIG_X86_PAE
15479 + paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
15480 +#endif
15481 +
15482 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
15483 pmd++, pmd_idx++) {
15484 pte = page_table_kmap_check(one_page_table_init(pmd),
15485 @@ -223,11 +215,23 @@ page_table_range_init(unsigned long star
15486 }
15487 }
15488
15489 -static inline int is_kernel_text(unsigned long addr)
15490 +static inline int is_kernel_text(unsigned long start, unsigned long end)
15491 {
15492 - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
15493 - return 1;
15494 - return 0;
15495 + unsigned long etext;
15496 +
15497 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
15498 + etext = ktva_ktla((unsigned long)&MODULES_EXEC_END);
15499 +#else
15500 + etext = (unsigned long)&_etext;
15501 +#endif
15502 +
15503 + if ((start > ktla_ktva(etext) ||
15504 + end <= ktla_ktva((unsigned long)_stext)) &&
15505 + (start > ktla_ktva((unsigned long)_einittext) ||
15506 + end <= ktla_ktva((unsigned long)_sinittext)) &&
15507 + (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
15508 + return 0;
15509 + return 1;
15510 }
15511
15512 /*
15513 @@ -243,9 +247,10 @@ kernel_physical_mapping_init(unsigned lo
15514 int use_pse = page_size_mask == (1<<PG_LEVEL_2M);
15515 unsigned long start_pfn, end_pfn;
15516 pgd_t *pgd_base = swapper_pg_dir;
15517 - int pgd_idx, pmd_idx, pte_ofs;
15518 + unsigned int pgd_idx, pmd_idx, pte_ofs;
15519 unsigned long pfn;
15520 pgd_t *pgd;
15521 + pud_t *pud;
15522 pmd_t *pmd;
15523 pte_t *pte;
15524 unsigned pages_2m, pages_4k;
15525 @@ -278,8 +283,13 @@ repeat:
15526 pfn = start_pfn;
15527 pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
15528 pgd = pgd_base + pgd_idx;
15529 - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
15530 - pmd = one_md_table_init(pgd);
15531 + for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
15532 + pud = pud_offset(pgd, 0);
15533 + pmd = pmd_offset(pud, 0);
15534 +
15535 +#ifdef CONFIG_X86_PAE
15536 + paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
15537 +#endif
15538
15539 if (pfn >= end_pfn)
15540 continue;
15541 @@ -291,14 +301,13 @@ repeat:
15542 #endif
15543 for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
15544 pmd++, pmd_idx++) {
15545 - unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
15546 + unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
15547
15548 /*
15549 * Map with big pages if possible, otherwise
15550 * create normal page tables:
15551 */
15552 if (use_pse) {
15553 - unsigned int addr2;
15554 pgprot_t prot = PAGE_KERNEL_LARGE;
15555 /*
15556 * first pass will use the same initial
15557 @@ -308,11 +317,7 @@ repeat:
15558 __pgprot(PTE_IDENT_ATTR |
15559 _PAGE_PSE);
15560
15561 - addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
15562 - PAGE_OFFSET + PAGE_SIZE-1;
15563 -
15564 - if (is_kernel_text(addr) ||
15565 - is_kernel_text(addr2))
15566 + if (is_kernel_text(address, address + PMD_SIZE))
15567 prot = PAGE_KERNEL_LARGE_EXEC;
15568
15569 pages_2m++;
15570 @@ -329,7 +334,7 @@ repeat:
15571 pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
15572 pte += pte_ofs;
15573 for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
15574 - pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
15575 + pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
15576 pgprot_t prot = PAGE_KERNEL;
15577 /*
15578 * first pass will use the same initial
15579 @@ -337,7 +342,7 @@ repeat:
15580 */
15581 pgprot_t init_prot = __pgprot(PTE_IDENT_ATTR);
15582
15583 - if (is_kernel_text(addr))
15584 + if (is_kernel_text(address, address + PAGE_SIZE))
15585 prot = PAGE_KERNEL_EXEC;
15586
15587 pages_4k++;
15588 @@ -489,7 +494,7 @@ void __init native_pagetable_setup_start
15589
15590 pud = pud_offset(pgd, va);
15591 pmd = pmd_offset(pud, va);
15592 - if (!pmd_present(*pmd))
15593 + if (!pmd_present(*pmd) || pmd_huge(*pmd))
15594 break;
15595
15596 pte = pte_offset_kernel(pmd, va);
15597 @@ -541,9 +546,7 @@ void __init early_ioremap_page_table_ran
15598
15599 static void __init pagetable_init(void)
15600 {
15601 - pgd_t *pgd_base = swapper_pg_dir;
15602 -
15603 - permanent_kmaps_init(pgd_base);
15604 + permanent_kmaps_init(swapper_pg_dir);
15605 }
15606
15607 #ifdef CONFIG_ACPI_SLEEP
15608 @@ -551,12 +554,12 @@ static void __init pagetable_init(void)
15609 * ACPI suspend needs this for resume, because things like the intel-agp
15610 * driver might have split up a kernel 4MB mapping.
15611 */
15612 -char swsusp_pg_dir[PAGE_SIZE]
15613 +pgd_t swsusp_pg_dir[PTRS_PER_PGD]
15614 __attribute__ ((aligned(PAGE_SIZE)));
15615
15616 static inline void save_pg_dir(void)
15617 {
15618 - memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
15619 + clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
15620 }
15621 #else /* !CONFIG_ACPI_SLEEP */
15622 static inline void save_pg_dir(void)
15623 @@ -588,7 +591,7 @@ void zap_low_mappings(bool early)
15624 flush_tlb_all();
15625 }
15626
15627 -pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
15628 +pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
15629 EXPORT_SYMBOL_GPL(__supported_pte_mask);
15630
15631 /* user-defined highmem size */
15632 @@ -883,7 +886,7 @@ void __init mem_init(void)
15633 set_highmem_pages_init();
15634
15635 codesize = (unsigned long) &_etext - (unsigned long) &_text;
15636 - datasize = (unsigned long) &_edata - (unsigned long) &_etext;
15637 + datasize = (unsigned long) &_edata - (unsigned long) &_sdata;
15638 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
15639
15640 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
15641 @@ -929,10 +932,10 @@ void __init mem_init(void)
15642 ((unsigned long)&__init_end -
15643 (unsigned long)&__init_begin) >> 10,
15644
15645 - (unsigned long)&_etext, (unsigned long)&_edata,
15646 - ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
15647 + (unsigned long)&_sdata, (unsigned long)&_edata,
15648 + ((unsigned long)&_edata - (unsigned long)&_sdata) >> 10,
15649
15650 - (unsigned long)&_text, (unsigned long)&_etext,
15651 + ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
15652 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
15653
15654 /*
15655 diff -urNp linux-2.6.31.1/arch/x86/mm/init_64.c linux-2.6.31.1/arch/x86/mm/init_64.c
15656 --- linux-2.6.31.1/arch/x86/mm/init_64.c 2009-09-24 11:45:25.000000000 -0400
15657 +++ linux-2.6.31.1/arch/x86/mm/init_64.c 2009-10-01 20:12:42.000000000 -0400
15658 @@ -159,12 +159,24 @@ void set_pte_vaddr_pud(pud_t *pud_page,
15659 pmd_t *pmd;
15660 pte_t *pte;
15661
15662 +#ifdef CONFIG_PAX_KERNEXEC
15663 + unsigned long cr0;
15664 +#endif
15665 +
15666 pud = pud_page + pud_index(vaddr);
15667 pmd = fill_pmd(pud, vaddr);
15668 pte = fill_pte(pmd, vaddr);
15669
15670 +#ifdef CONFIG_PAX_KERNEXEC
15671 + pax_open_kernel(cr0);
15672 +#endif
15673 +
15674 set_pte(pte, new_pte);
15675
15676 +#ifdef CONFIG_PAX_KERNEXEC
15677 + pax_close_kernel(cr0);
15678 +#endif
15679 +
15680 /*
15681 * It's enough to flush this one mapping.
15682 * (PGE mappings get flushed as well)
15683 @@ -222,14 +234,12 @@ static void __init __init_extra_mapping(
15684 pgd = pgd_offset_k((unsigned long)__va(phys));
15685 if (pgd_none(*pgd)) {
15686 pud = (pud_t *) spp_getpage();
15687 - set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
15688 - _PAGE_USER));
15689 + set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
15690 }
15691 pud = pud_offset(pgd, (unsigned long)__va(phys));
15692 if (pud_none(*pud)) {
15693 pmd = (pmd_t *) spp_getpage();
15694 - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
15695 - _PAGE_USER));
15696 + set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
15697 }
15698 pmd = pmd_offset(pud, phys);
15699 BUG_ON(!pmd_none(*pmd));
15700 @@ -848,8 +858,8 @@ int kern_addr_valid(unsigned long addr)
15701 static struct vm_area_struct gate_vma = {
15702 .vm_start = VSYSCALL_START,
15703 .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE),
15704 - .vm_page_prot = PAGE_READONLY_EXEC,
15705 - .vm_flags = VM_READ | VM_EXEC
15706 + .vm_page_prot = PAGE_READONLY,
15707 + .vm_flags = VM_READ
15708 };
15709
15710 struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
15711 @@ -883,7 +893,7 @@ int in_gate_area_no_task(unsigned long a
15712
15713 const char *arch_vma_name(struct vm_area_struct *vma)
15714 {
15715 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
15716 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
15717 return "[vdso]";
15718 if (vma == &gate_vma)
15719 return "[vsyscall]";
15720 diff -urNp linux-2.6.31.1/arch/x86/mm/init.c linux-2.6.31.1/arch/x86/mm/init.c
15721 --- linux-2.6.31.1/arch/x86/mm/init.c 2009-09-24 11:45:25.000000000 -0400
15722 +++ linux-2.6.31.1/arch/x86/mm/init.c 2009-10-01 20:12:42.000000000 -0400
15723 @@ -28,11 +28,10 @@ int direct_gbpages
15724 #endif
15725 ;
15726
15727 +#if defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE)
15728 int nx_enabled;
15729
15730 -#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
15731 -static int disable_nx __cpuinitdata;
15732 -
15733 +#ifndef CONFIG_PAX_PAGEEXEC
15734 /*
15735 * noexec = on|off
15736 *
15737 @@ -46,32 +45,26 @@ static int __init noexec_setup(char *str
15738 if (!str)
15739 return -EINVAL;
15740 if (!strncmp(str, "on", 2)) {
15741 - __supported_pte_mask |= _PAGE_NX;
15742 - disable_nx = 0;
15743 + nx_enabled = 1;
15744 } else if (!strncmp(str, "off", 3)) {
15745 - disable_nx = 1;
15746 - __supported_pte_mask &= ~_PAGE_NX;
15747 + nx_enabled = 0;
15748 }
15749 return 0;
15750 }
15751 early_param("noexec", noexec_setup);
15752 #endif
15753 +#endif
15754
15755 #ifdef CONFIG_X86_PAE
15756 static void __init set_nx(void)
15757 {
15758 - unsigned int v[4], l, h;
15759 -
15760 - if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
15761 - cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
15762 + if (!nx_enabled && cpu_has_nx) {
15763 + unsigned l, h;
15764
15765 - if ((v[3] & (1 << 20)) && !disable_nx) {
15766 - rdmsr(MSR_EFER, l, h);
15767 - l |= EFER_NX;
15768 - wrmsr(MSR_EFER, l, h);
15769 - nx_enabled = 1;
15770 - __supported_pte_mask |= _PAGE_NX;
15771 - }
15772 + __supported_pte_mask &= ~_PAGE_NX;
15773 + rdmsr(MSR_EFER, l, h);
15774 + l &= ~EFER_NX;
15775 + wrmsr(MSR_EFER, l, h);
15776 }
15777 }
15778 #else
15779 @@ -86,7 +79,7 @@ void __cpuinit check_efer(void)
15780 unsigned long efer;
15781
15782 rdmsrl(MSR_EFER, efer);
15783 - if (!(efer & EFER_NX) || disable_nx)
15784 + if (!(efer & EFER_NX) || !nx_enabled)
15785 __supported_pte_mask &= ~_PAGE_NX;
15786 }
15787 #endif
15788 @@ -394,7 +387,13 @@ unsigned long __init_refok init_memory_m
15789 */
15790 int devmem_is_allowed(unsigned long pagenr)
15791 {
15792 - if (pagenr <= 256)
15793 + if (!pagenr)
15794 + return 1;
15795 +#ifdef CONFIG_VM86
15796 + if (pagenr < (ISA_START_ADDRESS >> PAGE_SHIFT))
15797 + return 1;
15798 +#endif
15799 + if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
15800 return 1;
15801 if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
15802 return 0;
15803 @@ -442,6 +441,76 @@ void free_init_pages(char *what, unsigne
15804
15805 void free_initmem(void)
15806 {
15807 +
15808 +#ifdef CONFIG_PAX_KERNEXEC
15809 + pgd_t *pgd;
15810 + pud_t *pud;
15811 + pmd_t *pmd;
15812 +
15813 +#ifdef CONFIG_X86_32
15814 + /* PaX: limit KERNEL_CS to actual size */
15815 + unsigned long addr, limit;
15816 + struct desc_struct d;
15817 + int cpu;
15818 +
15819 +#ifdef CONFIG_MODULES
15820 + limit = ktva_ktla((unsigned long)&MODULES_EXEC_END);
15821 +#else
15822 + limit = (unsigned long)&_etext;
15823 +#endif
15824 + limit = (limit - 1UL) >> PAGE_SHIFT;
15825 +
15826 + memset(__LOAD_PHYSICAL_ADDR + PAGE_OFFSET, POISON_FREE_INITMEM, PAGE_SIZE);
15827 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
15828 + pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
15829 + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
15830 + }
15831 +
15832 + /* PaX: make KERNEL_CS read-only */
15833 + for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_sdata; addr += PMD_SIZE) {
15834 + pgd = pgd_offset_k(addr);
15835 + pud = pud_offset(pgd, addr);
15836 + pmd = pmd_offset(pud, addr);
15837 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
15838 + }
15839 +#ifdef CONFIG_X86_PAE
15840 + for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
15841 + pgd = pgd_offset_k(addr);
15842 + pud = pud_offset(pgd, addr);
15843 + pmd = pmd_offset(pud, addr);
15844 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
15845 + }
15846 +#endif
15847 +#else
15848 + unsigned long addr, end;
15849 +
15850 + /* PaX: make kernel code/rodata read-only, rest non-executable */
15851 + for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
15852 + pgd = pgd_offset_k(addr);
15853 + pud = pud_offset(pgd, addr);
15854 + pmd = pmd_offset(pud, addr);
15855 + if ((unsigned long)_text <= addr && addr < (unsigned long)_sdata)
15856 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
15857 + else
15858 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
15859 + }
15860 +
15861 + addr = (unsigned long)__va(__pa(__START_KERNEL_map));
15862 + end = addr + KERNEL_IMAGE_SIZE;
15863 + for (; addr < end; addr += PMD_SIZE) {
15864 + pgd = pgd_offset_k(addr);
15865 + pud = pud_offset(pgd, addr);
15866 + pmd = pmd_offset(pud, addr);
15867 + if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_sdata)))
15868 + set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
15869 + else
15870 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
15871 + }
15872 +#endif
15873 +
15874 + flush_tlb_all();
15875 +#endif
15876 +
15877 free_init_pages("unused kernel memory",
15878 (unsigned long)(&__init_begin),
15879 (unsigned long)(&__init_end));
15880 diff -urNp linux-2.6.31.1/arch/x86/mm/iomap_32.c linux-2.6.31.1/arch/x86/mm/iomap_32.c
15881 --- linux-2.6.31.1/arch/x86/mm/iomap_32.c 2009-09-24 11:45:25.000000000 -0400
15882 +++ linux-2.6.31.1/arch/x86/mm/iomap_32.c 2009-10-01 20:12:42.000000000 -0400
15883 @@ -37,12 +37,26 @@ void *kmap_atomic_prot_pfn(unsigned long
15884 enum fixed_addresses idx;
15885 unsigned long vaddr;
15886
15887 +#ifdef CONFIG_PAX_KERNEXEC
15888 + unsigned long cr0;
15889 +#endif
15890 +
15891 pagefault_disable();
15892
15893 debug_kmap_atomic(type);
15894 idx = type + KM_TYPE_NR * smp_processor_id();
15895 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
15896 +
15897 +#ifdef CONFIG_PAX_KERNEXEC
15898 + pax_open_kernel(cr0);
15899 +#endif
15900 +
15901 set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
15902 +
15903 +#ifdef CONFIG_PAX_KERNEXEC
15904 + pax_close_kernel(cr0);
15905 +#endif
15906 +
15907 arch_flush_lazy_mmu_mode();
15908
15909 return (void *)vaddr;
15910 diff -urNp linux-2.6.31.1/arch/x86/mm/ioremap.c linux-2.6.31.1/arch/x86/mm/ioremap.c
15911 --- linux-2.6.31.1/arch/x86/mm/ioremap.c 2009-09-24 11:45:25.000000000 -0400
15912 +++ linux-2.6.31.1/arch/x86/mm/ioremap.c 2009-10-01 20:12:42.000000000 -0400
15913 @@ -111,8 +111,8 @@ int page_is_ram(unsigned long pagenr)
15914 * Second special case: Some BIOSen report the PC BIOS
15915 * area (640->1Mb) as ram even though it is not.
15916 */
15917 - if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
15918 - pagenr < (BIOS_END >> PAGE_SHIFT))
15919 + if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
15920 + pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
15921 return 0;
15922
15923 for (i = 0; i < e820.nr_map; i++) {
15924 @@ -207,10 +207,7 @@ static void __iomem *__ioremap_caller(re
15925 /*
15926 * Don't allow anybody to remap normal RAM that we're using..
15927 */
15928 - for (pfn = phys_addr >> PAGE_SHIFT;
15929 - (pfn << PAGE_SHIFT) < (last_addr & PAGE_MASK);
15930 - pfn++) {
15931 -
15932 + for (pfn = phys_addr >> PAGE_SHIFT; ((resource_size_t)pfn << PAGE_SHIFT) < (last_addr & PAGE_MASK); pfn++) {
15933 int is_ram = page_is_ram(pfn);
15934
15935 if (is_ram && pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn)))
15936 @@ -272,6 +269,8 @@ static void __iomem *__ioremap_caller(re
15937 break;
15938 }
15939
15940 + prot = canon_pgprot(prot);
15941 +
15942 /*
15943 * Ok, go for it..
15944 */
15945 @@ -489,7 +488,7 @@ static int __init early_ioremap_debug_se
15946 early_param("early_ioremap_debug", early_ioremap_debug_setup);
15947
15948 static __initdata int after_paging_init;
15949 -static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
15950 +static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __read_only __aligned(PAGE_SIZE);
15951
15952 static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
15953 {
15954 @@ -521,8 +520,7 @@ void __init early_ioremap_init(void)
15955 slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
15956
15957 pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
15958 - memset(bm_pte, 0, sizeof(bm_pte));
15959 - pmd_populate_kernel(&init_mm, pmd, bm_pte);
15960 + pmd_populate_user(&init_mm, pmd, bm_pte);
15961
15962 /*
15963 * The boot-ioremap range spans multiple pmds, for which
15964 diff -urNp linux-2.6.31.1/arch/x86/mm/mmap.c linux-2.6.31.1/arch/x86/mm/mmap.c
15965 --- linux-2.6.31.1/arch/x86/mm/mmap.c 2009-09-24 11:45:25.000000000 -0400
15966 +++ linux-2.6.31.1/arch/x86/mm/mmap.c 2009-10-01 20:12:42.000000000 -0400
15967 @@ -36,7 +36,7 @@
15968 * Leave an at least ~128 MB hole.
15969 */
15970 #define MIN_GAP (128*1024*1024)
15971 -#define MAX_GAP (TASK_SIZE/6*5)
15972 +#define MAX_GAP (pax_task_size/6*5)
15973
15974 /*
15975 * True on X86_32 or when emulating IA32 on X86_64
15976 @@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
15977 return rnd << PAGE_SHIFT;
15978 }
15979
15980 -static unsigned long mmap_base(void)
15981 +static unsigned long mmap_base(struct mm_struct *mm)
15982 {
15983 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
15984 + unsigned long pax_task_size = TASK_SIZE;
15985 +
15986 +#ifdef CONFIG_PAX_SEGMEXEC
15987 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
15988 + pax_task_size = SEGMEXEC_TASK_SIZE;
15989 +#endif
15990
15991 if (gap < MIN_GAP)
15992 gap = MIN_GAP;
15993 else if (gap > MAX_GAP)
15994 gap = MAX_GAP;
15995
15996 - return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
15997 + return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
15998 }
15999
16000 /*
16001 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
16002 * does, but not when emulating X86_32
16003 */
16004 -static unsigned long mmap_legacy_base(void)
16005 +static unsigned long mmap_legacy_base(struct mm_struct *mm)
16006 {
16007 - if (mmap_is_ia32())
16008 + if (mmap_is_ia32()) {
16009 +
16010 +#ifdef CONFIG_PAX_SEGMEXEC
16011 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
16012 + return SEGMEXEC_TASK_UNMAPPED_BASE;
16013 + else
16014 +#endif
16015 +
16016 return TASK_UNMAPPED_BASE;
16017 - else
16018 + } else
16019 return TASK_UNMAPPED_BASE + mmap_rnd();
16020 }
16021
16022 @@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
16023 void arch_pick_mmap_layout(struct mm_struct *mm)
16024 {
16025 if (mmap_is_legacy()) {
16026 - mm->mmap_base = mmap_legacy_base();
16027 + mm->mmap_base = mmap_legacy_base(mm);
16028 +
16029 +#ifdef CONFIG_PAX_RANDMMAP
16030 + if (mm->pax_flags & MF_PAX_RANDMMAP)
16031 + mm->mmap_base += mm->delta_mmap;
16032 +#endif
16033 +
16034 mm->get_unmapped_area = arch_get_unmapped_area;
16035 mm->unmap_area = arch_unmap_area;
16036 } else {
16037 - mm->mmap_base = mmap_base();
16038 + mm->mmap_base = mmap_base(mm);
16039 +
16040 +#ifdef CONFIG_PAX_RANDMMAP
16041 + if (mm->pax_flags & MF_PAX_RANDMMAP)
16042 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
16043 +#endif
16044 +
16045 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
16046 mm->unmap_area = arch_unmap_area_topdown;
16047 }
16048 diff -urNp linux-2.6.31.1/arch/x86/mm/numa_32.c linux-2.6.31.1/arch/x86/mm/numa_32.c
16049 --- linux-2.6.31.1/arch/x86/mm/numa_32.c 2009-09-24 11:45:25.000000000 -0400
16050 +++ linux-2.6.31.1/arch/x86/mm/numa_32.c 2009-10-01 20:12:42.000000000 -0400
16051 @@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int
16052 }
16053 #endif
16054
16055 -extern unsigned long find_max_low_pfn(void);
16056 extern unsigned long highend_pfn, highstart_pfn;
16057
16058 #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
16059 diff -urNp linux-2.6.31.1/arch/x86/mm/pageattr.c linux-2.6.31.1/arch/x86/mm/pageattr.c
16060 --- linux-2.6.31.1/arch/x86/mm/pageattr.c 2009-09-24 11:45:25.000000000 -0400
16061 +++ linux-2.6.31.1/arch/x86/mm/pageattr.c 2009-10-01 20:12:42.000000000 -0400
16062 @@ -22,6 +22,7 @@
16063 #include <asm/pgalloc.h>
16064 #include <asm/proto.h>
16065 #include <asm/pat.h>
16066 +#include <asm/desc.h>
16067
16068 /*
16069 * The current flushing context - we pass it instead of 5 arguments:
16070 @@ -266,9 +267,10 @@ static inline pgprot_t static_protection
16071 * Does not cover __inittext since that is gone later on. On
16072 * 64bit we do not enforce !NX on the low mapping
16073 */
16074 - if (within(address, (unsigned long)_text, (unsigned long)_etext))
16075 + if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
16076 pgprot_val(forbidden) |= _PAGE_NX;
16077
16078 +#ifdef CONFIG_DEBUG_RODATA
16079 /*
16080 * The .rodata section needs to be read-only. Using the pfn
16081 * catches all aliases.
16082 @@ -276,6 +278,7 @@ static inline pgprot_t static_protection
16083 if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT,
16084 __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
16085 pgprot_val(forbidden) |= _PAGE_RW;
16086 +#endif
16087
16088 prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
16089
16090 @@ -328,8 +331,20 @@ EXPORT_SYMBOL_GPL(lookup_address);
16091 */
16092 static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
16093 {
16094 +
16095 +#ifdef CONFIG_PAX_KERNEXEC
16096 + unsigned long cr0;
16097 +
16098 + pax_open_kernel(cr0);
16099 +#endif
16100 +
16101 /* change init_mm */
16102 set_pte_atomic(kpte, pte);
16103 +
16104 +#ifdef CONFIG_PAX_KERNEXEC
16105 + pax_close_kernel(cr0);
16106 +#endif
16107 +
16108 #ifdef CONFIG_X86_32
16109 if (!SHARED_KERNEL_PMD) {
16110 struct page *page;
16111 diff -urNp linux-2.6.31.1/arch/x86/mm/pageattr-test.c linux-2.6.31.1/arch/x86/mm/pageattr-test.c
16112 --- linux-2.6.31.1/arch/x86/mm/pageattr-test.c 2009-09-24 11:45:25.000000000 -0400
16113 +++ linux-2.6.31.1/arch/x86/mm/pageattr-test.c 2009-10-01 20:12:42.000000000 -0400
16114 @@ -36,7 +36,7 @@ enum {
16115
16116 static int pte_testbit(pte_t pte)
16117 {
16118 - return pte_flags(pte) & _PAGE_UNUSED1;
16119 + return pte_flags(pte) & _PAGE_CPA_TEST;
16120 }
16121
16122 struct split_state {
16123 diff -urNp linux-2.6.31.1/arch/x86/mm/pat.c linux-2.6.31.1/arch/x86/mm/pat.c
16124 --- linux-2.6.31.1/arch/x86/mm/pat.c 2009-09-24 11:45:25.000000000 -0400
16125 +++ linux-2.6.31.1/arch/x86/mm/pat.c 2009-10-01 20:12:42.000000000 -0400
16126 @@ -213,7 +213,7 @@ chk_conflict(struct memtype *new, struct
16127
16128 conflict:
16129 printk(KERN_INFO "%s:%d conflicting memory types "
16130 - "%Lx-%Lx %s<->%s\n", current->comm, current->pid, new->start,
16131 + "%Lx-%Lx %s<->%s\n", current->comm, task_pid_nr(current), new->start,
16132 new->end, cattr_name(new->type), cattr_name(entry->type));
16133 return -EBUSY;
16134 }
16135 @@ -487,7 +487,7 @@ int free_memtype(u64 start, u64 end)
16136
16137 if (err) {
16138 printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n",
16139 - current->comm, current->pid, start, end);
16140 + current->comm, task_pid_nr(current), start, end);
16141 }
16142
16143 dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end);
16144 @@ -588,7 +588,7 @@ int kernel_map_sync_memtype(u64 base, un
16145 printk(KERN_INFO
16146 "%s:%d ioremap_change_attr failed %s "
16147 "for %Lx-%Lx\n",
16148 - current->comm, current->pid,
16149 + current->comm, task_pid_nr(current),
16150 cattr_name(flags),
16151 base, (unsigned long long)(base + size));
16152 return -EINVAL;
16153 @@ -628,7 +628,7 @@ static int reserve_pfn_range(u64 paddr,
16154 free_memtype(paddr, paddr + size);
16155 printk(KERN_ERR "%s:%d map pfn expected mapping type %s"
16156 " for %Lx-%Lx, got %s\n",
16157 - current->comm, current->pid,
16158 + current->comm, task_pid_nr(current),
16159 cattr_name(want_flags),
16160 (unsigned long long)paddr,
16161 (unsigned long long)(paddr + size),
16162 @@ -827,7 +827,7 @@ static int memtype_seq_show(struct seq_f
16163 return 0;
16164 }
16165
16166 -static struct seq_operations memtype_seq_ops = {
16167 +static const struct seq_operations memtype_seq_ops = {
16168 .start = memtype_seq_start,
16169 .next = memtype_seq_next,
16170 .stop = memtype_seq_stop,
16171 diff -urNp linux-2.6.31.1/arch/x86/mm/pgtable_32.c linux-2.6.31.1/arch/x86/mm/pgtable_32.c
16172 --- linux-2.6.31.1/arch/x86/mm/pgtable_32.c 2009-09-24 11:45:25.000000000 -0400
16173 +++ linux-2.6.31.1/arch/x86/mm/pgtable_32.c 2009-10-01 20:12:42.000000000 -0400
16174 @@ -33,6 +33,10 @@ void set_pte_vaddr(unsigned long vaddr,
16175 pmd_t *pmd;
16176 pte_t *pte;
16177
16178 +#ifdef CONFIG_PAX_KERNEXEC
16179 + unsigned long cr0;
16180 +#endif
16181 +
16182 pgd = swapper_pg_dir + pgd_index(vaddr);
16183 if (pgd_none(*pgd)) {
16184 BUG();
16185 @@ -49,11 +53,20 @@ void set_pte_vaddr(unsigned long vaddr,
16186 return;
16187 }
16188 pte = pte_offset_kernel(pmd, vaddr);
16189 +
16190 +#ifdef CONFIG_PAX_KERNEXEC
16191 + pax_open_kernel(cr0);
16192 +#endif
16193 +
16194 if (pte_val(pteval))
16195 set_pte_at(&init_mm, vaddr, pte, pteval);
16196 else
16197 pte_clear(&init_mm, vaddr, pte);
16198
16199 +#ifdef CONFIG_PAX_KERNEXEC
16200 + pax_close_kernel(cr0);
16201 +#endif
16202 +
16203 /*
16204 * It's enough to flush this one mapping.
16205 * (PGE mappings get flushed as well)
16206 diff -urNp linux-2.6.31.1/arch/x86/mm/tlb.c linux-2.6.31.1/arch/x86/mm/tlb.c
16207 --- linux-2.6.31.1/arch/x86/mm/tlb.c 2009-09-24 11:45:25.000000000 -0400
16208 +++ linux-2.6.31.1/arch/x86/mm/tlb.c 2009-10-01 20:12:42.000000000 -0400
16209 @@ -12,7 +12,7 @@
16210 #include <asm/uv/uv.h>
16211
16212 DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
16213 - = { &init_mm, 0, };
16214 + = { &init_mm, 0 };
16215
16216 /*
16217 * Smarter SMP flushing macros.
16218 diff -urNp linux-2.6.31.1/arch/x86/oprofile/backtrace.c linux-2.6.31.1/arch/x86/oprofile/backtrace.c
16219 --- linux-2.6.31.1/arch/x86/oprofile/backtrace.c 2009-09-24 11:45:25.000000000 -0400
16220 +++ linux-2.6.31.1/arch/x86/oprofile/backtrace.c 2009-10-01 20:12:42.000000000 -0400
16221 @@ -37,7 +37,7 @@ static void backtrace_address(void *data
16222 unsigned int *depth = data;
16223
16224 if ((*depth)--)
16225 - oprofile_add_trace(addr);
16226 + oprofile_add_trace(ktla_ktva(addr));
16227 }
16228
16229 static struct stacktrace_ops backtrace_ops = {
16230 @@ -77,7 +77,7 @@ x86_backtrace(struct pt_regs * const reg
16231 {
16232 struct frame_head *head = (struct frame_head *)frame_pointer(regs);
16233
16234 - if (!user_mode_vm(regs)) {
16235 + if (!user_mode(regs)) {
16236 unsigned long stack = kernel_stack_pointer(regs);
16237 if (depth)
16238 dump_trace(NULL, regs, (unsigned long *)stack, 0,
16239 diff -urNp linux-2.6.31.1/arch/x86/oprofile/op_model_p4.c linux-2.6.31.1/arch/x86/oprofile/op_model_p4.c
16240 --- linux-2.6.31.1/arch/x86/oprofile/op_model_p4.c 2009-09-24 11:45:25.000000000 -0400
16241 +++ linux-2.6.31.1/arch/x86/oprofile/op_model_p4.c 2009-10-01 20:12:42.000000000 -0400
16242 @@ -48,7 +48,7 @@ static inline void setup_num_counters(vo
16243 #endif
16244 }
16245
16246 -static int inline addr_increment(void)
16247 +static inline int addr_increment(void)
16248 {
16249 #ifdef CONFIG_SMP
16250 return smp_num_siblings == 2 ? 2 : 1;
16251 diff -urNp linux-2.6.31.1/arch/x86/pci/common.c linux-2.6.31.1/arch/x86/pci/common.c
16252 --- linux-2.6.31.1/arch/x86/pci/common.c 2009-09-24 11:45:25.000000000 -0400
16253 +++ linux-2.6.31.1/arch/x86/pci/common.c 2009-10-01 20:12:42.000000000 -0400
16254 @@ -370,7 +370,7 @@ static const struct dmi_system_id __devi
16255 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
16256 },
16257 },
16258 - {}
16259 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
16260 };
16261
16262 void __init dmi_check_pciprobe(void)
16263 diff -urNp linux-2.6.31.1/arch/x86/pci/fixup.c linux-2.6.31.1/arch/x86/pci/fixup.c
16264 --- linux-2.6.31.1/arch/x86/pci/fixup.c 2009-09-24 11:45:25.000000000 -0400
16265 +++ linux-2.6.31.1/arch/x86/pci/fixup.c 2009-10-01 20:12:42.000000000 -0400
16266 @@ -364,7 +364,7 @@ static const struct dmi_system_id __devi
16267 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
16268 },
16269 },
16270 - {}
16271 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
16272 };
16273
16274 /*
16275 @@ -435,7 +435,7 @@ static const struct dmi_system_id __devi
16276 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
16277 },
16278 },
16279 - { }
16280 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
16281 };
16282
16283 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
16284 diff -urNp linux-2.6.31.1/arch/x86/pci/i386.c linux-2.6.31.1/arch/x86/pci/i386.c
16285 --- linux-2.6.31.1/arch/x86/pci/i386.c 2009-09-24 11:45:25.000000000 -0400
16286 +++ linux-2.6.31.1/arch/x86/pci/i386.c 2009-10-01 20:12:42.000000000 -0400
16287 @@ -266,7 +266,7 @@ void pcibios_set_master(struct pci_dev *
16288 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
16289 }
16290
16291 -static struct vm_operations_struct pci_mmap_ops = {
16292 +static const struct vm_operations_struct pci_mmap_ops = {
16293 .access = generic_access_phys,
16294 };
16295
16296 diff -urNp linux-2.6.31.1/arch/x86/pci/irq.c linux-2.6.31.1/arch/x86/pci/irq.c
16297 --- linux-2.6.31.1/arch/x86/pci/irq.c 2009-09-24 11:45:25.000000000 -0400
16298 +++ linux-2.6.31.1/arch/x86/pci/irq.c 2009-10-01 20:12:42.000000000 -0400
16299 @@ -543,7 +543,7 @@ static __init int intel_router_probe(str
16300 static struct pci_device_id __initdata pirq_440gx[] = {
16301 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
16302 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
16303 - { },
16304 + { PCI_DEVICE(0, 0) }
16305 };
16306
16307 /* 440GX has a proprietary PIRQ router -- don't use it */
16308 @@ -1107,7 +1107,7 @@ static struct dmi_system_id __initdata p
16309 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
16310 },
16311 },
16312 - { }
16313 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
16314 };
16315
16316 int __init pcibios_irq_init(void)
16317 diff -urNp linux-2.6.31.1/arch/x86/pci/pcbios.c linux-2.6.31.1/arch/x86/pci/pcbios.c
16318 --- linux-2.6.31.1/arch/x86/pci/pcbios.c 2009-09-24 11:45:25.000000000 -0400
16319 +++ linux-2.6.31.1/arch/x86/pci/pcbios.c 2009-10-01 20:12:42.000000000 -0400
16320 @@ -56,50 +56,120 @@ union bios32 {
16321 static struct {
16322 unsigned long address;
16323 unsigned short segment;
16324 -} bios32_indirect = { 0, __KERNEL_CS };
16325 +} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
16326
16327 /*
16328 * Returns the entry point for the given service, NULL on error
16329 */
16330
16331 -static unsigned long bios32_service(unsigned long service)
16332 +static unsigned long __devinit bios32_service(unsigned long service)
16333 {
16334 unsigned char return_code; /* %al */
16335 unsigned long address; /* %ebx */
16336 unsigned long length; /* %ecx */
16337 unsigned long entry; /* %edx */
16338 unsigned long flags;
16339 + struct desc_struct d, *gdt;
16340 +
16341 +#ifdef CONFIG_PAX_KERNEXEC
16342 + unsigned long cr0;
16343 +#endif
16344
16345 local_irq_save(flags);
16346 - __asm__("lcall *(%%edi); cld"
16347 +
16348 + gdt = get_cpu_gdt_table(smp_processor_id());
16349 +
16350 +#ifdef CONFIG_PAX_KERNEXEC
16351 + pax_open_kernel(cr0);
16352 +#endif
16353 +
16354 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
16355 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
16356 + pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
16357 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
16358 +
16359 +#ifdef CONFIG_PAX_KERNEXEC
16360 + pax_close_kernel(cr0);
16361 +#endif
16362 +
16363 + __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
16364 : "=a" (return_code),
16365 "=b" (address),
16366 "=c" (length),
16367 "=d" (entry)
16368 : "0" (service),
16369 "1" (0),
16370 - "D" (&bios32_indirect));
16371 + "D" (&bios32_indirect),
16372 + "r"(__PCIBIOS_DS)
16373 + : "memory");
16374 +
16375 +#ifdef CONFIG_PAX_KERNEXEC
16376 + pax_open_kernel(cr0);
16377 +#endif
16378 +
16379 + gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
16380 + gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
16381 + gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
16382 + gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
16383 +
16384 +#ifdef CONFIG_PAX_KERNEXEC
16385 + pax_close_kernel(cr0);
16386 +#endif
16387 +
16388 local_irq_restore(flags);
16389
16390 switch (return_code) {
16391 - case 0:
16392 - return address + entry;
16393 - case 0x80: /* Not present */
16394 - printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
16395 - return 0;
16396 - default: /* Shouldn't happen */
16397 - printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
16398 - service, return_code);
16399 + case 0: {
16400 + int cpu;
16401 + unsigned char flags;
16402 +
16403 + printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
16404 + if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
16405 + printk(KERN_WARNING "bios32_service: not valid\n");
16406 return 0;
16407 + }
16408 + address = address + PAGE_OFFSET;
16409 + length += 16UL; /* some BIOSs underreport this... */
16410 + flags = 4;
16411 + if (length >= 64*1024*1024) {
16412 + length >>= PAGE_SHIFT;
16413 + flags |= 8;
16414 + }
16415 +
16416 +#ifdef CONFIG_PAX_KERNEXEC
16417 + pax_open_kernel(cr0);
16418 +#endif
16419 +
16420 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
16421 + gdt = get_cpu_gdt_table(cpu);
16422 + pack_descriptor(&d, address, length, 0x9b, flags);
16423 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
16424 + pack_descriptor(&d, address, length, 0x93, flags);
16425 + write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
16426 + }
16427 +
16428 +#ifdef CONFIG_PAX_KERNEXEC
16429 + pax_close_kernel(cr0);
16430 +#endif
16431 +
16432 + return entry;
16433 + }
16434 + case 0x80: /* Not present */
16435 + printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
16436 + return 0;
16437 + default: /* Shouldn't happen */
16438 + printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
16439 + service, return_code);
16440 + return 0;
16441 }
16442 }
16443
16444 static struct {
16445 unsigned long address;
16446 unsigned short segment;
16447 -} pci_indirect = { 0, __KERNEL_CS };
16448 +} pci_indirect __read_only = { 0, __PCIBIOS_CS };
16449
16450 -static int pci_bios_present;
16451 +static int pci_bios_present __read_only;
16452
16453 static int __devinit check_pcibios(void)
16454 {
16455 @@ -108,11 +178,13 @@ static int __devinit check_pcibios(void)
16456 unsigned long flags, pcibios_entry;
16457
16458 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
16459 - pci_indirect.address = pcibios_entry + PAGE_OFFSET;
16460 + pci_indirect.address = pcibios_entry;
16461
16462 local_irq_save(flags);
16463 - __asm__(
16464 - "lcall *(%%edi); cld\n\t"
16465 + __asm__("movw %w6, %%ds\n\t"
16466 + "lcall *%%ss:(%%edi); cld\n\t"
16467 + "push %%ss\n\t"
16468 + "pop %%ds\n\t"
16469 "jc 1f\n\t"
16470 "xor %%ah, %%ah\n"
16471 "1:"
16472 @@ -121,7 +193,8 @@ static int __devinit check_pcibios(void)
16473 "=b" (ebx),
16474 "=c" (ecx)
16475 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
16476 - "D" (&pci_indirect)
16477 + "D" (&pci_indirect),
16478 + "r" (__PCIBIOS_DS)
16479 : "memory");
16480 local_irq_restore(flags);
16481
16482 @@ -165,7 +238,10 @@ static int pci_bios_read(unsigned int se
16483
16484 switch (len) {
16485 case 1:
16486 - __asm__("lcall *(%%esi); cld\n\t"
16487 + __asm__("movw %w6, %%ds\n\t"
16488 + "lcall *%%ss:(%%esi); cld\n\t"
16489 + "push %%ss\n\t"
16490 + "pop %%ds\n\t"
16491 "jc 1f\n\t"
16492 "xor %%ah, %%ah\n"
16493 "1:"
16494 @@ -174,7 +250,8 @@ static int pci_bios_read(unsigned int se
16495 : "1" (PCIBIOS_READ_CONFIG_BYTE),
16496 "b" (bx),
16497 "D" ((long)reg),
16498 - "S" (&pci_indirect));
16499 + "S" (&pci_indirect),
16500 + "r" (__PCIBIOS_DS));
16501 /*
16502 * Zero-extend the result beyond 8 bits, do not trust the
16503 * BIOS having done it:
16504 @@ -182,7 +259,10 @@ static int pci_bios_read(unsigned int se
16505 *value &= 0xff;
16506 break;
16507 case 2:
16508 - __asm__("lcall *(%%esi); cld\n\t"
16509 + __asm__("movw %w6, %%ds\n\t"
16510 + "lcall *%%ss:(%%esi); cld\n\t"
16511 + "push %%ss\n\t"
16512 + "pop %%ds\n\t"
16513 "jc 1f\n\t"
16514 "xor %%ah, %%ah\n"
16515 "1:"
16516 @@ -191,7 +271,8 @@ static int pci_bios_read(unsigned int se
16517 : "1" (PCIBIOS_READ_CONFIG_WORD),
16518 "b" (bx),
16519 "D" ((long)reg),
16520 - "S" (&pci_indirect));
16521 + "S" (&pci_indirect),
16522 + "r" (__PCIBIOS_DS));
16523 /*
16524 * Zero-extend the result beyond 16 bits, do not trust the
16525 * BIOS having done it:
16526 @@ -199,7 +280,10 @@ static int pci_bios_read(unsigned int se
16527 *value &= 0xffff;
16528 break;
16529 case 4:
16530 - __asm__("lcall *(%%esi); cld\n\t"
16531 + __asm__("movw %w6, %%ds\n\t"
16532 + "lcall *%%ss:(%%esi); cld\n\t"
16533 + "push %%ss\n\t"
16534 + "pop %%ds\n\t"
16535 "jc 1f\n\t"
16536 "xor %%ah, %%ah\n"
16537 "1:"
16538 @@ -208,7 +292,8 @@ static int pci_bios_read(unsigned int se
16539 : "1" (PCIBIOS_READ_CONFIG_DWORD),
16540 "b" (bx),
16541 "D" ((long)reg),
16542 - "S" (&pci_indirect));
16543 + "S" (&pci_indirect),
16544 + "r" (__PCIBIOS_DS));
16545 break;
16546 }
16547
16548 @@ -231,7 +316,10 @@ static int pci_bios_write(unsigned int s
16549
16550 switch (len) {
16551 case 1:
16552 - __asm__("lcall *(%%esi); cld\n\t"
16553 + __asm__("movw %w6, %%ds\n\t"
16554 + "lcall *%%ss:(%%esi); cld\n\t"
16555 + "push %%ss\n\t"
16556 + "pop %%ds\n\t"
16557 "jc 1f\n\t"
16558 "xor %%ah, %%ah\n"
16559 "1:"
16560 @@ -240,10 +328,14 @@ static int pci_bios_write(unsigned int s
16561 "c" (value),
16562 "b" (bx),
16563 "D" ((long)reg),
16564 - "S" (&pci_indirect));
16565 + "S" (&pci_indirect),
16566 + "r" (__PCIBIOS_DS));
16567 break;
16568 case 2:
16569 - __asm__("lcall *(%%esi); cld\n\t"
16570 + __asm__("movw %w6, %%ds\n\t"
16571 + "lcall *%%ss:(%%esi); cld\n\t"
16572 + "push %%ss\n\t"
16573 + "pop %%ds\n\t"
16574 "jc 1f\n\t"
16575 "xor %%ah, %%ah\n"
16576 "1:"
16577 @@ -252,10 +344,14 @@ static int pci_bios_write(unsigned int s
16578 "c" (value),
16579 "b" (bx),
16580 "D" ((long)reg),
16581 - "S" (&pci_indirect));
16582 + "S" (&pci_indirect),
16583 + "r" (__PCIBIOS_DS));
16584 break;
16585 case 4:
16586 - __asm__("lcall *(%%esi); cld\n\t"
16587 + __asm__("movw %w6, %%ds\n\t"
16588 + "lcall *%%ss:(%%esi); cld\n\t"
16589 + "push %%ss\n\t"
16590 + "pop %%ds\n\t"
16591 "jc 1f\n\t"
16592 "xor %%ah, %%ah\n"
16593 "1:"
16594 @@ -264,7 +360,8 @@ static int pci_bios_write(unsigned int s
16595 "c" (value),
16596 "b" (bx),
16597 "D" ((long)reg),
16598 - "S" (&pci_indirect));
16599 + "S" (&pci_indirect),
16600 + "r" (__PCIBIOS_DS));
16601 break;
16602 }
16603
16604 @@ -368,10 +465,13 @@ struct irq_routing_table * pcibios_get_i
16605
16606 DBG("PCI: Fetching IRQ routing table... ");
16607 __asm__("push %%es\n\t"
16608 + "movw %w8, %%ds\n\t"
16609 "push %%ds\n\t"
16610 "pop %%es\n\t"
16611 - "lcall *(%%esi); cld\n\t"
16612 + "lcall *%%ss:(%%esi); cld\n\t"
16613 "pop %%es\n\t"
16614 + "push %%ss\n\t"
16615 + "pop %%ds\n"
16616 "jc 1f\n\t"
16617 "xor %%ah, %%ah\n"
16618 "1:"
16619 @@ -382,7 +482,8 @@ struct irq_routing_table * pcibios_get_i
16620 "1" (0),
16621 "D" ((long) &opt),
16622 "S" (&pci_indirect),
16623 - "m" (opt)
16624 + "m" (opt),
16625 + "r" (__PCIBIOS_DS)
16626 : "memory");
16627 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
16628 if (ret & 0xff00)
16629 @@ -406,7 +507,10 @@ int pcibios_set_irq_routing(struct pci_d
16630 {
16631 int ret;
16632
16633 - __asm__("lcall *(%%esi); cld\n\t"
16634 + __asm__("movw %w5, %%ds\n\t"
16635 + "lcall *%%ss:(%%esi); cld\n\t"
16636 + "push %%ss\n\t"
16637 + "pop %%ds\n"
16638 "jc 1f\n\t"
16639 "xor %%ah, %%ah\n"
16640 "1:"
16641 @@ -414,7 +518,8 @@ int pcibios_set_irq_routing(struct pci_d
16642 : "0" (PCIBIOS_SET_PCI_HW_INT),
16643 "b" ((dev->bus->number << 8) | dev->devfn),
16644 "c" ((irq << 8) | (pin + 10)),
16645 - "S" (&pci_indirect));
16646 + "S" (&pci_indirect),
16647 + "r" (__PCIBIOS_DS));
16648 return !(ret & 0xff00);
16649 }
16650 EXPORT_SYMBOL(pcibios_set_irq_routing);
16651 diff -urNp linux-2.6.31.1/arch/x86/power/cpu.c linux-2.6.31.1/arch/x86/power/cpu.c
16652 --- linux-2.6.31.1/arch/x86/power/cpu.c 2009-09-24 11:45:25.000000000 -0400
16653 +++ linux-2.6.31.1/arch/x86/power/cpu.c 2009-10-01 20:12:42.000000000 -0400
16654 @@ -126,7 +126,11 @@ static void do_fpu_end(void)
16655 static void fix_processor_context(void)
16656 {
16657 int cpu = smp_processor_id();
16658 - struct tss_struct *t = &per_cpu(init_tss, cpu);
16659 + struct tss_struct *t = init_tss + cpu;
16660 +
16661 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_KERNEXEC)
16662 + unsigned long cr0;
16663 +#endif
16664
16665 set_tss_desc(cpu, t); /*
16666 * This just modifies memory; should not be
16667 @@ -136,8 +140,17 @@ static void fix_processor_context(void)
16668 */
16669
16670 #ifdef CONFIG_X86_64
16671 +
16672 +#ifdef CONFIG_PAX_KERNEXEC
16673 + pax_open_kernel(cr0);
16674 +#endif
16675 +
16676 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
16677
16678 +#ifdef CONFIG_PAX_KERNEXEC
16679 + pax_close_kernel(cr0);
16680 +#endif
16681 +
16682 syscall_init(); /* This sets MSR_*STAR and related */
16683 #endif
16684 load_TR_desc(); /* This does ltr */
16685 diff -urNp linux-2.6.31.1/arch/x86/vdso/Makefile linux-2.6.31.1/arch/x86/vdso/Makefile
16686 --- linux-2.6.31.1/arch/x86/vdso/Makefile 2009-09-24 11:45:25.000000000 -0400
16687 +++ linux-2.6.31.1/arch/x86/vdso/Makefile 2009-10-01 20:12:42.000000000 -0400
16688 @@ -122,7 +122,7 @@ quiet_cmd_vdso = VDSO $@
16689 $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
16690 -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^)
16691
16692 -VDSO_LDFLAGS = -fPIC -shared $(call ld-option, -Wl$(comma)--hash-style=sysv)
16693 +VDSO_LDFLAGS = -fPIC -shared --no-undefined $(call ld-option, -Wl$(comma)--hash-style=sysv)
16694 GCOV_PROFILE := n
16695
16696 #
16697 diff -urNp linux-2.6.31.1/arch/x86/vdso/vclock_gettime.c linux-2.6.31.1/arch/x86/vdso/vclock_gettime.c
16698 --- linux-2.6.31.1/arch/x86/vdso/vclock_gettime.c 2009-09-24 11:45:25.000000000 -0400
16699 +++ linux-2.6.31.1/arch/x86/vdso/vclock_gettime.c 2009-10-01 20:12:42.000000000 -0400
16700 @@ -22,24 +22,48 @@
16701 #include <asm/hpet.h>
16702 #include <asm/unistd.h>
16703 #include <asm/io.h>
16704 +#include <asm/fixmap.h>
16705 #include "vextern.h"
16706
16707 #define gtod vdso_vsyscall_gtod_data
16708
16709 +notrace noinline long __vdso_fallback_time(long *t)
16710 +{
16711 + long secs;
16712 + asm volatile("syscall"
16713 + : "=a" (secs)
16714 + : "0" (__NR_time),"D" (t) : "r11", "cx", "memory");
16715 + return secs;
16716 +}
16717 +
16718 notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
16719 {
16720 long ret;
16721 asm("syscall" : "=a" (ret) :
16722 - "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "memory");
16723 + "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "r11", "cx", "memory");
16724 return ret;
16725 }
16726
16727 +notrace static inline cycle_t __vdso_vread_hpet(void)
16728 +{
16729 + return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0);
16730 +}
16731 +
16732 +notrace static inline cycle_t __vdso_vread_tsc(void)
16733 +{
16734 + cycle_t ret = (cycle_t)vget_cycles();
16735 +
16736 + return ret >= gtod->clock.cycle_last ? ret : gtod->clock.cycle_last;
16737 +}
16738 +
16739 notrace static inline long vgetns(void)
16740 {
16741 long v;
16742 - cycles_t (*vread)(void);
16743 - vread = gtod->clock.vread;
16744 - v = (vread() - gtod->clock.cycle_last) & gtod->clock.mask;
16745 + if (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3])
16746 + v = __vdso_vread_tsc();
16747 + else
16748 + v = __vdso_vread_hpet();
16749 + v = (v - gtod->clock.cycle_last) & gtod->clock.mask;
16750 return (v * gtod->clock.mult) >> gtod->clock.shift;
16751 }
16752
16753 @@ -88,7 +112,9 @@ notrace static noinline int do_monotonic
16754
16755 notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
16756 {
16757 - if (likely(gtod->sysctl_enabled && gtod->clock.vread))
16758 + if (likely(gtod->sysctl_enabled &&
16759 + ((gtod->clock.name[0] == 'h' && gtod->clock.name[1] == 'p' && gtod->clock.name[2] == 'e' && gtod->clock.name[3] == 't' && !gtod->clock.name[4]) ||
16760 + (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3]))))
16761 switch (clock) {
16762 case CLOCK_REALTIME:
16763 return do_realtime(ts);
16764 @@ -100,10 +126,20 @@ notrace int __vdso_clock_gettime(clockid
16765 int clock_gettime(clockid_t, struct timespec *)
16766 __attribute__((weak, alias("__vdso_clock_gettime")));
16767
16768 -notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
16769 +notrace noinline int __vdso_fallback_gettimeofday(struct timeval *tv, struct timezone *tz)
16770 {
16771 long ret;
16772 - if (likely(gtod->sysctl_enabled && gtod->clock.vread)) {
16773 + asm("syscall" : "=a" (ret) :
16774 + "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "r11", "cx", "memory");
16775 + return ret;
16776 +}
16777 +
16778 +notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
16779 +{
16780 + if (likely(gtod->sysctl_enabled &&
16781 + ((gtod->clock.name[0] == 'h' && gtod->clock.name[1] == 'p' && gtod->clock.name[2] == 'e' && gtod->clock.name[3] == 't' && !gtod->clock.name[4]) ||
16782 + (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3]))))
16783 + {
16784 if (likely(tv != NULL)) {
16785 BUILD_BUG_ON(offsetof(struct timeval, tv_usec) !=
16786 offsetof(struct timespec, tv_nsec) ||
16787 @@ -118,9 +154,7 @@ notrace int __vdso_gettimeofday(struct t
16788 }
16789 return 0;
16790 }
16791 - asm("syscall" : "=a" (ret) :
16792 - "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory");
16793 - return ret;
16794 + return __vdso_fallback_gettimeofday(tv, tz);
16795 }
16796 int gettimeofday(struct timeval *, struct timezone *)
16797 __attribute__((weak, alias("__vdso_gettimeofday")));
16798 diff -urNp linux-2.6.31.1/arch/x86/vdso/vdso32-setup.c linux-2.6.31.1/arch/x86/vdso/vdso32-setup.c
16799 --- linux-2.6.31.1/arch/x86/vdso/vdso32-setup.c 2009-09-24 11:45:25.000000000 -0400
16800 +++ linux-2.6.31.1/arch/x86/vdso/vdso32-setup.c 2009-10-01 20:12:42.000000000 -0400
16801 @@ -25,6 +25,7 @@
16802 #include <asm/tlbflush.h>
16803 #include <asm/vdso.h>
16804 #include <asm/proto.h>
16805 +#include <asm/mman.h>
16806
16807 enum {
16808 VDSO_DISABLED = 0,
16809 @@ -226,7 +227,7 @@ static inline void map_compat_vdso(int m
16810 void enable_sep_cpu(void)
16811 {
16812 int cpu = get_cpu();
16813 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
16814 + struct tss_struct *tss = init_tss + cpu;
16815
16816 if (!boot_cpu_has(X86_FEATURE_SEP)) {
16817 put_cpu();
16818 @@ -249,7 +250,7 @@ static int __init gate_vma_init(void)
16819 gate_vma.vm_start = FIXADDR_USER_START;
16820 gate_vma.vm_end = FIXADDR_USER_END;
16821 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
16822 - gate_vma.vm_page_prot = __P101;
16823 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
16824 /*
16825 * Make sure the vDSO gets into every core dump.
16826 * Dumping its contents makes post-mortem fully interpretable later
16827 @@ -331,14 +332,14 @@ int arch_setup_additional_pages(struct l
16828 if (compat)
16829 addr = VDSO_HIGH_BASE;
16830 else {
16831 - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
16832 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
16833 if (IS_ERR_VALUE(addr)) {
16834 ret = addr;
16835 goto up_fail;
16836 }
16837 }
16838
16839 - current->mm->context.vdso = (void *)addr;
16840 + current->mm->context.vdso = addr;
16841
16842 if (compat_uses_vma || !compat) {
16843 /*
16844 @@ -365,7 +366,7 @@ int arch_setup_additional_pages(struct l
16845
16846 up_fail:
16847 if (ret)
16848 - current->mm->context.vdso = NULL;
16849 + current->mm->context.vdso = 0;
16850
16851 up_write(&mm->mmap_sem);
16852
16853 @@ -388,7 +389,7 @@ static ctl_table abi_table2[] = {
16854 .mode = 0644,
16855 .proc_handler = proc_dointvec
16856 },
16857 - {}
16858 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
16859 };
16860
16861 static ctl_table abi_root_table2[] = {
16862 @@ -398,7 +399,7 @@ static ctl_table abi_root_table2[] = {
16863 .mode = 0555,
16864 .child = abi_table2
16865 },
16866 - {}
16867 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
16868 };
16869
16870 static __init int ia32_binfmt_init(void)
16871 @@ -413,8 +414,14 @@ __initcall(ia32_binfmt_init);
16872
16873 const char *arch_vma_name(struct vm_area_struct *vma)
16874 {
16875 - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
16876 + if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
16877 return "[vdso]";
16878 +
16879 +#ifdef CONFIG_PAX_SEGMEXEC
16880 + if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
16881 + return "[vdso]";
16882 +#endif
16883 +
16884 return NULL;
16885 }
16886
16887 @@ -423,7 +430,7 @@ struct vm_area_struct *get_gate_vma(stru
16888 struct mm_struct *mm = tsk->mm;
16889
16890 /* Check to see if this task was created in compat vdso mode */
16891 - if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
16892 + if (mm && mm->context.vdso == VDSO_HIGH_BASE)
16893 return &gate_vma;
16894 return NULL;
16895 }
16896 diff -urNp linux-2.6.31.1/arch/x86/vdso/vdso.lds.S linux-2.6.31.1/arch/x86/vdso/vdso.lds.S
16897 --- linux-2.6.31.1/arch/x86/vdso/vdso.lds.S 2009-09-24 11:45:25.000000000 -0400
16898 +++ linux-2.6.31.1/arch/x86/vdso/vdso.lds.S 2009-10-01 20:12:42.000000000 -0400
16899 @@ -35,3 +35,9 @@ VDSO64_PRELINK = VDSO_PRELINK;
16900 #define VEXTERN(x) VDSO64_ ## x = vdso_ ## x;
16901 #include "vextern.h"
16902 #undef VEXTERN
16903 +
16904 +#define VEXTERN(x) VDSO64_ ## x = __vdso_ ## x;
16905 +VEXTERN(fallback_gettimeofday)
16906 +VEXTERN(fallback_time)
16907 +VEXTERN(getcpu)
16908 +#undef VEXTERN
16909 diff -urNp linux-2.6.31.1/arch/x86/vdso/vextern.h linux-2.6.31.1/arch/x86/vdso/vextern.h
16910 --- linux-2.6.31.1/arch/x86/vdso/vextern.h 2009-09-24 11:45:25.000000000 -0400
16911 +++ linux-2.6.31.1/arch/x86/vdso/vextern.h 2009-10-01 20:12:42.000000000 -0400
16912 @@ -11,6 +11,5 @@
16913 put into vextern.h and be referenced as a pointer with vdso prefix.
16914 The main kernel later fills in the values. */
16915
16916 -VEXTERN(jiffies)
16917 VEXTERN(vgetcpu_mode)
16918 VEXTERN(vsyscall_gtod_data)
16919 diff -urNp linux-2.6.31.1/arch/x86/vdso/vma.c linux-2.6.31.1/arch/x86/vdso/vma.c
16920 --- linux-2.6.31.1/arch/x86/vdso/vma.c 2009-09-24 11:45:25.000000000 -0400
16921 +++ linux-2.6.31.1/arch/x86/vdso/vma.c 2009-10-01 20:12:42.000000000 -0400
16922 @@ -57,7 +57,7 @@ static int __init init_vdso_vars(void)
16923 if (!vbase)
16924 goto oom;
16925
16926 - if (memcmp(vbase, "\177ELF", 4)) {
16927 + if (memcmp(vbase, ELFMAG, SELFMAG)) {
16928 printk("VDSO: I'm broken; not ELF\n");
16929 vdso_enabled = 0;
16930 }
16931 @@ -66,6 +66,7 @@ static int __init init_vdso_vars(void)
16932 *(typeof(__ ## x) **) var_ref(VDSO64_SYMBOL(vbase, x), #x) = &__ ## x;
16933 #include "vextern.h"
16934 #undef VEXTERN
16935 + vunmap(vbase);
16936 return 0;
16937
16938 oom:
16939 @@ -116,7 +117,7 @@ int arch_setup_additional_pages(struct l
16940 goto up_fail;
16941 }
16942
16943 - current->mm->context.vdso = (void *)addr;
16944 + current->mm->context.vdso = addr;
16945
16946 ret = install_special_mapping(mm, addr, vdso_size,
16947 VM_READ|VM_EXEC|
16948 @@ -124,7 +125,7 @@ int arch_setup_additional_pages(struct l
16949 VM_ALWAYSDUMP,
16950 vdso_pages);
16951 if (ret) {
16952 - current->mm->context.vdso = NULL;
16953 + current->mm->context.vdso = 0;
16954 goto up_fail;
16955 }
16956
16957 @@ -132,10 +133,3 @@ up_fail:
16958 up_write(&mm->mmap_sem);
16959 return ret;
16960 }
16961 -
16962 -static __init int vdso_setup(char *s)
16963 -{
16964 - vdso_enabled = simple_strtoul(s, NULL, 0);
16965 - return 0;
16966 -}
16967 -__setup("vdso=", vdso_setup);
16968 diff -urNp linux-2.6.31.1/arch/x86/xen/debugfs.c linux-2.6.31.1/arch/x86/xen/debugfs.c
16969 --- linux-2.6.31.1/arch/x86/xen/debugfs.c 2009-09-24 11:45:25.000000000 -0400
16970 +++ linux-2.6.31.1/arch/x86/xen/debugfs.c 2009-10-01 20:12:42.000000000 -0400
16971 @@ -100,7 +100,7 @@ static int xen_array_release(struct inod
16972 return 0;
16973 }
16974
16975 -static struct file_operations u32_array_fops = {
16976 +static const struct file_operations u32_array_fops = {
16977 .owner = THIS_MODULE,
16978 .open = u32_array_open,
16979 .release= xen_array_release,
16980 diff -urNp linux-2.6.31.1/arch/x86/xen/enlighten.c linux-2.6.31.1/arch/x86/xen/enlighten.c
16981 --- linux-2.6.31.1/arch/x86/xen/enlighten.c 2009-09-24 11:45:25.000000000 -0400
16982 +++ linux-2.6.31.1/arch/x86/xen/enlighten.c 2009-10-01 20:12:42.000000000 -0400
16983 @@ -69,8 +69,6 @@ EXPORT_SYMBOL_GPL(xen_start_info);
16984
16985 struct shared_info xen_dummy_shared_info;
16986
16987 -void *xen_initial_gdt;
16988 -
16989 /*
16990 * Point at some empty memory to start with. We map the real shared_info
16991 * page as soon as fixmap is up and running.
16992 @@ -490,7 +488,7 @@ static void xen_write_idt_entry(gate_des
16993
16994 preempt_disable();
16995
16996 - start = __get_cpu_var(idt_desc).address;
16997 + start = (unsigned long)__get_cpu_var(idt_desc).address;
16998 end = start + __get_cpu_var(idt_desc).size + 1;
16999
17000 xen_mc_flush();
17001 @@ -1010,13 +1008,6 @@ asmlinkage void __init xen_start_kernel(
17002
17003 machine_ops = xen_machine_ops;
17004
17005 - /*
17006 - * The only reliable way to retain the initial address of the
17007 - * percpu gdt_page is to remember it here, so we can go and
17008 - * mark it RW later, when the initial percpu area is freed.
17009 - */
17010 - xen_initial_gdt = &per_cpu(gdt_page, 0);
17011 -
17012 xen_smp_init();
17013
17014 /* Get mfn list */
17015 diff -urNp linux-2.6.31.1/arch/x86/xen/mmu.c linux-2.6.31.1/arch/x86/xen/mmu.c
17016 --- linux-2.6.31.1/arch/x86/xen/mmu.c 2009-09-24 11:45:25.000000000 -0400
17017 +++ linux-2.6.31.1/arch/x86/xen/mmu.c 2009-10-01 20:12:42.000000000 -0400
17018 @@ -1707,6 +1707,8 @@ __init pgd_t *xen_setup_kernel_pagetable
17019 convert_pfn_mfn(init_level4_pgt);
17020 convert_pfn_mfn(level3_ident_pgt);
17021 convert_pfn_mfn(level3_kernel_pgt);
17022 + convert_pfn_mfn(level3_vmalloc_pgt);
17023 + convert_pfn_mfn(level3_vmemmap_pgt);
17024
17025 l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
17026 l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
17027 @@ -1725,7 +1727,10 @@ __init pgd_t *xen_setup_kernel_pagetable
17028 set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
17029 set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
17030 set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
17031 + set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
17032 + set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
17033 set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
17034 + set_page_prot(level2_vmemmap_pgt, PAGE_KERNEL_RO);
17035 set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
17036 set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
17037
17038 diff -urNp linux-2.6.31.1/arch/x86/xen/smp.c linux-2.6.31.1/arch/x86/xen/smp.c
17039 --- linux-2.6.31.1/arch/x86/xen/smp.c 2009-09-24 11:45:25.000000000 -0400
17040 +++ linux-2.6.31.1/arch/x86/xen/smp.c 2009-10-01 20:12:42.000000000 -0400
17041 @@ -167,11 +167,6 @@ static void __init xen_smp_prepare_boot_
17042 {
17043 BUG_ON(smp_processor_id() != 0);
17044 native_smp_prepare_boot_cpu();
17045 -
17046 - /* We've switched to the "real" per-cpu gdt, so make sure the
17047 - old memory can be recycled */
17048 - make_lowmem_page_readwrite(xen_initial_gdt);
17049 -
17050 xen_setup_vcpu_info_placement();
17051 }
17052
17053 @@ -231,8 +226,8 @@ cpu_initialize_context(unsigned int cpu,
17054 gdt = get_cpu_gdt_table(cpu);
17055
17056 ctxt->flags = VGCF_IN_KERNEL;
17057 - ctxt->user_regs.ds = __USER_DS;
17058 - ctxt->user_regs.es = __USER_DS;
17059 + ctxt->user_regs.ds = __KERNEL_DS;
17060 + ctxt->user_regs.es = __KERNEL_DS;
17061 ctxt->user_regs.ss = __KERNEL_DS;
17062 #ifdef CONFIG_X86_32
17063 ctxt->user_regs.fs = __KERNEL_PERCPU;
17064 diff -urNp linux-2.6.31.1/arch/x86/xen/xen-ops.h linux-2.6.31.1/arch/x86/xen/xen-ops.h
17065 --- linux-2.6.31.1/arch/x86/xen/xen-ops.h 2009-09-24 11:45:25.000000000 -0400
17066 +++ linux-2.6.31.1/arch/x86/xen/xen-ops.h 2009-10-01 20:12:42.000000000 -0400
17067 @@ -10,8 +10,6 @@
17068 extern const char xen_hypervisor_callback[];
17069 extern const char xen_failsafe_callback[];
17070
17071 -extern void *xen_initial_gdt;
17072 -
17073 struct trap_info;
17074 void xen_copy_trap_info(struct trap_info *traps);
17075
17076 diff -urNp linux-2.6.31.1/arch/xtensa/include/asm/atomic.h linux-2.6.31.1/arch/xtensa/include/asm/atomic.h
17077 --- linux-2.6.31.1/arch/xtensa/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400
17078 +++ linux-2.6.31.1/arch/xtensa/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400
17079 @@ -49,6 +49,14 @@
17080 #define atomic_read(v) ((v)->counter)
17081
17082 /**
17083 + * atomic_read_unchecked - read atomic variable
17084 + * @v: pointer of type atomic_unchecked_t
17085 + *
17086 + * Atomically reads the value of @v.
17087 + */
17088 +#define atomic_read_unchecked(v) ((v)->counter)
17089 +
17090 +/**
17091 * atomic_set - set atomic variable
17092 * @v: pointer of type atomic_t
17093 * @i: required value
17094 @@ -58,6 +66,15 @@
17095 #define atomic_set(v,i) ((v)->counter = (i))
17096
17097 /**
17098 + * atomic_set_unchecked - set atomic variable
17099 + * @v: pointer of type atomic_unchecked_t
17100 + * @i: required value
17101 + *
17102 + * Atomically sets the value of @v to @i.
17103 + */
17104 +#define atomic_set_unchecked(v,i) ((v)->counter = (i))
17105 +
17106 +/**
17107 * atomic_add - add integer to atomic variable
17108 * @i: integer value to add
17109 * @v: pointer of type atomic_t
17110 @@ -81,6 +98,11 @@ static inline void atomic_add(int i, ato
17111 );
17112 }
17113
17114 +static inline void atomic_add_unchecked(int i, atomic_unchecked_t * v)
17115 +{
17116 + atomic_add(i, (atomic_t *)v);
17117 +}
17118 +
17119 /**
17120 * atomic_sub - subtract the atomic variable
17121 * @i: integer value to subtract
17122 @@ -105,6 +127,11 @@ static inline void atomic_sub(int i, ato
17123 );
17124 }
17125
17126 +static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
17127 +{
17128 + atomic_sub(i, (atomic_t *)v);
17129 +}
17130 +
17131 /*
17132 * We use atomic_{add|sub}_return to define other functions.
17133 */
17134 @@ -165,6 +192,7 @@ static inline int atomic_sub_return(int
17135 * Atomically increments @v by 1.
17136 */
17137 #define atomic_inc(v) atomic_add(1,(v))
17138 +#define atomic_inc_unchecked(v) atomic_add_unchecked(1,(v))
17139
17140 /**
17141 * atomic_inc - increment atomic variable
17142 diff -urNp linux-2.6.31.1/crypto/lrw.c linux-2.6.31.1/crypto/lrw.c
17143 --- linux-2.6.31.1/crypto/lrw.c 2009-09-24 11:45:25.000000000 -0400
17144 +++ linux-2.6.31.1/crypto/lrw.c 2009-10-01 20:12:42.000000000 -0400
17145 @@ -60,7 +60,7 @@ static int setkey(struct crypto_tfm *par
17146 struct priv *ctx = crypto_tfm_ctx(parent);
17147 struct crypto_cipher *child = ctx->child;
17148 int err, i;
17149 - be128 tmp = { 0 };
17150 + be128 tmp = { 0, 0 };
17151 int bsize = crypto_cipher_blocksize(child);
17152
17153 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
17154 diff -urNp linux-2.6.31.1/Documentation/dontdiff linux-2.6.31.1/Documentation/dontdiff
17155 --- linux-2.6.31.1/Documentation/dontdiff 2009-09-24 11:45:25.000000000 -0400
17156 +++ linux-2.6.31.1/Documentation/dontdiff 2009-10-01 20:12:42.000000000 -0400
17157 @@ -3,6 +3,7 @@
17158 *.bin
17159 *.cpio
17160 *.csp
17161 +*.dbg
17162 *.dsp
17163 *.dvi
17164 *.elf
17165 @@ -49,11 +50,16 @@
17166 53c700_d.h
17167 CVS
17168 ChangeSet
17169 +GPATH
17170 +GRTAGS
17171 +GSYMS
17172 +GTAGS
17173 Image
17174 Kerntypes
17175 Module.markers
17176 Module.symvers
17177 PENDING
17178 +PERF*
17179 SCCS
17180 System.map*
17181 TAGS
17182 @@ -76,7 +82,9 @@ btfixupprep
17183 build
17184 bvmlinux
17185 bzImage*
17186 +capflags.c
17187 classlist.h*
17188 +common-cmds.h
17189 comp*.log
17190 compile.h*
17191 conf
17192 @@ -103,13 +111,14 @@ gen_crc32table
17193 gen_init_cpio
17194 genksyms
17195 *_gray256.c
17196 +hash
17197 ihex2fw
17198 ikconfig.h*
17199 initramfs_data.cpio
17200 +initramfs_data.cpio.bz2
17201 initramfs_data.cpio.gz
17202 initramfs_list
17203 kallsyms
17204 -kconfig
17205 keywords.c
17206 ksym.c*
17207 ksym.h*
17208 @@ -133,6 +142,7 @@ mkboot
17209 mkbugboot
17210 mkcpustr
17211 mkdep
17212 +mkpiggy
17213 mkprep
17214 mktables
17215 mktree
17216 @@ -149,6 +159,7 @@ patches*
17217 pca200e.bin
17218 pca200e_ecd.bin2
17219 piggy.gz
17220 +piggy.S
17221 piggyback
17222 pnmtologo
17223 ppc_defs.h*
17224 @@ -164,6 +175,7 @@ setup
17225 setup.bin
17226 setup.elf
17227 sImage
17228 +slabinfo
17229 sm_tbl*
17230 split-include
17231 syscalltab.h
17232 @@ -187,14 +199,20 @@ version.h*
17233 vmlinux
17234 vmlinux-*
17235 vmlinux.aout
17236 +vmlinux.bin.all
17237 +vmlinux.bin.bz2
17238 vmlinux.lds
17239 +vmlinux.relocs
17240 +voffset.h
17241 vsyscall.lds
17242 vsyscall_32.lds
17243 wanxlfw.inc
17244 uImage
17245 unifdef
17246 +utsrelease.h
17247 wakeup.bin
17248 wakeup.elf
17249 wakeup.lds
17250 zImage*
17251 zconf.hash.c
17252 +zoffset.h
17253 diff -urNp linux-2.6.31.1/Documentation/kernel-parameters.txt linux-2.6.31.1/Documentation/kernel-parameters.txt
17254 --- linux-2.6.31.1/Documentation/kernel-parameters.txt 2009-09-24 11:45:25.000000000 -0400
17255 +++ linux-2.6.31.1/Documentation/kernel-parameters.txt 2009-10-01 20:12:42.000000000 -0400
17256 @@ -1776,6 +1776,12 @@ and is between 256 and 4096 characters.
17257 the specified number of seconds. This is to be used if
17258 your oopses keep scrolling off the screen.
17259
17260 + pax_nouderef [X86-32] disables UDEREF. Most likely needed under certain
17261 + virtualization environments that don't cope well with the
17262 + expand down segment used by UDEREF on X86-32.
17263 +
17264 + pax_softmode= [X86-32] 0/1 to disable/enable PaX softmode on boot already.
17265 +
17266 pcbit= [HW,ISDN]
17267
17268 pcd. [PARIDE]
17269 diff -urNp linux-2.6.31.1/drivers/acpi/blacklist.c linux-2.6.31.1/drivers/acpi/blacklist.c
17270 --- linux-2.6.31.1/drivers/acpi/blacklist.c 2009-09-24 11:45:25.000000000 -0400
17271 +++ linux-2.6.31.1/drivers/acpi/blacklist.c 2009-10-01 20:12:42.000000000 -0400
17272 @@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
17273 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
17274 "Incorrect _ADR", 1},
17275
17276 - {""}
17277 + {"", "", 0, 0, 0, all_versions, 0}
17278 };
17279
17280 #if CONFIG_ACPI_BLACKLIST_YEAR
17281 diff -urNp linux-2.6.31.1/drivers/acpi/osl.c linux-2.6.31.1/drivers/acpi/osl.c
17282 --- linux-2.6.31.1/drivers/acpi/osl.c 2009-09-24 11:45:25.000000000 -0400
17283 +++ linux-2.6.31.1/drivers/acpi/osl.c 2009-10-01 20:12:42.000000000 -0400
17284 @@ -521,6 +521,8 @@ acpi_os_read_memory(acpi_physical_addres
17285 void __iomem *virt_addr;
17286
17287 virt_addr = ioremap(phys_addr, width);
17288 + if (!virt_addr)
17289 + return AE_NO_MEMORY;
17290 if (!value)
17291 value = &dummy;
17292
17293 @@ -549,6 +551,8 @@ acpi_os_write_memory(acpi_physical_addre
17294 void __iomem *virt_addr;
17295
17296 virt_addr = ioremap(phys_addr, width);
17297 + if (!virt_addr)
17298 + return AE_NO_MEMORY;
17299
17300 switch (width) {
17301 case 8:
17302 diff -urNp linux-2.6.31.1/drivers/acpi/processor_core.c linux-2.6.31.1/drivers/acpi/processor_core.c
17303 --- linux-2.6.31.1/drivers/acpi/processor_core.c 2009-09-24 11:45:25.000000000 -0400
17304 +++ linux-2.6.31.1/drivers/acpi/processor_core.c 2009-10-01 20:12:42.000000000 -0400
17305 @@ -712,7 +712,7 @@ static int __cpuinit acpi_processor_star
17306 return 0;
17307 }
17308
17309 - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
17310 + BUG_ON(pr->id >= nr_cpu_ids);
17311
17312 /*
17313 * Buggy BIOS check
17314 diff -urNp linux-2.6.31.1/drivers/acpi/processor_idle.c linux-2.6.31.1/drivers/acpi/processor_idle.c
17315 --- linux-2.6.31.1/drivers/acpi/processor_idle.c 2009-09-24 11:45:25.000000000 -0400
17316 +++ linux-2.6.31.1/drivers/acpi/processor_idle.c 2009-10-01 20:12:42.000000000 -0400
17317 @@ -108,7 +108,7 @@ static struct dmi_system_id __cpuinitdat
17318 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
17319 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
17320 (void *)2},
17321 - {},
17322 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL},
17323 };
17324
17325
17326 diff -urNp linux-2.6.31.1/drivers/acpi/video.c linux-2.6.31.1/drivers/acpi/video.c
17327 --- linux-2.6.31.1/drivers/acpi/video.c 2009-09-24 11:45:25.000000000 -0400
17328 +++ linux-2.6.31.1/drivers/acpi/video.c 2009-10-01 20:12:42.000000000 -0400
17329 @@ -283,7 +283,7 @@ static int acpi_video_device_brightness_
17330 struct file *file);
17331 static ssize_t acpi_video_device_write_brightness(struct file *file,
17332 const char __user *buffer, size_t count, loff_t *data);
17333 -static struct file_operations acpi_video_device_brightness_fops = {
17334 +static const struct file_operations acpi_video_device_brightness_fops = {
17335 .owner = THIS_MODULE,
17336 .open = acpi_video_device_brightness_open_fs,
17337 .read = seq_read,
17338 diff -urNp linux-2.6.31.1/drivers/ata/ahci.c linux-2.6.31.1/drivers/ata/ahci.c
17339 --- linux-2.6.31.1/drivers/ata/ahci.c 2009-09-24 11:45:25.000000000 -0400
17340 +++ linux-2.6.31.1/drivers/ata/ahci.c 2009-10-01 20:12:42.000000000 -0400
17341 @@ -629,7 +629,7 @@ static const struct pci_device_id ahci_p
17342 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
17343 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
17344
17345 - { } /* terminate list */
17346 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
17347 };
17348
17349
17350 diff -urNp linux-2.6.31.1/drivers/ata/ata_piix.c linux-2.6.31.1/drivers/ata/ata_piix.c
17351 --- linux-2.6.31.1/drivers/ata/ata_piix.c 2009-09-24 11:45:25.000000000 -0400
17352 +++ linux-2.6.31.1/drivers/ata/ata_piix.c 2009-10-01 20:12:42.000000000 -0400
17353 @@ -291,7 +291,7 @@ static const struct pci_device_id piix_p
17354 { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
17355 /* SATA Controller IDE (PCH) */
17356 { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
17357 - { } /* terminate list */
17358 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
17359 };
17360
17361 static struct pci_driver piix_pci_driver = {
17362 @@ -608,7 +608,7 @@ static const struct ich_laptop ich_lapto
17363 { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
17364 { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */
17365 /* end marker */
17366 - { 0, }
17367 + { 0, 0, 0 }
17368 };
17369
17370 /**
17371 @@ -1086,7 +1086,7 @@ static int piix_broken_suspend(void)
17372 },
17373 },
17374
17375 - { } /* terminate list */
17376 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } /* terminate list */
17377 };
17378 static const char *oemstrs[] = {
17379 "Tecra M3,",
17380 diff -urNp linux-2.6.31.1/drivers/ata/libata-core.c linux-2.6.31.1/drivers/ata/libata-core.c
17381 --- linux-2.6.31.1/drivers/ata/libata-core.c 2009-09-24 11:45:25.000000000 -0400
17382 +++ linux-2.6.31.1/drivers/ata/libata-core.c 2009-10-01 20:12:42.000000000 -0400
17383 @@ -896,7 +896,7 @@ static const struct ata_xfer_ent {
17384 { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
17385 { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
17386 { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
17387 - { -1, },
17388 + { -1, 0, 0 }
17389 };
17390
17391 /**
17392 @@ -3141,7 +3141,7 @@ static const struct ata_timing ata_timin
17393 { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 },
17394 { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 },
17395
17396 - { 0xFF }
17397 + { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
17398 };
17399
17400 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
17401 @@ -4339,7 +4339,7 @@ static const struct ata_blacklist_entry
17402 { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER },
17403
17404 /* End Marker */
17405 - { }
17406 + { NULL, NULL, 0 }
17407 };
17408
17409 static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
17410 diff -urNp linux-2.6.31.1/drivers/atm/adummy.c linux-2.6.31.1/drivers/atm/adummy.c
17411 --- linux-2.6.31.1/drivers/atm/adummy.c 2009-09-24 11:45:25.000000000 -0400
17412 +++ linux-2.6.31.1/drivers/atm/adummy.c 2009-10-01 20:12:42.000000000 -0400
17413 @@ -77,7 +77,7 @@ adummy_send(struct atm_vcc *vcc, struct
17414 vcc->pop(vcc, skb);
17415 else
17416 dev_kfree_skb_any(skb);
17417 - atomic_inc(&vcc->stats->tx);
17418 + atomic_inc_unchecked(&vcc->stats->tx);
17419
17420 return 0;
17421 }
17422 diff -urNp linux-2.6.31.1/drivers/atm/ambassador.c linux-2.6.31.1/drivers/atm/ambassador.c
17423 --- linux-2.6.31.1/drivers/atm/ambassador.c 2009-09-24 11:45:25.000000000 -0400
17424 +++ linux-2.6.31.1/drivers/atm/ambassador.c 2009-10-01 20:12:42.000000000 -0400
17425 @@ -453,7 +453,7 @@ static void tx_complete (amb_dev * dev,
17426 PRINTD (DBG_FLOW|DBG_TX, "tx_complete %p %p", dev, tx);
17427
17428 // VC layer stats
17429 - atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
17430 + atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
17431
17432 // free the descriptor
17433 kfree (tx_descr);
17434 @@ -494,7 +494,7 @@ static void rx_complete (amb_dev * dev,
17435 dump_skb ("<<<", vc, skb);
17436
17437 // VC layer stats
17438 - atomic_inc(&atm_vcc->stats->rx);
17439 + atomic_inc_unchecked(&atm_vcc->stats->rx);
17440 __net_timestamp(skb);
17441 // end of our responsability
17442 atm_vcc->push (atm_vcc, skb);
17443 @@ -509,7 +509,7 @@ static void rx_complete (amb_dev * dev,
17444 } else {
17445 PRINTK (KERN_INFO, "dropped over-size frame");
17446 // should we count this?
17447 - atomic_inc(&atm_vcc->stats->rx_drop);
17448 + atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
17449 }
17450
17451 } else {
17452 @@ -1349,7 +1349,7 @@ static int amb_send (struct atm_vcc * at
17453 }
17454
17455 if (check_area (skb->data, skb->len)) {
17456 - atomic_inc(&atm_vcc->stats->tx_err);
17457 + atomic_inc_unchecked(&atm_vcc->stats->tx_err);
17458 return -ENOMEM; // ?
17459 }
17460
17461 diff -urNp linux-2.6.31.1/drivers/atm/atmtcp.c linux-2.6.31.1/drivers/atm/atmtcp.c
17462 --- linux-2.6.31.1/drivers/atm/atmtcp.c 2009-09-24 11:45:25.000000000 -0400
17463 +++ linux-2.6.31.1/drivers/atm/atmtcp.c 2009-10-01 20:12:42.000000000 -0400
17464 @@ -206,7 +206,7 @@ static int atmtcp_v_send(struct atm_vcc
17465 if (vcc->pop) vcc->pop(vcc,skb);
17466 else dev_kfree_skb(skb);
17467 if (dev_data) return 0;
17468 - atomic_inc(&vcc->stats->tx_err);
17469 + atomic_inc_unchecked(&vcc->stats->tx_err);
17470 return -ENOLINK;
17471 }
17472 size = skb->len+sizeof(struct atmtcp_hdr);
17473 @@ -214,7 +214,7 @@ static int atmtcp_v_send(struct atm_vcc
17474 if (!new_skb) {
17475 if (vcc->pop) vcc->pop(vcc,skb);
17476 else dev_kfree_skb(skb);
17477 - atomic_inc(&vcc->stats->tx_err);
17478 + atomic_inc_unchecked(&vcc->stats->tx_err);
17479 return -ENOBUFS;
17480 }
17481 hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr));
17482 @@ -225,8 +225,8 @@ static int atmtcp_v_send(struct atm_vcc
17483 if (vcc->pop) vcc->pop(vcc,skb);
17484 else dev_kfree_skb(skb);
17485 out_vcc->push(out_vcc,new_skb);
17486 - atomic_inc(&vcc->stats->tx);
17487 - atomic_inc(&out_vcc->stats->rx);
17488 + atomic_inc_unchecked(&vcc->stats->tx);
17489 + atomic_inc_unchecked(&out_vcc->stats->rx);
17490 return 0;
17491 }
17492
17493 @@ -300,7 +300,7 @@ static int atmtcp_c_send(struct atm_vcc
17494 out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci));
17495 read_unlock(&vcc_sklist_lock);
17496 if (!out_vcc) {
17497 - atomic_inc(&vcc->stats->tx_err);
17498 + atomic_inc_unchecked(&vcc->stats->tx_err);
17499 goto done;
17500 }
17501 skb_pull(skb,sizeof(struct atmtcp_hdr));
17502 @@ -312,8 +312,8 @@ static int atmtcp_c_send(struct atm_vcc
17503 __net_timestamp(new_skb);
17504 skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
17505 out_vcc->push(out_vcc,new_skb);
17506 - atomic_inc(&vcc->stats->tx);
17507 - atomic_inc(&out_vcc->stats->rx);
17508 + atomic_inc_unchecked(&vcc->stats->tx);
17509 + atomic_inc_unchecked(&out_vcc->stats->rx);
17510 done:
17511 if (vcc->pop) vcc->pop(vcc,skb);
17512 else dev_kfree_skb(skb);
17513 diff -urNp linux-2.6.31.1/drivers/atm/eni.c linux-2.6.31.1/drivers/atm/eni.c
17514 --- linux-2.6.31.1/drivers/atm/eni.c 2009-09-24 11:45:25.000000000 -0400
17515 +++ linux-2.6.31.1/drivers/atm/eni.c 2009-10-01 20:12:42.000000000 -0400
17516 @@ -525,7 +525,7 @@ static int rx_aal0(struct atm_vcc *vcc)
17517 DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
17518 vcc->dev->number);
17519 length = 0;
17520 - atomic_inc(&vcc->stats->rx_err);
17521 + atomic_inc_unchecked(&vcc->stats->rx_err);
17522 }
17523 else {
17524 length = ATM_CELL_SIZE-1; /* no HEC */
17525 @@ -580,7 +580,7 @@ static int rx_aal5(struct atm_vcc *vcc)
17526 size);
17527 }
17528 eff = length = 0;
17529 - atomic_inc(&vcc->stats->rx_err);
17530 + atomic_inc_unchecked(&vcc->stats->rx_err);
17531 }
17532 else {
17533 size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
17534 @@ -597,7 +597,7 @@ static int rx_aal5(struct atm_vcc *vcc)
17535 "(VCI=%d,length=%ld,size=%ld (descr 0x%lx))\n",
17536 vcc->dev->number,vcc->vci,length,size << 2,descr);
17537 length = eff = 0;
17538 - atomic_inc(&vcc->stats->rx_err);
17539 + atomic_inc_unchecked(&vcc->stats->rx_err);
17540 }
17541 }
17542 skb = eff ? atm_alloc_charge(vcc,eff << 2,GFP_ATOMIC) : NULL;
17543 @@ -770,7 +770,7 @@ rx_dequeued++;
17544 vcc->push(vcc,skb);
17545 pushed++;
17546 }
17547 - atomic_inc(&vcc->stats->rx);
17548 + atomic_inc_unchecked(&vcc->stats->rx);
17549 }
17550 wake_up(&eni_dev->rx_wait);
17551 }
17552 @@ -1227,7 +1227,7 @@ static void dequeue_tx(struct atm_dev *d
17553 PCI_DMA_TODEVICE);
17554 if (vcc->pop) vcc->pop(vcc,skb);
17555 else dev_kfree_skb_irq(skb);
17556 - atomic_inc(&vcc->stats->tx);
17557 + atomic_inc_unchecked(&vcc->stats->tx);
17558 wake_up(&eni_dev->tx_wait);
17559 dma_complete++;
17560 }
17561 diff -urNp linux-2.6.31.1/drivers/atm/firestream.c linux-2.6.31.1/drivers/atm/firestream.c
17562 --- linux-2.6.31.1/drivers/atm/firestream.c 2009-09-24 11:45:25.000000000 -0400
17563 +++ linux-2.6.31.1/drivers/atm/firestream.c 2009-10-01 20:12:42.000000000 -0400
17564 @@ -748,7 +748,7 @@ static void process_txdone_queue (struct
17565 }
17566 }
17567
17568 - atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
17569 + atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
17570
17571 fs_dprintk (FS_DEBUG_TXMEM, "i");
17572 fs_dprintk (FS_DEBUG_ALLOC, "Free t-skb: %p\n", skb);
17573 @@ -815,7 +815,7 @@ static void process_incoming (struct fs_
17574 #endif
17575 skb_put (skb, qe->p1 & 0xffff);
17576 ATM_SKB(skb)->vcc = atm_vcc;
17577 - atomic_inc(&atm_vcc->stats->rx);
17578 + atomic_inc_unchecked(&atm_vcc->stats->rx);
17579 __net_timestamp(skb);
17580 fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb);
17581 atm_vcc->push (atm_vcc, skb);
17582 @@ -836,12 +836,12 @@ static void process_incoming (struct fs_
17583 kfree (pe);
17584 }
17585 if (atm_vcc)
17586 - atomic_inc(&atm_vcc->stats->rx_drop);
17587 + atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
17588 break;
17589 case 0x1f: /* Reassembly abort: no buffers. */
17590 /* Silently increment error counter. */
17591 if (atm_vcc)
17592 - atomic_inc(&atm_vcc->stats->rx_drop);
17593 + atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
17594 break;
17595 default: /* Hmm. Haven't written the code to handle the others yet... -- REW */
17596 printk (KERN_WARNING "Don't know what to do with RX status %x: %s.\n",
17597 diff -urNp linux-2.6.31.1/drivers/atm/fore200e.c linux-2.6.31.1/drivers/atm/fore200e.c
17598 --- linux-2.6.31.1/drivers/atm/fore200e.c 2009-09-24 11:45:25.000000000 -0400
17599 +++ linux-2.6.31.1/drivers/atm/fore200e.c 2009-10-01 20:12:42.000000000 -0400
17600 @@ -931,9 +931,9 @@ fore200e_tx_irq(struct fore200e* fore200
17601 #endif
17602 /* check error condition */
17603 if (*entry->status & STATUS_ERROR)
17604 - atomic_inc(&vcc->stats->tx_err);
17605 + atomic_inc_unchecked(&vcc->stats->tx_err);
17606 else
17607 - atomic_inc(&vcc->stats->tx);
17608 + atomic_inc_unchecked(&vcc->stats->tx);
17609 }
17610 }
17611
17612 @@ -1082,7 +1082,7 @@ fore200e_push_rpd(struct fore200e* fore2
17613 if (skb == NULL) {
17614 DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
17615
17616 - atomic_inc(&vcc->stats->rx_drop);
17617 + atomic_inc_unchecked(&vcc->stats->rx_drop);
17618 return -ENOMEM;
17619 }
17620
17621 @@ -1125,14 +1125,14 @@ fore200e_push_rpd(struct fore200e* fore2
17622
17623 dev_kfree_skb_any(skb);
17624
17625 - atomic_inc(&vcc->stats->rx_drop);
17626 + atomic_inc_unchecked(&vcc->stats->rx_drop);
17627 return -ENOMEM;
17628 }
17629
17630 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
17631
17632 vcc->push(vcc, skb);
17633 - atomic_inc(&vcc->stats->rx);
17634 + atomic_inc_unchecked(&vcc->stats->rx);
17635
17636 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
17637
17638 @@ -1210,7 +1210,7 @@ fore200e_rx_irq(struct fore200e* fore200
17639 DPRINTK(2, "damaged PDU on %d.%d.%d\n",
17640 fore200e->atm_dev->number,
17641 entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
17642 - atomic_inc(&vcc->stats->rx_err);
17643 + atomic_inc_unchecked(&vcc->stats->rx_err);
17644 }
17645 }
17646
17647 @@ -1655,7 +1655,7 @@ fore200e_send(struct atm_vcc *vcc, struc
17648 goto retry_here;
17649 }
17650
17651 - atomic_inc(&vcc->stats->tx_err);
17652 + atomic_inc_unchecked(&vcc->stats->tx_err);
17653
17654 fore200e->tx_sat++;
17655 DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
17656 diff -urNp linux-2.6.31.1/drivers/atm/he.c linux-2.6.31.1/drivers/atm/he.c
17657 --- linux-2.6.31.1/drivers/atm/he.c 2009-09-24 11:45:25.000000000 -0400
17658 +++ linux-2.6.31.1/drivers/atm/he.c 2009-10-01 20:12:42.000000000 -0400
17659 @@ -1728,7 +1728,7 @@ he_service_rbrq(struct he_dev *he_dev, i
17660
17661 if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
17662 hprintk("HBUF_ERR! (cid 0x%x)\n", cid);
17663 - atomic_inc(&vcc->stats->rx_drop);
17664 + atomic_inc_unchecked(&vcc->stats->rx_drop);
17665 goto return_host_buffers;
17666 }
17667
17668 @@ -1761,7 +1761,7 @@ he_service_rbrq(struct he_dev *he_dev, i
17669 RBRQ_LEN_ERR(he_dev->rbrq_head)
17670 ? "LEN_ERR" : "",
17671 vcc->vpi, vcc->vci);
17672 - atomic_inc(&vcc->stats->rx_err);
17673 + atomic_inc_unchecked(&vcc->stats->rx_err);
17674 goto return_host_buffers;
17675 }
17676
17677 @@ -1820,7 +1820,7 @@ he_service_rbrq(struct he_dev *he_dev, i
17678 vcc->push(vcc, skb);
17679 spin_lock(&he_dev->global_lock);
17680
17681 - atomic_inc(&vcc->stats->rx);
17682 + atomic_inc_unchecked(&vcc->stats->rx);
17683
17684 return_host_buffers:
17685 ++pdus_assembled;
17686 @@ -2165,7 +2165,7 @@ __enqueue_tpd(struct he_dev *he_dev, str
17687 tpd->vcc->pop(tpd->vcc, tpd->skb);
17688 else
17689 dev_kfree_skb_any(tpd->skb);
17690 - atomic_inc(&tpd->vcc->stats->tx_err);
17691 + atomic_inc_unchecked(&tpd->vcc->stats->tx_err);
17692 }
17693 pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
17694 return;
17695 @@ -2577,7 +2577,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
17696 vcc->pop(vcc, skb);
17697 else
17698 dev_kfree_skb_any(skb);
17699 - atomic_inc(&vcc->stats->tx_err);
17700 + atomic_inc_unchecked(&vcc->stats->tx_err);
17701 return -EINVAL;
17702 }
17703
17704 @@ -2588,7 +2588,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
17705 vcc->pop(vcc, skb);
17706 else
17707 dev_kfree_skb_any(skb);
17708 - atomic_inc(&vcc->stats->tx_err);
17709 + atomic_inc_unchecked(&vcc->stats->tx_err);
17710 return -EINVAL;
17711 }
17712 #endif
17713 @@ -2600,7 +2600,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
17714 vcc->pop(vcc, skb);
17715 else
17716 dev_kfree_skb_any(skb);
17717 - atomic_inc(&vcc->stats->tx_err);
17718 + atomic_inc_unchecked(&vcc->stats->tx_err);
17719 spin_unlock_irqrestore(&he_dev->global_lock, flags);
17720 return -ENOMEM;
17721 }
17722 @@ -2642,7 +2642,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
17723 vcc->pop(vcc, skb);
17724 else
17725 dev_kfree_skb_any(skb);
17726 - atomic_inc(&vcc->stats->tx_err);
17727 + atomic_inc_unchecked(&vcc->stats->tx_err);
17728 spin_unlock_irqrestore(&he_dev->global_lock, flags);
17729 return -ENOMEM;
17730 }
17731 @@ -2673,7 +2673,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
17732 __enqueue_tpd(he_dev, tpd, cid);
17733 spin_unlock_irqrestore(&he_dev->global_lock, flags);
17734
17735 - atomic_inc(&vcc->stats->tx);
17736 + atomic_inc_unchecked(&vcc->stats->tx);
17737
17738 return 0;
17739 }
17740 diff -urNp linux-2.6.31.1/drivers/atm/horizon.c linux-2.6.31.1/drivers/atm/horizon.c
17741 --- linux-2.6.31.1/drivers/atm/horizon.c 2009-09-24 11:45:25.000000000 -0400
17742 +++ linux-2.6.31.1/drivers/atm/horizon.c 2009-10-01 20:12:42.000000000 -0400
17743 @@ -1033,7 +1033,7 @@ static void rx_schedule (hrz_dev * dev,
17744 {
17745 struct atm_vcc * vcc = ATM_SKB(skb)->vcc;
17746 // VC layer stats
17747 - atomic_inc(&vcc->stats->rx);
17748 + atomic_inc_unchecked(&vcc->stats->rx);
17749 __net_timestamp(skb);
17750 // end of our responsability
17751 vcc->push (vcc, skb);
17752 @@ -1185,7 +1185,7 @@ static void tx_schedule (hrz_dev * const
17753 dev->tx_iovec = NULL;
17754
17755 // VC layer stats
17756 - atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
17757 + atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
17758
17759 // free the skb
17760 hrz_kfree_skb (skb);
17761 diff -urNp linux-2.6.31.1/drivers/atm/idt77252.c linux-2.6.31.1/drivers/atm/idt77252.c
17762 --- linux-2.6.31.1/drivers/atm/idt77252.c 2009-09-24 11:45:25.000000000 -0400
17763 +++ linux-2.6.31.1/drivers/atm/idt77252.c 2009-10-01 20:12:42.000000000 -0400
17764 @@ -810,7 +810,7 @@ drain_scq(struct idt77252_dev *card, str
17765 else
17766 dev_kfree_skb(skb);
17767
17768 - atomic_inc(&vcc->stats->tx);
17769 + atomic_inc_unchecked(&vcc->stats->tx);
17770 }
17771
17772 atomic_dec(&scq->used);
17773 @@ -1073,13 +1073,13 @@ dequeue_rx(struct idt77252_dev *card, st
17774 if ((sb = dev_alloc_skb(64)) == NULL) {
17775 printk("%s: Can't allocate buffers for aal0.\n",
17776 card->name);
17777 - atomic_add(i, &vcc->stats->rx_drop);
17778 + atomic_add_unchecked(i, &vcc->stats->rx_drop);
17779 break;
17780 }
17781 if (!atm_charge(vcc, sb->truesize)) {
17782 RXPRINTK("%s: atm_charge() dropped aal0 packets.\n",
17783 card->name);
17784 - atomic_add(i - 1, &vcc->stats->rx_drop);
17785 + atomic_add_unchecked(i - 1, &vcc->stats->rx_drop);
17786 dev_kfree_skb(sb);
17787 break;
17788 }
17789 @@ -1096,7 +1096,7 @@ dequeue_rx(struct idt77252_dev *card, st
17790 ATM_SKB(sb)->vcc = vcc;
17791 __net_timestamp(sb);
17792 vcc->push(vcc, sb);
17793 - atomic_inc(&vcc->stats->rx);
17794 + atomic_inc_unchecked(&vcc->stats->rx);
17795
17796 cell += ATM_CELL_PAYLOAD;
17797 }
17798 @@ -1133,13 +1133,13 @@ dequeue_rx(struct idt77252_dev *card, st
17799 "(CDC: %08x)\n",
17800 card->name, len, rpp->len, readl(SAR_REG_CDC));
17801 recycle_rx_pool_skb(card, rpp);
17802 - atomic_inc(&vcc->stats->rx_err);
17803 + atomic_inc_unchecked(&vcc->stats->rx_err);
17804 return;
17805 }
17806 if (stat & SAR_RSQE_CRC) {
17807 RXPRINTK("%s: AAL5 CRC error.\n", card->name);
17808 recycle_rx_pool_skb(card, rpp);
17809 - atomic_inc(&vcc->stats->rx_err);
17810 + atomic_inc_unchecked(&vcc->stats->rx_err);
17811 return;
17812 }
17813 if (skb_queue_len(&rpp->queue) > 1) {
17814 @@ -1150,7 +1150,7 @@ dequeue_rx(struct idt77252_dev *card, st
17815 RXPRINTK("%s: Can't alloc RX skb.\n",
17816 card->name);
17817 recycle_rx_pool_skb(card, rpp);
17818 - atomic_inc(&vcc->stats->rx_err);
17819 + atomic_inc_unchecked(&vcc->stats->rx_err);
17820 return;
17821 }
17822 if (!atm_charge(vcc, skb->truesize)) {
17823 @@ -1169,7 +1169,7 @@ dequeue_rx(struct idt77252_dev *card, st
17824 __net_timestamp(skb);
17825
17826 vcc->push(vcc, skb);
17827 - atomic_inc(&vcc->stats->rx);
17828 + atomic_inc_unchecked(&vcc->stats->rx);
17829
17830 return;
17831 }
17832 @@ -1191,7 +1191,7 @@ dequeue_rx(struct idt77252_dev *card, st
17833 __net_timestamp(skb);
17834
17835 vcc->push(vcc, skb);
17836 - atomic_inc(&vcc->stats->rx);
17837 + atomic_inc_unchecked(&vcc->stats->rx);
17838
17839 if (skb->truesize > SAR_FB_SIZE_3)
17840 add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);
17841 @@ -1303,14 +1303,14 @@ idt77252_rx_raw(struct idt77252_dev *car
17842 if (vcc->qos.aal != ATM_AAL0) {
17843 RPRINTK("%s: raw cell for non AAL0 vc %u.%u\n",
17844 card->name, vpi, vci);
17845 - atomic_inc(&vcc->stats->rx_drop);
17846 + atomic_inc_unchecked(&vcc->stats->rx_drop);
17847 goto drop;
17848 }
17849
17850 if ((sb = dev_alloc_skb(64)) == NULL) {
17851 printk("%s: Can't allocate buffers for AAL0.\n",
17852 card->name);
17853 - atomic_inc(&vcc->stats->rx_err);
17854 + atomic_inc_unchecked(&vcc->stats->rx_err);
17855 goto drop;
17856 }
17857
17858 @@ -1329,7 +1329,7 @@ idt77252_rx_raw(struct idt77252_dev *car
17859 ATM_SKB(sb)->vcc = vcc;
17860 __net_timestamp(sb);
17861 vcc->push(vcc, sb);
17862 - atomic_inc(&vcc->stats->rx);
17863 + atomic_inc_unchecked(&vcc->stats->rx);
17864
17865 drop:
17866 skb_pull(queue, 64);
17867 @@ -1954,13 +1954,13 @@ idt77252_send_skb(struct atm_vcc *vcc, s
17868
17869 if (vc == NULL) {
17870 printk("%s: NULL connection in send().\n", card->name);
17871 - atomic_inc(&vcc->stats->tx_err);
17872 + atomic_inc_unchecked(&vcc->stats->tx_err);
17873 dev_kfree_skb(skb);
17874 return -EINVAL;
17875 }
17876 if (!test_bit(VCF_TX, &vc->flags)) {
17877 printk("%s: Trying to transmit on a non-tx VC.\n", card->name);
17878 - atomic_inc(&vcc->stats->tx_err);
17879 + atomic_inc_unchecked(&vcc->stats->tx_err);
17880 dev_kfree_skb(skb);
17881 return -EINVAL;
17882 }
17883 @@ -1972,14 +1972,14 @@ idt77252_send_skb(struct atm_vcc *vcc, s
17884 break;
17885 default:
17886 printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
17887 - atomic_inc(&vcc->stats->tx_err);
17888 + atomic_inc_unchecked(&vcc->stats->tx_err);
17889 dev_kfree_skb(skb);
17890 return -EINVAL;
17891 }
17892
17893 if (skb_shinfo(skb)->nr_frags != 0) {
17894 printk("%s: No scatter-gather yet.\n", card->name);
17895 - atomic_inc(&vcc->stats->tx_err);
17896 + atomic_inc_unchecked(&vcc->stats->tx_err);
17897 dev_kfree_skb(skb);
17898 return -EINVAL;
17899 }
17900 @@ -1987,7 +1987,7 @@ idt77252_send_skb(struct atm_vcc *vcc, s
17901
17902 err = queue_skb(card, vc, skb, oam);
17903 if (err) {
17904 - atomic_inc(&vcc->stats->tx_err);
17905 + atomic_inc_unchecked(&vcc->stats->tx_err);
17906 dev_kfree_skb(skb);
17907 return err;
17908 }
17909 @@ -2010,7 +2010,7 @@ idt77252_send_oam(struct atm_vcc *vcc, v
17910 skb = dev_alloc_skb(64);
17911 if (!skb) {
17912 printk("%s: Out of memory in send_oam().\n", card->name);
17913 - atomic_inc(&vcc->stats->tx_err);
17914 + atomic_inc_unchecked(&vcc->stats->tx_err);
17915 return -ENOMEM;
17916 }
17917 atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
17918 diff -urNp linux-2.6.31.1/drivers/atm/iphase.c linux-2.6.31.1/drivers/atm/iphase.c
17919 --- linux-2.6.31.1/drivers/atm/iphase.c 2009-09-24 11:45:25.000000000 -0400
17920 +++ linux-2.6.31.1/drivers/atm/iphase.c 2009-10-01 20:12:42.000000000 -0400
17921 @@ -1123,7 +1123,7 @@ static int rx_pkt(struct atm_dev *dev)
17922 status = (u_short) (buf_desc_ptr->desc_mode);
17923 if (status & (RX_CER | RX_PTE | RX_OFL))
17924 {
17925 - atomic_inc(&vcc->stats->rx_err);
17926 + atomic_inc_unchecked(&vcc->stats->rx_err);
17927 IF_ERR(printk("IA: bad packet, dropping it");)
17928 if (status & RX_CER) {
17929 IF_ERR(printk(" cause: packet CRC error\n");)
17930 @@ -1146,7 +1146,7 @@ static int rx_pkt(struct atm_dev *dev)
17931 len = dma_addr - buf_addr;
17932 if (len > iadev->rx_buf_sz) {
17933 printk("Over %d bytes sdu received, dropped!!!\n", iadev->rx_buf_sz);
17934 - atomic_inc(&vcc->stats->rx_err);
17935 + atomic_inc_unchecked(&vcc->stats->rx_err);
17936 goto out_free_desc;
17937 }
17938
17939 @@ -1296,7 +1296,7 @@ static void rx_dle_intr(struct atm_dev *
17940 ia_vcc = INPH_IA_VCC(vcc);
17941 if (ia_vcc == NULL)
17942 {
17943 - atomic_inc(&vcc->stats->rx_err);
17944 + atomic_inc_unchecked(&vcc->stats->rx_err);
17945 dev_kfree_skb_any(skb);
17946 atm_return(vcc, atm_guess_pdu2truesize(len));
17947 goto INCR_DLE;
17948 @@ -1308,7 +1308,7 @@ static void rx_dle_intr(struct atm_dev *
17949 if ((length > iadev->rx_buf_sz) || (length >
17950 (skb->len - sizeof(struct cpcs_trailer))))
17951 {
17952 - atomic_inc(&vcc->stats->rx_err);
17953 + atomic_inc_unchecked(&vcc->stats->rx_err);
17954 IF_ERR(printk("rx_dle_intr: Bad AAL5 trailer %d (skb len %d)",
17955 length, skb->len);)
17956 dev_kfree_skb_any(skb);
17957 @@ -1324,7 +1324,7 @@ static void rx_dle_intr(struct atm_dev *
17958
17959 IF_RX(printk("rx_dle_intr: skb push");)
17960 vcc->push(vcc,skb);
17961 - atomic_inc(&vcc->stats->rx);
17962 + atomic_inc_unchecked(&vcc->stats->rx);
17963 iadev->rx_pkt_cnt++;
17964 }
17965 INCR_DLE:
17966 @@ -2806,15 +2806,15 @@ static int ia_ioctl(struct atm_dev *dev,
17967 {
17968 struct k_sonet_stats *stats;
17969 stats = &PRIV(_ia_dev[board])->sonet_stats;
17970 - printk("section_bip: %d\n", atomic_read(&stats->section_bip));
17971 - printk("line_bip : %d\n", atomic_read(&stats->line_bip));
17972 - printk("path_bip : %d\n", atomic_read(&stats->path_bip));
17973 - printk("line_febe : %d\n", atomic_read(&stats->line_febe));
17974 - printk("path_febe : %d\n", atomic_read(&stats->path_febe));
17975 - printk("corr_hcs : %d\n", atomic_read(&stats->corr_hcs));
17976 - printk("uncorr_hcs : %d\n", atomic_read(&stats->uncorr_hcs));
17977 - printk("tx_cells : %d\n", atomic_read(&stats->tx_cells));
17978 - printk("rx_cells : %d\n", atomic_read(&stats->rx_cells));
17979 + printk("section_bip: %d\n", atomic_read_unchecked(&stats->section_bip));
17980 + printk("line_bip : %d\n", atomic_read_unchecked(&stats->line_bip));
17981 + printk("path_bip : %d\n", atomic_read_unchecked(&stats->path_bip));
17982 + printk("line_febe : %d\n", atomic_read_unchecked(&stats->line_febe));
17983 + printk("path_febe : %d\n", atomic_read_unchecked(&stats->path_febe));
17984 + printk("corr_hcs : %d\n", atomic_read_unchecked(&stats->corr_hcs));
17985 + printk("uncorr_hcs : %d\n", atomic_read_unchecked(&stats->uncorr_hcs));
17986 + printk("tx_cells : %d\n", atomic_read_unchecked(&stats->tx_cells));
17987 + printk("rx_cells : %d\n", atomic_read_unchecked(&stats->rx_cells));
17988 }
17989 ia_cmds.status = 0;
17990 break;
17991 @@ -2919,7 +2919,7 @@ static int ia_pkt_tx (struct atm_vcc *vc
17992 if ((desc == 0) || (desc > iadev->num_tx_desc))
17993 {
17994 IF_ERR(printk(DEV_LABEL "invalid desc for send: %d\n", desc);)
17995 - atomic_inc(&vcc->stats->tx);
17996 + atomic_inc_unchecked(&vcc->stats->tx);
17997 if (vcc->pop)
17998 vcc->pop(vcc, skb);
17999 else
18000 @@ -3024,14 +3024,14 @@ static int ia_pkt_tx (struct atm_vcc *vc
18001 ATM_DESC(skb) = vcc->vci;
18002 skb_queue_tail(&iadev->tx_dma_q, skb);
18003
18004 - atomic_inc(&vcc->stats->tx);
18005 + atomic_inc_unchecked(&vcc->stats->tx);
18006 iadev->tx_pkt_cnt++;
18007 /* Increment transaction counter */
18008 writel(2, iadev->dma+IPHASE5575_TX_COUNTER);
18009
18010 #if 0
18011 /* add flow control logic */
18012 - if (atomic_read(&vcc->stats->tx) % 20 == 0) {
18013 + if (atomic_read_unchecked(&vcc->stats->tx) % 20 == 0) {
18014 if (iavcc->vc_desc_cnt > 10) {
18015 vcc->tx_quota = vcc->tx_quota * 3 / 4;
18016 printk("Tx1: vcc->tx_quota = %d \n", (u32)vcc->tx_quota );
18017 diff -urNp linux-2.6.31.1/drivers/atm/lanai.c linux-2.6.31.1/drivers/atm/lanai.c
18018 --- linux-2.6.31.1/drivers/atm/lanai.c 2009-09-24 11:45:25.000000000 -0400
18019 +++ linux-2.6.31.1/drivers/atm/lanai.c 2009-10-01 20:12:42.000000000 -0400
18020 @@ -1305,7 +1305,7 @@ static void lanai_send_one_aal5(struct l
18021 vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);
18022 lanai_endtx(lanai, lvcc);
18023 lanai_free_skb(lvcc->tx.atmvcc, skb);
18024 - atomic_inc(&lvcc->tx.atmvcc->stats->tx);
18025 + atomic_inc_unchecked(&lvcc->tx.atmvcc->stats->tx);
18026 }
18027
18028 /* Try to fill the buffer - don't call unless there is backlog */
18029 @@ -1428,7 +1428,7 @@ static void vcc_rx_aal5(struct lanai_vcc
18030 ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
18031 __net_timestamp(skb);
18032 lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
18033 - atomic_inc(&lvcc->rx.atmvcc->stats->rx);
18034 + atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx);
18035 out:
18036 lvcc->rx.buf.ptr = end;
18037 cardvcc_write(lvcc, endptr, vcc_rxreadptr);
18038 @@ -1670,7 +1670,7 @@ static int handle_service(struct lanai_d
18039 DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 "
18040 "vcc %d\n", lanai->number, (unsigned int) s, vci);
18041 lanai->stats.service_rxnotaal5++;
18042 - atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
18043 + atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
18044 return 0;
18045 }
18046 if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) {
18047 @@ -1682,7 +1682,7 @@ static int handle_service(struct lanai_d
18048 int bytes;
18049 read_unlock(&vcc_sklist_lock);
18050 DPRINTK("got trashed rx pdu on vci %d\n", vci);
18051 - atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
18052 + atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
18053 lvcc->stats.x.aal5.service_trash++;
18054 bytes = (SERVICE_GET_END(s) * 16) -
18055 (((unsigned long) lvcc->rx.buf.ptr) -
18056 @@ -1694,7 +1694,7 @@ static int handle_service(struct lanai_d
18057 }
18058 if (s & SERVICE_STREAM) {
18059 read_unlock(&vcc_sklist_lock);
18060 - atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
18061 + atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
18062 lvcc->stats.x.aal5.service_stream++;
18063 printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream "
18064 "PDU on VCI %d!\n", lanai->number, vci);
18065 @@ -1702,7 +1702,7 @@ static int handle_service(struct lanai_d
18066 return 0;
18067 }
18068 DPRINTK("got rx crc error on vci %d\n", vci);
18069 - atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
18070 + atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
18071 lvcc->stats.x.aal5.service_rxcrc++;
18072 lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
18073 cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
18074 diff -urNp linux-2.6.31.1/drivers/atm/nicstar.c linux-2.6.31.1/drivers/atm/nicstar.c
18075 --- linux-2.6.31.1/drivers/atm/nicstar.c 2009-09-24 11:45:25.000000000 -0400
18076 +++ linux-2.6.31.1/drivers/atm/nicstar.c 2009-10-01 20:12:42.000000000 -0400
18077 @@ -1723,7 +1723,7 @@ static int ns_send(struct atm_vcc *vcc,
18078 if ((vc = (vc_map *) vcc->dev_data) == NULL)
18079 {
18080 printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n", card->index);
18081 - atomic_inc(&vcc->stats->tx_err);
18082 + atomic_inc_unchecked(&vcc->stats->tx_err);
18083 dev_kfree_skb_any(skb);
18084 return -EINVAL;
18085 }
18086 @@ -1731,7 +1731,7 @@ static int ns_send(struct atm_vcc *vcc,
18087 if (!vc->tx)
18088 {
18089 printk("nicstar%d: Trying to transmit on a non-tx VC.\n", card->index);
18090 - atomic_inc(&vcc->stats->tx_err);
18091 + atomic_inc_unchecked(&vcc->stats->tx_err);
18092 dev_kfree_skb_any(skb);
18093 return -EINVAL;
18094 }
18095 @@ -1739,7 +1739,7 @@ static int ns_send(struct atm_vcc *vcc,
18096 if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0)
18097 {
18098 printk("nicstar%d: Only AAL0 and AAL5 are supported.\n", card->index);
18099 - atomic_inc(&vcc->stats->tx_err);
18100 + atomic_inc_unchecked(&vcc->stats->tx_err);
18101 dev_kfree_skb_any(skb);
18102 return -EINVAL;
18103 }
18104 @@ -1747,7 +1747,7 @@ static int ns_send(struct atm_vcc *vcc,
18105 if (skb_shinfo(skb)->nr_frags != 0)
18106 {
18107 printk("nicstar%d: No scatter-gather yet.\n", card->index);
18108 - atomic_inc(&vcc->stats->tx_err);
18109 + atomic_inc_unchecked(&vcc->stats->tx_err);
18110 dev_kfree_skb_any(skb);
18111 return -EINVAL;
18112 }
18113 @@ -1792,11 +1792,11 @@ static int ns_send(struct atm_vcc *vcc,
18114
18115 if (push_scqe(card, vc, scq, &scqe, skb) != 0)
18116 {
18117 - atomic_inc(&vcc->stats->tx_err);
18118 + atomic_inc_unchecked(&vcc->stats->tx_err);
18119 dev_kfree_skb_any(skb);
18120 return -EIO;
18121 }
18122 - atomic_inc(&vcc->stats->tx);
18123 + atomic_inc_unchecked(&vcc->stats->tx);
18124
18125 return 0;
18126 }
18127 @@ -2111,14 +2111,14 @@ static void dequeue_rx(ns_dev *card, ns_
18128 {
18129 printk("nicstar%d: Can't allocate buffers for aal0.\n",
18130 card->index);
18131 - atomic_add(i,&vcc->stats->rx_drop);
18132 + atomic_add_unchecked(i,&vcc->stats->rx_drop);
18133 break;
18134 }
18135 if (!atm_charge(vcc, sb->truesize))
18136 {
18137 RXPRINTK("nicstar%d: atm_charge() dropped aal0 packets.\n",
18138 card->index);
18139 - atomic_add(i-1,&vcc->stats->rx_drop); /* already increased by 1 */
18140 + atomic_add_unchecked(i-1,&vcc->stats->rx_drop); /* already increased by 1 */
18141 dev_kfree_skb_any(sb);
18142 break;
18143 }
18144 @@ -2133,7 +2133,7 @@ static void dequeue_rx(ns_dev *card, ns_
18145 ATM_SKB(sb)->vcc = vcc;
18146 __net_timestamp(sb);
18147 vcc->push(vcc, sb);
18148 - atomic_inc(&vcc->stats->rx);
18149 + atomic_inc_unchecked(&vcc->stats->rx);
18150 cell += ATM_CELL_PAYLOAD;
18151 }
18152
18153 @@ -2152,7 +2152,7 @@ static void dequeue_rx(ns_dev *card, ns_
18154 if (iovb == NULL)
18155 {
18156 printk("nicstar%d: Out of iovec buffers.\n", card->index);
18157 - atomic_inc(&vcc->stats->rx_drop);
18158 + atomic_inc_unchecked(&vcc->stats->rx_drop);
18159 recycle_rx_buf(card, skb);
18160 return;
18161 }
18162 @@ -2182,7 +2182,7 @@ static void dequeue_rx(ns_dev *card, ns_
18163 else if (NS_SKB(iovb)->iovcnt >= NS_MAX_IOVECS)
18164 {
18165 printk("nicstar%d: received too big AAL5 SDU.\n", card->index);
18166 - atomic_inc(&vcc->stats->rx_err);
18167 + atomic_inc_unchecked(&vcc->stats->rx_err);
18168 recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, NS_MAX_IOVECS);
18169 NS_SKB(iovb)->iovcnt = 0;
18170 iovb->len = 0;
18171 @@ -2202,7 +2202,7 @@ static void dequeue_rx(ns_dev *card, ns_
18172 printk("nicstar%d: Expected a small buffer, and this is not one.\n",
18173 card->index);
18174 which_list(card, skb);
18175 - atomic_inc(&vcc->stats->rx_err);
18176 + atomic_inc_unchecked(&vcc->stats->rx_err);
18177 recycle_rx_buf(card, skb);
18178 vc->rx_iov = NULL;
18179 recycle_iov_buf(card, iovb);
18180 @@ -2216,7 +2216,7 @@ static void dequeue_rx(ns_dev *card, ns_
18181 printk("nicstar%d: Expected a large buffer, and this is not one.\n",
18182 card->index);
18183 which_list(card, skb);
18184 - atomic_inc(&vcc->stats->rx_err);
18185 + atomic_inc_unchecked(&vcc->stats->rx_err);
18186 recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data,
18187 NS_SKB(iovb)->iovcnt);
18188 vc->rx_iov = NULL;
18189 @@ -2240,7 +2240,7 @@ static void dequeue_rx(ns_dev *card, ns_
18190 printk(" - PDU size mismatch.\n");
18191 else
18192 printk(".\n");
18193 - atomic_inc(&vcc->stats->rx_err);
18194 + atomic_inc_unchecked(&vcc->stats->rx_err);
18195 recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data,
18196 NS_SKB(iovb)->iovcnt);
18197 vc->rx_iov = NULL;
18198 @@ -2256,7 +2256,7 @@ static void dequeue_rx(ns_dev *card, ns_
18199 if (!atm_charge(vcc, skb->truesize))
18200 {
18201 push_rxbufs(card, skb);
18202 - atomic_inc(&vcc->stats->rx_drop);
18203 + atomic_inc_unchecked(&vcc->stats->rx_drop);
18204 }
18205 else
18206 {
18207 @@ -2268,7 +2268,7 @@ static void dequeue_rx(ns_dev *card, ns_
18208 ATM_SKB(skb)->vcc = vcc;
18209 __net_timestamp(skb);
18210 vcc->push(vcc, skb);
18211 - atomic_inc(&vcc->stats->rx);
18212 + atomic_inc_unchecked(&vcc->stats->rx);
18213 }
18214 }
18215 else if (NS_SKB(iovb)->iovcnt == 2) /* One small plus one large buffer */
18216 @@ -2283,7 +2283,7 @@ static void dequeue_rx(ns_dev *card, ns_
18217 if (!atm_charge(vcc, sb->truesize))
18218 {
18219 push_rxbufs(card, sb);
18220 - atomic_inc(&vcc->stats->rx_drop);
18221 + atomic_inc_unchecked(&vcc->stats->rx_drop);
18222 }
18223 else
18224 {
18225 @@ -2295,7 +2295,7 @@ static void dequeue_rx(ns_dev *card, ns_
18226 ATM_SKB(sb)->vcc = vcc;
18227 __net_timestamp(sb);
18228 vcc->push(vcc, sb);
18229 - atomic_inc(&vcc->stats->rx);
18230 + atomic_inc_unchecked(&vcc->stats->rx);
18231 }
18232
18233 push_rxbufs(card, skb);
18234 @@ -2306,7 +2306,7 @@ static void dequeue_rx(ns_dev *card, ns_
18235 if (!atm_charge(vcc, skb->truesize))
18236 {
18237 push_rxbufs(card, skb);
18238 - atomic_inc(&vcc->stats->rx_drop);
18239 + atomic_inc_unchecked(&vcc->stats->rx_drop);
18240 }
18241 else
18242 {
18243 @@ -2320,7 +2320,7 @@ static void dequeue_rx(ns_dev *card, ns_
18244 ATM_SKB(skb)->vcc = vcc;
18245 __net_timestamp(skb);
18246 vcc->push(vcc, skb);
18247 - atomic_inc(&vcc->stats->rx);
18248 + atomic_inc_unchecked(&vcc->stats->rx);
18249 }
18250
18251 push_rxbufs(card, sb);
18252 @@ -2342,7 +2342,7 @@ static void dequeue_rx(ns_dev *card, ns_
18253 if (hb == NULL)
18254 {
18255 printk("nicstar%d: Out of huge buffers.\n", card->index);
18256 - atomic_inc(&vcc->stats->rx_drop);
18257 + atomic_inc_unchecked(&vcc->stats->rx_drop);
18258 recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data,
18259 NS_SKB(iovb)->iovcnt);
18260 vc->rx_iov = NULL;
18261 @@ -2393,7 +2393,7 @@ static void dequeue_rx(ns_dev *card, ns_
18262 }
18263 else
18264 dev_kfree_skb_any(hb);
18265 - atomic_inc(&vcc->stats->rx_drop);
18266 + atomic_inc_unchecked(&vcc->stats->rx_drop);
18267 }
18268 else
18269 {
18270 @@ -2427,7 +2427,7 @@ static void dequeue_rx(ns_dev *card, ns_
18271 #endif /* NS_USE_DESTRUCTORS */
18272 __net_timestamp(hb);
18273 vcc->push(vcc, hb);
18274 - atomic_inc(&vcc->stats->rx);
18275 + atomic_inc_unchecked(&vcc->stats->rx);
18276 }
18277 }
18278
18279 diff -urNp linux-2.6.31.1/drivers/atm/solos-pci.c linux-2.6.31.1/drivers/atm/solos-pci.c
18280 --- linux-2.6.31.1/drivers/atm/solos-pci.c 2009-09-24 11:45:25.000000000 -0400
18281 +++ linux-2.6.31.1/drivers/atm/solos-pci.c 2009-10-01 20:12:42.000000000 -0400
18282 @@ -663,7 +663,7 @@ void solos_bh(unsigned long card_arg)
18283 }
18284 atm_charge(vcc, skb->truesize);
18285 vcc->push(vcc, skb);
18286 - atomic_inc(&vcc->stats->rx);
18287 + atomic_inc_unchecked(&vcc->stats->rx);
18288 break;
18289
18290 case PKT_STATUS:
18291 @@ -966,7 +966,7 @@ static uint32_t fpga_tx(struct solos_car
18292 vcc = SKB_CB(oldskb)->vcc;
18293
18294 if (vcc) {
18295 - atomic_inc(&vcc->stats->tx);
18296 + atomic_inc_unchecked(&vcc->stats->tx);
18297 solos_pop(vcc, oldskb);
18298 } else
18299 dev_kfree_skb_irq(oldskb);
18300 diff -urNp linux-2.6.31.1/drivers/atm/suni.c linux-2.6.31.1/drivers/atm/suni.c
18301 --- linux-2.6.31.1/drivers/atm/suni.c 2009-09-24 11:45:25.000000000 -0400
18302 +++ linux-2.6.31.1/drivers/atm/suni.c 2009-10-01 20:12:42.000000000 -0400
18303 @@ -49,8 +49,8 @@ static DEFINE_SPINLOCK(sunis_lock);
18304
18305
18306 #define ADD_LIMITED(s,v) \
18307 - atomic_add((v),&stats->s); \
18308 - if (atomic_read(&stats->s) < 0) atomic_set(&stats->s,INT_MAX);
18309 + atomic_add_unchecked((v),&stats->s); \
18310 + if (atomic_read_unchecked(&stats->s) < 0) atomic_set_unchecked(&stats->s,INT_MAX);
18311
18312
18313 static void suni_hz(unsigned long from_timer)
18314 diff -urNp linux-2.6.31.1/drivers/atm/uPD98402.c linux-2.6.31.1/drivers/atm/uPD98402.c
18315 --- linux-2.6.31.1/drivers/atm/uPD98402.c 2009-09-24 11:45:25.000000000 -0400
18316 +++ linux-2.6.31.1/drivers/atm/uPD98402.c 2009-10-01 20:12:42.000000000 -0400
18317 @@ -41,7 +41,7 @@ static int fetch_stats(struct atm_dev *d
18318 struct sonet_stats tmp;
18319 int error = 0;
18320
18321 - atomic_add(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
18322 + atomic_add_unchecked(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
18323 sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp);
18324 if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
18325 if (zero && !error) {
18326 @@ -160,9 +160,9 @@ static int uPD98402_ioctl(struct atm_dev
18327
18328
18329 #define ADD_LIMITED(s,v) \
18330 - { atomic_add(GET(v),&PRIV(dev)->sonet_stats.s); \
18331 - if (atomic_read(&PRIV(dev)->sonet_stats.s) < 0) \
18332 - atomic_set(&PRIV(dev)->sonet_stats.s,INT_MAX); }
18333 + { atomic_add_unchecked(GET(v),&PRIV(dev)->sonet_stats.s); \
18334 + if (atomic_read_unchecked(&PRIV(dev)->sonet_stats.s) < 0) \
18335 + atomic_set_unchecked(&PRIV(dev)->sonet_stats.s,INT_MAX); }
18336
18337
18338 static void stat_event(struct atm_dev *dev)
18339 @@ -193,7 +193,7 @@ static void uPD98402_int(struct atm_dev
18340 if (reason & uPD98402_INT_PFM) stat_event(dev);
18341 if (reason & uPD98402_INT_PCO) {
18342 (void) GET(PCOCR); /* clear interrupt cause */
18343 - atomic_add(GET(HECCT),
18344 + atomic_add_unchecked(GET(HECCT),
18345 &PRIV(dev)->sonet_stats.uncorr_hcs);
18346 }
18347 if ((reason & uPD98402_INT_RFO) &&
18348 @@ -221,9 +221,9 @@ static int uPD98402_start(struct atm_dev
18349 PUT(~(uPD98402_INT_PFM | uPD98402_INT_ALM | uPD98402_INT_RFO |
18350 uPD98402_INT_LOS),PIMR); /* enable them */
18351 (void) fetch_stats(dev,NULL,1); /* clear kernel counters */
18352 - atomic_set(&PRIV(dev)->sonet_stats.corr_hcs,-1);
18353 - atomic_set(&PRIV(dev)->sonet_stats.tx_cells,-1);
18354 - atomic_set(&PRIV(dev)->sonet_stats.rx_cells,-1);
18355 + atomic_set_unchecked(&PRIV(dev)->sonet_stats.corr_hcs,-1);
18356 + atomic_set_unchecked(&PRIV(dev)->sonet_stats.tx_cells,-1);
18357 + atomic_set_unchecked(&PRIV(dev)->sonet_stats.rx_cells,-1);
18358 return 0;
18359 }
18360
18361 diff -urNp linux-2.6.31.1/drivers/atm/zatm.c linux-2.6.31.1/drivers/atm/zatm.c
18362 --- linux-2.6.31.1/drivers/atm/zatm.c 2009-09-24 11:45:25.000000000 -0400
18363 +++ linux-2.6.31.1/drivers/atm/zatm.c 2009-10-01 20:12:42.000000000 -0400
18364 @@ -458,7 +458,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
18365 }
18366 if (!size) {
18367 dev_kfree_skb_irq(skb);
18368 - if (vcc) atomic_inc(&vcc->stats->rx_err);
18369 + if (vcc) atomic_inc_unchecked(&vcc->stats->rx_err);
18370 continue;
18371 }
18372 if (!atm_charge(vcc,skb->truesize)) {
18373 @@ -468,7 +468,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
18374 skb->len = size;
18375 ATM_SKB(skb)->vcc = vcc;
18376 vcc->push(vcc,skb);
18377 - atomic_inc(&vcc->stats->rx);
18378 + atomic_inc_unchecked(&vcc->stats->rx);
18379 }
18380 zout(pos & 0xffff,MTA(mbx));
18381 #if 0 /* probably a stupid idea */
18382 @@ -732,7 +732,7 @@ if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD
18383 skb_queue_head(&zatm_vcc->backlog,skb);
18384 break;
18385 }
18386 - atomic_inc(&vcc->stats->tx);
18387 + atomic_inc_unchecked(&vcc->stats->tx);
18388 wake_up(&zatm_vcc->tx_wait);
18389 }
18390
18391 diff -urNp linux-2.6.31.1/drivers/block/cciss.c linux-2.6.31.1/drivers/block/cciss.c
18392 --- linux-2.6.31.1/drivers/block/cciss.c 2009-09-24 11:45:25.000000000 -0400
18393 +++ linux-2.6.31.1/drivers/block/cciss.c 2009-10-01 20:12:42.000000000 -0400
18394 @@ -363,7 +363,7 @@ static void cciss_seq_stop(struct seq_fi
18395 h->busy_configuring = 0;
18396 }
18397
18398 -static struct seq_operations cciss_seq_ops = {
18399 +static const struct seq_operations cciss_seq_ops = {
18400 .start = cciss_seq_start,
18401 .show = cciss_seq_show,
18402 .next = cciss_seq_next,
18403 @@ -426,7 +426,7 @@ out:
18404 return err;
18405 }
18406
18407 -static struct file_operations cciss_proc_fops = {
18408 +static const struct file_operations cciss_proc_fops = {
18409 .owner = THIS_MODULE,
18410 .open = cciss_seq_open,
18411 .read = seq_read,
18412 diff -urNp linux-2.6.31.1/drivers/char/agp/agp.h linux-2.6.31.1/drivers/char/agp/agp.h
18413 --- linux-2.6.31.1/drivers/char/agp/agp.h 2009-09-24 11:45:25.000000000 -0400
18414 +++ linux-2.6.31.1/drivers/char/agp/agp.h 2009-10-01 20:12:42.000000000 -0400
18415 @@ -126,7 +126,7 @@ struct agp_bridge_driver {
18416 struct agp_bridge_data {
18417 const struct agp_version *version;
18418 const struct agp_bridge_driver *driver;
18419 - struct vm_operations_struct *vm_ops;
18420 + const struct vm_operations_struct *vm_ops;
18421 void *previous_size;
18422 void *current_size;
18423 void *dev_private_data;
18424 diff -urNp linux-2.6.31.1/drivers/char/agp/alpha-agp.c linux-2.6.31.1/drivers/char/agp/alpha-agp.c
18425 --- linux-2.6.31.1/drivers/char/agp/alpha-agp.c 2009-09-24 11:45:25.000000000 -0400
18426 +++ linux-2.6.31.1/drivers/char/agp/alpha-agp.c 2009-10-01 20:12:42.000000000 -0400
18427 @@ -40,7 +40,7 @@ static struct aper_size_info_fixed alpha
18428 { 0, 0, 0 }, /* filled in by alpha_core_agp_setup */
18429 };
18430
18431 -struct vm_operations_struct alpha_core_agp_vm_ops = {
18432 +const struct vm_operations_struct alpha_core_agp_vm_ops = {
18433 .fault = alpha_core_agp_vm_fault,
18434 };
18435
18436 diff -urNp linux-2.6.31.1/drivers/char/agp/frontend.c linux-2.6.31.1/drivers/char/agp/frontend.c
18437 --- linux-2.6.31.1/drivers/char/agp/frontend.c 2009-09-24 11:45:25.000000000 -0400
18438 +++ linux-2.6.31.1/drivers/char/agp/frontend.c 2009-10-01 20:12:42.000000000 -0400
18439 @@ -824,7 +824,7 @@ static int agpioc_reserve_wrap(struct ag
18440 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
18441 return -EFAULT;
18442
18443 - if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
18444 + if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
18445 return -EFAULT;
18446
18447 client = agp_find_client_by_pid(reserve.pid);
18448 diff -urNp linux-2.6.31.1/drivers/char/agp/intel-agp.c linux-2.6.31.1/drivers/char/agp/intel-agp.c
18449 --- linux-2.6.31.1/drivers/char/agp/intel-agp.c 2009-09-24 11:45:25.000000000 -0400
18450 +++ linux-2.6.31.1/drivers/char/agp/intel-agp.c 2009-10-01 20:12:42.000000000 -0400
18451 @@ -2395,7 +2395,7 @@ static struct pci_device_id agp_intel_pc
18452 ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
18453 ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
18454 ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
18455 - { }
18456 + { 0, 0, 0, 0, 0, 0, 0 }
18457 };
18458
18459 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
18460 diff -urNp linux-2.6.31.1/drivers/char/apm-emulation.c linux-2.6.31.1/drivers/char/apm-emulation.c
18461 --- linux-2.6.31.1/drivers/char/apm-emulation.c 2009-09-24 11:45:25.000000000 -0400
18462 +++ linux-2.6.31.1/drivers/char/apm-emulation.c 2009-10-01 20:12:42.000000000 -0400
18463 @@ -393,7 +393,7 @@ static int apm_open(struct inode * inode
18464 return as ? 0 : -ENOMEM;
18465 }
18466
18467 -static struct file_operations apm_bios_fops = {
18468 +static const struct file_operations apm_bios_fops = {
18469 .owner = THIS_MODULE,
18470 .read = apm_read,
18471 .poll = apm_poll,
18472 diff -urNp linux-2.6.31.1/drivers/char/bfin-otp.c linux-2.6.31.1/drivers/char/bfin-otp.c
18473 --- linux-2.6.31.1/drivers/char/bfin-otp.c 2009-09-24 11:45:25.000000000 -0400
18474 +++ linux-2.6.31.1/drivers/char/bfin-otp.c 2009-10-01 20:12:42.000000000 -0400
18475 @@ -133,7 +133,7 @@ static ssize_t bfin_otp_write(struct fil
18476 # define bfin_otp_write NULL
18477 #endif
18478
18479 -static struct file_operations bfin_otp_fops = {
18480 +static const struct file_operations bfin_otp_fops = {
18481 .owner = THIS_MODULE,
18482 .read = bfin_otp_read,
18483 .write = bfin_otp_write,
18484 diff -urNp linux-2.6.31.1/drivers/char/hpet.c linux-2.6.31.1/drivers/char/hpet.c
18485 --- linux-2.6.31.1/drivers/char/hpet.c 2009-09-24 11:45:25.000000000 -0400
18486 +++ linux-2.6.31.1/drivers/char/hpet.c 2009-10-01 20:12:42.000000000 -0400
18487 @@ -995,7 +995,7 @@ static struct acpi_driver hpet_acpi_driv
18488 },
18489 };
18490
18491 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
18492 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
18493
18494 static int __init hpet_init(void)
18495 {
18496 diff -urNp linux-2.6.31.1/drivers/char/hvcs.c linux-2.6.31.1/drivers/char/hvcs.c
18497 --- linux-2.6.31.1/drivers/char/hvcs.c 2009-09-24 11:45:25.000000000 -0400
18498 +++ linux-2.6.31.1/drivers/char/hvcs.c 2009-10-01 20:12:42.000000000 -0400
18499 @@ -269,7 +269,7 @@ struct hvcs_struct {
18500 unsigned int index;
18501
18502 struct tty_struct *tty;
18503 - int open_count;
18504 + atomic_t open_count;
18505
18506 /*
18507 * Used to tell the driver kernel_thread what operations need to take
18508 @@ -419,7 +419,7 @@ static ssize_t hvcs_vterm_state_store(st
18509
18510 spin_lock_irqsave(&hvcsd->lock, flags);
18511
18512 - if (hvcsd->open_count > 0) {
18513 + if (atomic_read(&hvcsd->open_count) > 0) {
18514 spin_unlock_irqrestore(&hvcsd->lock, flags);
18515 printk(KERN_INFO "HVCS: vterm state unchanged. "
18516 "The hvcs device node is still in use.\n");
18517 @@ -1135,7 +1135,7 @@ static int hvcs_open(struct tty_struct *
18518 if ((retval = hvcs_partner_connect(hvcsd)))
18519 goto error_release;
18520
18521 - hvcsd->open_count = 1;
18522 + atomic_set(&hvcsd->open_count, 1);
18523 hvcsd->tty = tty;
18524 tty->driver_data = hvcsd;
18525
18526 @@ -1169,7 +1169,7 @@ fast_open:
18527
18528 spin_lock_irqsave(&hvcsd->lock, flags);
18529 kref_get(&hvcsd->kref);
18530 - hvcsd->open_count++;
18531 + atomic_inc(&hvcsd->open_count);
18532 hvcsd->todo_mask |= HVCS_SCHED_READ;
18533 spin_unlock_irqrestore(&hvcsd->lock, flags);
18534
18535 @@ -1213,7 +1213,7 @@ static void hvcs_close(struct tty_struct
18536 hvcsd = tty->driver_data;
18537
18538 spin_lock_irqsave(&hvcsd->lock, flags);
18539 - if (--hvcsd->open_count == 0) {
18540 + if (atomic_dec_and_test(&hvcsd->open_count)) {
18541
18542 vio_disable_interrupts(hvcsd->vdev);
18543
18544 @@ -1239,10 +1239,10 @@ static void hvcs_close(struct tty_struct
18545 free_irq(irq, hvcsd);
18546 kref_put(&hvcsd->kref, destroy_hvcs_struct);
18547 return;
18548 - } else if (hvcsd->open_count < 0) {
18549 + } else if (atomic_read(&hvcsd->open_count) < 0) {
18550 printk(KERN_ERR "HVCS: vty-server@%X open_count: %d"
18551 " is missmanaged.\n",
18552 - hvcsd->vdev->unit_address, hvcsd->open_count);
18553 + hvcsd->vdev->unit_address, atomic_read(&hvcsd->open_count));
18554 }
18555
18556 spin_unlock_irqrestore(&hvcsd->lock, flags);
18557 @@ -1258,7 +1258,7 @@ static void hvcs_hangup(struct tty_struc
18558
18559 spin_lock_irqsave(&hvcsd->lock, flags);
18560 /* Preserve this so that we know how many kref refs to put */
18561 - temp_open_count = hvcsd->open_count;
18562 + temp_open_count = atomic_read(&hvcsd->open_count);
18563
18564 /*
18565 * Don't kref put inside the spinlock because the destruction
18566 @@ -1273,7 +1273,7 @@ static void hvcs_hangup(struct tty_struc
18567 hvcsd->tty->driver_data = NULL;
18568 hvcsd->tty = NULL;
18569
18570 - hvcsd->open_count = 0;
18571 + atomic_set(&hvcsd->open_count, 0);
18572
18573 /* This will drop any buffered data on the floor which is OK in a hangup
18574 * scenario. */
18575 @@ -1344,7 +1344,7 @@ static int hvcs_write(struct tty_struct
18576 * the middle of a write operation? This is a crummy place to do this
18577 * but we want to keep it all in the spinlock.
18578 */
18579 - if (hvcsd->open_count <= 0) {
18580 + if (atomic_read(&hvcsd->open_count) <= 0) {
18581 spin_unlock_irqrestore(&hvcsd->lock, flags);
18582 return -ENODEV;
18583 }
18584 @@ -1418,7 +1418,7 @@ static int hvcs_write_room(struct tty_st
18585 {
18586 struct hvcs_struct *hvcsd = tty->driver_data;
18587
18588 - if (!hvcsd || hvcsd->open_count <= 0)
18589 + if (!hvcsd || atomic_read(&hvcsd->open_count) <= 0)
18590 return 0;
18591
18592 return HVCS_BUFF_LEN - hvcsd->chars_in_buffer;
18593 diff -urNp linux-2.6.31.1/drivers/char/ipmi/ipmi_msghandler.c linux-2.6.31.1/drivers/char/ipmi/ipmi_msghandler.c
18594 --- linux-2.6.31.1/drivers/char/ipmi/ipmi_msghandler.c 2009-09-24 11:45:25.000000000 -0400
18595 +++ linux-2.6.31.1/drivers/char/ipmi/ipmi_msghandler.c 2009-10-01 20:12:42.000000000 -0400
18596 @@ -413,7 +413,7 @@ struct ipmi_smi {
18597 struct proc_dir_entry *proc_dir;
18598 char proc_dir_name[10];
18599
18600 - atomic_t stats[IPMI_NUM_STATS];
18601 + atomic_unchecked_t stats[IPMI_NUM_STATS];
18602
18603 /*
18604 * run_to_completion duplicate of smb_info, smi_info
18605 @@ -446,9 +446,9 @@ static DEFINE_MUTEX(smi_watchers_mutex);
18606
18607
18608 #define ipmi_inc_stat(intf, stat) \
18609 - atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
18610 + atomic_inc_unchecked(&(intf)->stats[IPMI_STAT_ ## stat])
18611 #define ipmi_get_stat(intf, stat) \
18612 - ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
18613 + ((unsigned int) atomic_read_unchecked(&(intf)->stats[IPMI_STAT_ ## stat]))
18614
18615 static int is_lan_addr(struct ipmi_addr *addr)
18616 {
18617 @@ -2807,7 +2807,7 @@ int ipmi_register_smi(struct ipmi_smi_ha
18618 INIT_LIST_HEAD(&intf->cmd_rcvrs);
18619 init_waitqueue_head(&intf->waitq);
18620 for (i = 0; i < IPMI_NUM_STATS; i++)
18621 - atomic_set(&intf->stats[i], 0);
18622 + atomic_set_unchecked(&intf->stats[i], 0);
18623
18624 intf->proc_dir = NULL;
18625
18626 diff -urNp linux-2.6.31.1/drivers/char/ipmi/ipmi_si_intf.c linux-2.6.31.1/drivers/char/ipmi/ipmi_si_intf.c
18627 --- linux-2.6.31.1/drivers/char/ipmi/ipmi_si_intf.c 2009-09-24 11:45:25.000000000 -0400
18628 +++ linux-2.6.31.1/drivers/char/ipmi/ipmi_si_intf.c 2009-10-01 20:12:42.000000000 -0400
18629 @@ -277,7 +277,7 @@ struct smi_info {
18630 unsigned char slave_addr;
18631
18632 /* Counters and things for the proc filesystem. */
18633 - atomic_t stats[SI_NUM_STATS];
18634 + atomic_unchecked_t stats[SI_NUM_STATS];
18635
18636 struct task_struct *thread;
18637
18638 @@ -285,9 +285,9 @@ struct smi_info {
18639 };
18640
18641 #define smi_inc_stat(smi, stat) \
18642 - atomic_inc(&(smi)->stats[SI_STAT_ ## stat])
18643 + atomic_inc_unchecked(&(smi)->stats[SI_STAT_ ## stat])
18644 #define smi_get_stat(smi, stat) \
18645 - ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_ ## stat]))
18646 + ((unsigned int) atomic_read_unchecked(&(smi)->stats[SI_STAT_ ## stat]))
18647
18648 #define SI_MAX_PARMS 4
18649
18650 @@ -2926,7 +2926,7 @@ static int try_smi_init(struct smi_info
18651 atomic_set(&new_smi->req_events, 0);
18652 new_smi->run_to_completion = 0;
18653 for (i = 0; i < SI_NUM_STATS; i++)
18654 - atomic_set(&new_smi->stats[i], 0);
18655 + atomic_set_unchecked(&new_smi->stats[i], 0);
18656
18657 new_smi->interrupt_disabled = 0;
18658 atomic_set(&new_smi->stop_operation, 0);
18659 diff -urNp linux-2.6.31.1/drivers/char/keyboard.c linux-2.6.31.1/drivers/char/keyboard.c
18660 --- linux-2.6.31.1/drivers/char/keyboard.c 2009-09-24 11:45:25.000000000 -0400
18661 +++ linux-2.6.31.1/drivers/char/keyboard.c 2009-10-01 20:12:42.000000000 -0400
18662 @@ -635,6 +635,16 @@ static void k_spec(struct vc_data *vc, u
18663 kbd->kbdmode == VC_MEDIUMRAW) &&
18664 value != KVAL(K_SAK))
18665 return; /* SAK is allowed even in raw mode */
18666 +
18667 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
18668 + {
18669 + void *func = fn_handler[value];
18670 + if (func == fn_show_state || func == fn_show_ptregs ||
18671 + func == fn_show_mem)
18672 + return;
18673 + }
18674 +#endif
18675 +
18676 fn_handler[value](vc);
18677 }
18678
18679 @@ -1386,7 +1396,7 @@ static const struct input_device_id kbd_
18680 .evbit = { BIT_MASK(EV_SND) },
18681 },
18682
18683 - { }, /* Terminating entry */
18684 + { 0 }, /* Terminating entry */
18685 };
18686
18687 MODULE_DEVICE_TABLE(input, kbd_ids);
18688 diff -urNp linux-2.6.31.1/drivers/char/mem.c linux-2.6.31.1/drivers/char/mem.c
18689 --- linux-2.6.31.1/drivers/char/mem.c 2009-09-24 11:45:25.000000000 -0400
18690 +++ linux-2.6.31.1/drivers/char/mem.c 2009-10-01 20:12:42.000000000 -0400
18691 @@ -18,6 +18,7 @@
18692 #include <linux/raw.h>
18693 #include <linux/tty.h>
18694 #include <linux/capability.h>
18695 +#include <linux/security.h>
18696 #include <linux/ptrace.h>
18697 #include <linux/device.h>
18698 #include <linux/highmem.h>
18699 @@ -35,6 +36,10 @@
18700 # include <linux/efi.h>
18701 #endif
18702
18703 +#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
18704 +extern struct file_operations grsec_fops;
18705 +#endif
18706 +
18707 /*
18708 * Architectures vary in how they handle caching for addresses
18709 * outside of main memory.
18710 @@ -192,6 +197,11 @@ static ssize_t write_mem(struct file * f
18711 if (!valid_phys_addr_range(p, count))
18712 return -EFAULT;
18713
18714 +#ifdef CONFIG_GRKERNSEC_KMEM
18715 + gr_handle_mem_write();
18716 + return -EPERM;
18717 +#endif
18718 +
18719 written = 0;
18720
18721 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
18722 @@ -301,7 +311,7 @@ static inline int private_mapping_ok(str
18723 }
18724 #endif
18725
18726 -static struct vm_operations_struct mmap_mem_ops = {
18727 +static const struct vm_operations_struct mmap_mem_ops = {
18728 #ifdef CONFIG_HAVE_IOREMAP_PROT
18729 .access = generic_access_phys
18730 #endif
18731 @@ -324,6 +334,11 @@ static int mmap_mem(struct file * file,
18732 &vma->vm_page_prot))
18733 return -EINVAL;
18734
18735 +#ifdef CONFIG_GRKERNSEC_KMEM
18736 + if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
18737 + return -EPERM;
18738 +#endif
18739 +
18740 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
18741 size,
18742 vma->vm_page_prot);
18743 @@ -558,6 +573,11 @@ static ssize_t write_kmem(struct file *
18744 ssize_t written;
18745 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
18746
18747 +#ifdef CONFIG_GRKERNSEC_KMEM
18748 + gr_handle_kmem_write();
18749 + return -EPERM;
18750 +#endif
18751 +
18752 if (p < (unsigned long) high_memory) {
18753
18754 wrote = count;
18755 @@ -763,6 +783,16 @@ static loff_t memory_lseek(struct file *
18756
18757 static int open_port(struct inode * inode, struct file * filp)
18758 {
18759 +#ifdef CONFIG_GRKERNSEC_KMEM
18760 + gr_handle_open_port();
18761 + return -EPERM;
18762 +#endif
18763 +
18764 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
18765 +}
18766 +
18767 +static int open_mem(struct inode * inode, struct file * filp)
18768 +{
18769 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
18770 }
18771
18772 @@ -770,7 +800,6 @@ static int open_port(struct inode * inod
18773 #define full_lseek null_lseek
18774 #define write_zero write_null
18775 #define read_full read_zero
18776 -#define open_mem open_port
18777 #define open_kmem open_mem
18778 #define open_oldmem open_mem
18779
18780 @@ -888,6 +917,9 @@ static const struct {
18781 #ifdef CONFIG_CRASH_DUMP
18782 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops, NULL},
18783 #endif
18784 +#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
18785 + {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
18786 +#endif
18787 };
18788
18789 static int memory_open(struct inode *inode, struct file *filp)
18790 diff -urNp linux-2.6.31.1/drivers/char/misc.c linux-2.6.31.1/drivers/char/misc.c
18791 --- linux-2.6.31.1/drivers/char/misc.c 2009-09-24 11:45:25.000000000 -0400
18792 +++ linux-2.6.31.1/drivers/char/misc.c 2009-10-01 20:12:42.000000000 -0400
18793 @@ -91,7 +91,7 @@ static int misc_seq_show(struct seq_file
18794 }
18795
18796
18797 -static struct seq_operations misc_seq_ops = {
18798 +static const struct seq_operations misc_seq_ops = {
18799 .start = misc_seq_start,
18800 .next = misc_seq_next,
18801 .stop = misc_seq_stop,
18802 diff -urNp linux-2.6.31.1/drivers/char/mspec.c linux-2.6.31.1/drivers/char/mspec.c
18803 --- linux-2.6.31.1/drivers/char/mspec.c 2009-09-24 11:45:25.000000000 -0400
18804 +++ linux-2.6.31.1/drivers/char/mspec.c 2009-10-01 20:12:43.000000000 -0400
18805 @@ -239,7 +239,7 @@ mspec_fault(struct vm_area_struct *vma,
18806 return VM_FAULT_NOPAGE;
18807 }
18808
18809 -static struct vm_operations_struct mspec_vm_ops = {
18810 +static const struct vm_operations_struct mspec_vm_ops = {
18811 .open = mspec_open,
18812 .close = mspec_close,
18813 .fault = mspec_fault,
18814 diff -urNp linux-2.6.31.1/drivers/char/nvram.c linux-2.6.31.1/drivers/char/nvram.c
18815 --- linux-2.6.31.1/drivers/char/nvram.c 2009-09-24 11:45:25.000000000 -0400
18816 +++ linux-2.6.31.1/drivers/char/nvram.c 2009-10-01 20:12:43.000000000 -0400
18817 @@ -429,7 +429,10 @@ static const struct file_operations nvra
18818 static struct miscdevice nvram_dev = {
18819 NVRAM_MINOR,
18820 "nvram",
18821 - &nvram_fops
18822 + &nvram_fops,
18823 + {NULL, NULL},
18824 + NULL,
18825 + NULL
18826 };
18827
18828 static int __init nvram_init(void)
18829 diff -urNp linux-2.6.31.1/drivers/char/pcmcia/ipwireless/tty.c linux-2.6.31.1/drivers/char/pcmcia/ipwireless/tty.c
18830 --- linux-2.6.31.1/drivers/char/pcmcia/ipwireless/tty.c 2009-09-24 11:45:25.000000000 -0400
18831 +++ linux-2.6.31.1/drivers/char/pcmcia/ipwireless/tty.c 2009-10-01 20:12:43.000000000 -0400
18832 @@ -51,7 +51,7 @@ struct ipw_tty {
18833 int tty_type;
18834 struct ipw_network *network;
18835 struct tty_struct *linux_tty;
18836 - int open_count;
18837 + atomic_t open_count;
18838 unsigned int control_lines;
18839 struct mutex ipw_tty_mutex;
18840 int tx_bytes_queued;
18841 @@ -127,10 +127,10 @@ static int ipw_open(struct tty_struct *l
18842 mutex_unlock(&tty->ipw_tty_mutex);
18843 return -ENODEV;
18844 }
18845 - if (tty->open_count == 0)
18846 + if (atomic_read(&tty->open_count) == 0)
18847 tty->tx_bytes_queued = 0;
18848
18849 - tty->open_count++;
18850 + atomic_inc(&tty->open_count);
18851
18852 tty->linux_tty = linux_tty;
18853 linux_tty->driver_data = tty;
18854 @@ -146,9 +146,7 @@ static int ipw_open(struct tty_struct *l
18855
18856 static void do_ipw_close(struct ipw_tty *tty)
18857 {
18858 - tty->open_count--;
18859 -
18860 - if (tty->open_count == 0) {
18861 + if (atomic_dec_return(&tty->open_count) == 0) {
18862 struct tty_struct *linux_tty = tty->linux_tty;
18863
18864 if (linux_tty != NULL) {
18865 @@ -169,7 +167,7 @@ static void ipw_hangup(struct tty_struct
18866 return;
18867
18868 mutex_lock(&tty->ipw_tty_mutex);
18869 - if (tty->open_count == 0) {
18870 + if (atomic_read(&tty->open_count) == 0) {
18871 mutex_unlock(&tty->ipw_tty_mutex);
18872 return;
18873 }
18874 @@ -198,7 +196,7 @@ void ipwireless_tty_received(struct ipw_
18875 return;
18876 }
18877
18878 - if (!tty->open_count) {
18879 + if (!atomic_read(&tty->open_count)) {
18880 mutex_unlock(&tty->ipw_tty_mutex);
18881 return;
18882 }
18883 @@ -240,7 +238,7 @@ static int ipw_write(struct tty_struct *
18884 return -ENODEV;
18885
18886 mutex_lock(&tty->ipw_tty_mutex);
18887 - if (!tty->open_count) {
18888 + if (!atomic_read(&tty->open_count)) {
18889 mutex_unlock(&tty->ipw_tty_mutex);
18890 return -EINVAL;
18891 }
18892 @@ -280,7 +278,7 @@ static int ipw_write_room(struct tty_str
18893 if (!tty)
18894 return -ENODEV;
18895
18896 - if (!tty->open_count)
18897 + if (!atomic_read(&tty->open_count))
18898 return -EINVAL;
18899
18900 room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued;
18901 @@ -322,7 +320,7 @@ static int ipw_chars_in_buffer(struct tt
18902 if (!tty)
18903 return 0;
18904
18905 - if (!tty->open_count)
18906 + if (!atomic_read(&tty->open_count))
18907 return 0;
18908
18909 return tty->tx_bytes_queued;
18910 @@ -403,7 +401,7 @@ static int ipw_tiocmget(struct tty_struc
18911 if (!tty)
18912 return -ENODEV;
18913
18914 - if (!tty->open_count)
18915 + if (!atomic_read(&tty->open_count))
18916 return -EINVAL;
18917
18918 return get_control_lines(tty);
18919 @@ -419,7 +417,7 @@ ipw_tiocmset(struct tty_struct *linux_tt
18920 if (!tty)
18921 return -ENODEV;
18922
18923 - if (!tty->open_count)
18924 + if (!atomic_read(&tty->open_count))
18925 return -EINVAL;
18926
18927 return set_control_lines(tty, set, clear);
18928 @@ -433,7 +431,7 @@ static int ipw_ioctl(struct tty_struct *
18929 if (!tty)
18930 return -ENODEV;
18931
18932 - if (!tty->open_count)
18933 + if (!atomic_read(&tty->open_count))
18934 return -EINVAL;
18935
18936 /* FIXME: Exactly how is the tty object locked here .. */
18937 @@ -591,7 +589,7 @@ void ipwireless_tty_free(struct ipw_tty
18938 against a parallel ioctl etc */
18939 mutex_lock(&ttyj->ipw_tty_mutex);
18940 }
18941 - while (ttyj->open_count)
18942 + while (atomic_read(&ttyj->open_count))
18943 do_ipw_close(ttyj);
18944 ipwireless_disassociate_network_ttys(network,
18945 ttyj->channel_idx);
18946 diff -urNp linux-2.6.31.1/drivers/char/random.c linux-2.6.31.1/drivers/char/random.c
18947 --- linux-2.6.31.1/drivers/char/random.c 2009-09-24 11:45:25.000000000 -0400
18948 +++ linux-2.6.31.1/drivers/char/random.c 2009-10-01 20:12:43.000000000 -0400
18949 @@ -253,8 +253,13 @@
18950 /*
18951 * Configuration information
18952 */
18953 +#ifdef CONFIG_GRKERNSEC_RANDNET
18954 +#define INPUT_POOL_WORDS 512
18955 +#define OUTPUT_POOL_WORDS 128
18956 +#else
18957 #define INPUT_POOL_WORDS 128
18958 #define OUTPUT_POOL_WORDS 32
18959 +#endif
18960 #define SEC_XFER_SIZE 512
18961
18962 /*
18963 @@ -291,10 +296,17 @@ static struct poolinfo {
18964 int poolwords;
18965 int tap1, tap2, tap3, tap4, tap5;
18966 } poolinfo_table[] = {
18967 +#ifdef CONFIG_GRKERNSEC_RANDNET
18968 + /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
18969 + { 512, 411, 308, 208, 104, 1 },
18970 + /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
18971 + { 128, 103, 76, 51, 25, 1 },
18972 +#else
18973 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
18974 { 128, 103, 76, 51, 25, 1 },
18975 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
18976 { 32, 26, 20, 14, 7, 1 },
18977 +#endif
18978 #if 0
18979 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
18980 { 2048, 1638, 1231, 819, 411, 1 },
18981 @@ -1204,7 +1216,7 @@ EXPORT_SYMBOL(generate_random_uuid);
18982 #include <linux/sysctl.h>
18983
18984 static int min_read_thresh = 8, min_write_thresh;
18985 -static int max_read_thresh = INPUT_POOL_WORDS * 32;
18986 +static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
18987 static int max_write_thresh = INPUT_POOL_WORDS * 32;
18988 static char sysctl_bootid[16];
18989
18990 diff -urNp linux-2.6.31.1/drivers/char/sonypi.c linux-2.6.31.1/drivers/char/sonypi.c
18991 --- linux-2.6.31.1/drivers/char/sonypi.c 2009-09-24 11:45:25.000000000 -0400
18992 +++ linux-2.6.31.1/drivers/char/sonypi.c 2009-10-01 20:12:43.000000000 -0400
18993 @@ -490,7 +490,7 @@ static struct sonypi_device {
18994 spinlock_t fifo_lock;
18995 wait_queue_head_t fifo_proc_list;
18996 struct fasync_struct *fifo_async;
18997 - int open_count;
18998 + atomic_t open_count;
18999 int model;
19000 struct input_dev *input_jog_dev;
19001 struct input_dev *input_key_dev;
19002 @@ -894,7 +894,7 @@ static int sonypi_misc_fasync(int fd, st
19003 static int sonypi_misc_release(struct inode *inode, struct file *file)
19004 {
19005 mutex_lock(&sonypi_device.lock);
19006 - sonypi_device.open_count--;
19007 + atomic_dec(&sonypi_device.open_count);
19008 mutex_unlock(&sonypi_device.lock);
19009 return 0;
19010 }
19011 @@ -904,9 +904,9 @@ static int sonypi_misc_open(struct inode
19012 lock_kernel();
19013 mutex_lock(&sonypi_device.lock);
19014 /* Flush input queue on first open */
19015 - if (!sonypi_device.open_count)
19016 + if (!atomic_read(&sonypi_device.open_count))
19017 kfifo_reset(sonypi_device.fifo);
19018 - sonypi_device.open_count++;
19019 + atomic_inc(&sonypi_device.open_count);
19020 mutex_unlock(&sonypi_device.lock);
19021 unlock_kernel();
19022 return 0;
19023 diff -urNp linux-2.6.31.1/drivers/char/tpm/tpm_bios.c linux-2.6.31.1/drivers/char/tpm/tpm_bios.c
19024 --- linux-2.6.31.1/drivers/char/tpm/tpm_bios.c 2009-09-24 11:45:25.000000000 -0400
19025 +++ linux-2.6.31.1/drivers/char/tpm/tpm_bios.c 2009-10-01 20:12:43.000000000 -0400
19026 @@ -343,14 +343,14 @@ static int tpm_ascii_bios_measurements_s
19027 return 0;
19028 }
19029
19030 -static struct seq_operations tpm_ascii_b_measurments_seqops = {
19031 +static const struct seq_operations tpm_ascii_b_measurments_seqops = {
19032 .start = tpm_bios_measurements_start,
19033 .next = tpm_bios_measurements_next,
19034 .stop = tpm_bios_measurements_stop,
19035 .show = tpm_ascii_bios_measurements_show,
19036 };
19037
19038 -static struct seq_operations tpm_binary_b_measurments_seqops = {
19039 +static const struct seq_operations tpm_binary_b_measurments_seqops = {
19040 .start = tpm_bios_measurements_start,
19041 .next = tpm_bios_measurements_next,
19042 .stop = tpm_bios_measurements_stop,
19043 diff -urNp linux-2.6.31.1/drivers/char/tty_ldisc.c linux-2.6.31.1/drivers/char/tty_ldisc.c
19044 --- linux-2.6.31.1/drivers/char/tty_ldisc.c 2009-09-24 11:45:25.000000000 -0400
19045 +++ linux-2.6.31.1/drivers/char/tty_ldisc.c 2009-10-01 20:12:43.000000000 -0400
19046 @@ -73,7 +73,7 @@ static void put_ldisc(struct tty_ldisc *
19047 if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) {
19048 struct tty_ldisc_ops *ldo = ld->ops;
19049
19050 - ldo->refcount--;
19051 + atomic_dec(&ldo->refcount);
19052 module_put(ldo->owner);
19053 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
19054
19055 @@ -107,7 +107,7 @@ int tty_register_ldisc(int disc, struct
19056 spin_lock_irqsave(&tty_ldisc_lock, flags);
19057 tty_ldiscs[disc] = new_ldisc;
19058 new_ldisc->num = disc;
19059 - new_ldisc->refcount = 0;
19060 + atomic_set(&new_ldisc->refcount, 0);
19061 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
19062
19063 return ret;
19064 @@ -135,7 +135,7 @@ int tty_unregister_ldisc(int disc)
19065 return -EINVAL;
19066
19067 spin_lock_irqsave(&tty_ldisc_lock, flags);
19068 - if (tty_ldiscs[disc]->refcount)
19069 + if (atomic_read(&tty_ldiscs[disc]->refcount))
19070 ret = -EBUSY;
19071 else
19072 tty_ldiscs[disc] = NULL;
19073 @@ -175,7 +175,7 @@ static struct tty_ldisc *tty_ldisc_try_g
19074 err = -EAGAIN;
19075 else {
19076 /* lock it */
19077 - ldops->refcount++;
19078 + atomic_inc(&ldops->refcount);
19079 ld->ops = ldops;
19080 atomic_set(&ld->users, 1);
19081 err = 0;
19082 diff -urNp linux-2.6.31.1/drivers/char/vt_ioctl.c linux-2.6.31.1/drivers/char/vt_ioctl.c
19083 --- linux-2.6.31.1/drivers/char/vt_ioctl.c 2009-09-24 11:45:25.000000000 -0400
19084 +++ linux-2.6.31.1/drivers/char/vt_ioctl.c 2009-10-01 20:12:43.000000000 -0400
19085 @@ -97,6 +97,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
19086 case KDSKBENT:
19087 if (!perm)
19088 return -EPERM;
19089 +
19090 +#ifdef CONFIG_GRKERNSEC
19091 + if (!capable(CAP_SYS_TTY_CONFIG))
19092 + return -EPERM;
19093 +#endif
19094 +
19095 if (!i && v == K_NOSUCHMAP) {
19096 /* deallocate map */
19097 key_map = key_maps[s];
19098 @@ -237,6 +243,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
19099 goto reterr;
19100 }
19101
19102 +#ifdef CONFIG_GRKERNSEC
19103 + if (!capable(CAP_SYS_TTY_CONFIG)) {
19104 + ret = -EPERM;
19105 + goto reterr;
19106 + }
19107 +#endif
19108 +
19109 q = func_table[i];
19110 first_free = funcbufptr + (funcbufsize - funcbufleft);
19111 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
19112 diff -urNp linux-2.6.31.1/drivers/char/xilinx_hwicap/xilinx_hwicap.c linux-2.6.31.1/drivers/char/xilinx_hwicap/xilinx_hwicap.c
19113 --- linux-2.6.31.1/drivers/char/xilinx_hwicap/xilinx_hwicap.c 2009-09-24 11:45:25.000000000 -0400
19114 +++ linux-2.6.31.1/drivers/char/xilinx_hwicap/xilinx_hwicap.c 2009-10-01 20:12:43.000000000 -0400
19115 @@ -559,7 +559,7 @@ static int hwicap_release(struct inode *
19116 return status;
19117 }
19118
19119 -static struct file_operations hwicap_fops = {
19120 +static const struct file_operations hwicap_fops = {
19121 .owner = THIS_MODULE,
19122 .write = hwicap_write,
19123 .read = hwicap_read,
19124 diff -urNp linux-2.6.31.1/drivers/edac/edac_core.h linux-2.6.31.1/drivers/edac/edac_core.h
19125 --- linux-2.6.31.1/drivers/edac/edac_core.h 2009-09-24 11:45:25.000000000 -0400
19126 +++ linux-2.6.31.1/drivers/edac/edac_core.h 2009-10-01 20:12:43.000000000 -0400
19127 @@ -99,11 +99,11 @@ extern int edac_debug_level;
19128
19129 #else /* !CONFIG_EDAC_DEBUG */
19130
19131 -#define debugf0( ... )
19132 -#define debugf1( ... )
19133 -#define debugf2( ... )
19134 -#define debugf3( ... )
19135 -#define debugf4( ... )
19136 +#define debugf0( ... ) do {} while (0)
19137 +#define debugf1( ... ) do {} while (0)
19138 +#define debugf2( ... ) do {} while (0)
19139 +#define debugf3( ... ) do {} while (0)
19140 +#define debugf4( ... ) do {} while (0)
19141
19142 #endif /* !CONFIG_EDAC_DEBUG */
19143
19144 diff -urNp linux-2.6.31.1/drivers/firmware/dmi_scan.c linux-2.6.31.1/drivers/firmware/dmi_scan.c
19145 --- linux-2.6.31.1/drivers/firmware/dmi_scan.c 2009-09-24 11:45:25.000000000 -0400
19146 +++ linux-2.6.31.1/drivers/firmware/dmi_scan.c 2009-10-01 20:12:43.000000000 -0400
19147 @@ -391,11 +391,6 @@ void __init dmi_scan_machine(void)
19148 }
19149 }
19150 else {
19151 - /*
19152 - * no iounmap() for that ioremap(); it would be a no-op, but
19153 - * it's so early in setup that sucker gets confused into doing
19154 - * what it shouldn't if we actually call it.
19155 - */
19156 p = dmi_ioremap(0xF0000, 0x10000);
19157 if (p == NULL)
19158 goto error;
19159 diff -urNp linux-2.6.31.1/drivers/gpio/gpiolib.c linux-2.6.31.1/drivers/gpio/gpiolib.c
19160 --- linux-2.6.31.1/drivers/gpio/gpiolib.c 2009-09-24 11:45:25.000000000 -0400
19161 +++ linux-2.6.31.1/drivers/gpio/gpiolib.c 2009-10-01 20:12:43.000000000 -0400
19162 @@ -1244,7 +1244,7 @@ static int gpiolib_open(struct inode *in
19163 return single_open(file, gpiolib_show, NULL);
19164 }
19165
19166 -static struct file_operations gpiolib_operations = {
19167 +static const struct file_operations gpiolib_operations = {
19168 .open = gpiolib_open,
19169 .read = seq_read,
19170 .llseek = seq_lseek,
19171 diff -urNp linux-2.6.31.1/drivers/gpu/drm/drm_drv.c linux-2.6.31.1/drivers/gpu/drm/drm_drv.c
19172 --- linux-2.6.31.1/drivers/gpu/drm/drm_drv.c 2009-09-24 11:45:25.000000000 -0400
19173 +++ linux-2.6.31.1/drivers/gpu/drm/drm_drv.c 2009-10-01 20:12:43.000000000 -0400
19174 @@ -417,7 +417,7 @@ int drm_ioctl(struct inode *inode, struc
19175 char *kdata = NULL;
19176
19177 atomic_inc(&dev->ioctl_count);
19178 - atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
19179 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_IOCTLS]);
19180 ++file_priv->ioctl_count;
19181
19182 DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
19183 diff -urNp linux-2.6.31.1/drivers/gpu/drm/drm_fops.c linux-2.6.31.1/drivers/gpu/drm/drm_fops.c
19184 --- linux-2.6.31.1/drivers/gpu/drm/drm_fops.c 2009-09-24 11:45:25.000000000 -0400
19185 +++ linux-2.6.31.1/drivers/gpu/drm/drm_fops.c 2009-10-01 20:12:43.000000000 -0400
19186 @@ -66,7 +66,7 @@ static int drm_setup(struct drm_device *
19187 }
19188
19189 for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
19190 - atomic_set(&dev->counts[i], 0);
19191 + atomic_set_unchecked(&dev->counts[i], 0);
19192
19193 dev->sigdata.lock = NULL;
19194
19195 @@ -130,9 +130,9 @@ int drm_open(struct inode *inode, struct
19196
19197 retcode = drm_open_helper(inode, filp, dev);
19198 if (!retcode) {
19199 - atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
19200 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]);
19201 spin_lock(&dev->count_lock);
19202 - if (!dev->open_count++) {
19203 + if (atomic_inc_return(&dev->open_count) == 1) {
19204 spin_unlock(&dev->count_lock);
19205 retcode = drm_setup(dev);
19206 goto out;
19207 @@ -433,7 +433,7 @@ int drm_release(struct inode *inode, str
19208
19209 lock_kernel();
19210
19211 - DRM_DEBUG("open_count = %d\n", dev->open_count);
19212 + DRM_DEBUG("open_count = %d\n", atomic_read(&dev->open_count));
19213
19214 if (dev->driver->preclose)
19215 dev->driver->preclose(dev, file_priv);
19216 @@ -445,7 +445,7 @@ int drm_release(struct inode *inode, str
19217 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
19218 task_pid_nr(current),
19219 (long)old_encode_dev(file_priv->minor->device),
19220 - dev->open_count);
19221 + atomic_read(&dev->open_count));
19222
19223 /* if the master has gone away we can't do anything with the lock */
19224 if (file_priv->minor->master)
19225 @@ -522,9 +522,9 @@ int drm_release(struct inode *inode, str
19226 * End inline drm_release
19227 */
19228
19229 - atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
19230 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_CLOSES]);
19231 spin_lock(&dev->count_lock);
19232 - if (!--dev->open_count) {
19233 + if (atomic_dec_and_test(&dev->open_count)) {
19234 if (atomic_read(&dev->ioctl_count)) {
19235 DRM_ERROR("Device busy: %d\n",
19236 atomic_read(&dev->ioctl_count));
19237 diff -urNp linux-2.6.31.1/drivers/gpu/drm/drm_ioctl.c linux-2.6.31.1/drivers/gpu/drm/drm_ioctl.c
19238 --- linux-2.6.31.1/drivers/gpu/drm/drm_ioctl.c 2009-09-24 11:45:25.000000000 -0400
19239 +++ linux-2.6.31.1/drivers/gpu/drm/drm_ioctl.c 2009-10-01 20:12:43.000000000 -0400
19240 @@ -283,7 +283,7 @@ int drm_getstats(struct drm_device *dev,
19241 stats->data[i].value =
19242 (file_priv->master->lock.hw_lock ? file_priv->master->lock.hw_lock->lock : 0);
19243 else
19244 - stats->data[i].value = atomic_read(&dev->counts[i]);
19245 + stats->data[i].value = atomic_read_unchecked(&dev->counts[i]);
19246 stats->data[i].type = dev->types[i];
19247 }
19248
19249 diff -urNp linux-2.6.31.1/drivers/gpu/drm/drm_lock.c linux-2.6.31.1/drivers/gpu/drm/drm_lock.c
19250 --- linux-2.6.31.1/drivers/gpu/drm/drm_lock.c 2009-09-24 11:45:25.000000000 -0400
19251 +++ linux-2.6.31.1/drivers/gpu/drm/drm_lock.c 2009-10-01 20:12:43.000000000 -0400
19252 @@ -87,7 +87,7 @@ int drm_lock(struct drm_device *dev, voi
19253 if (drm_lock_take(&master->lock, lock->context)) {
19254 master->lock.file_priv = file_priv;
19255 master->lock.lock_time = jiffies;
19256 - atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
19257 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_LOCKS]);
19258 break; /* Got lock */
19259 }
19260
19261 @@ -165,7 +165,7 @@ int drm_unlock(struct drm_device *dev, v
19262 return -EINVAL;
19263 }
19264
19265 - atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
19266 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_UNLOCKS]);
19267
19268 /* kernel_context_switch isn't used by any of the x86 drm
19269 * modules but is required by the Sparc driver.
19270 diff -urNp linux-2.6.31.1/drivers/gpu/drm/drm_vm.c linux-2.6.31.1/drivers/gpu/drm/drm_vm.c
19271 --- linux-2.6.31.1/drivers/gpu/drm/drm_vm.c 2009-09-24 11:45:25.000000000 -0400
19272 +++ linux-2.6.31.1/drivers/gpu/drm/drm_vm.c 2009-10-01 20:12:43.000000000 -0400
19273 @@ -369,28 +369,28 @@ static int drm_vm_sg_fault(struct vm_are
19274 }
19275
19276 /** AGP virtual memory operations */
19277 -static struct vm_operations_struct drm_vm_ops = {
19278 +static const struct vm_operations_struct drm_vm_ops = {
19279 .fault = drm_vm_fault,
19280 .open = drm_vm_open,
19281 .close = drm_vm_close,
19282 };
19283
19284 /** Shared virtual memory operations */
19285 -static struct vm_operations_struct drm_vm_shm_ops = {
19286 +static const struct vm_operations_struct drm_vm_shm_ops = {
19287 .fault = drm_vm_shm_fault,
19288 .open = drm_vm_open,
19289 .close = drm_vm_shm_close,
19290 };
19291
19292 /** DMA virtual memory operations */
19293 -static struct vm_operations_struct drm_vm_dma_ops = {
19294 +static const struct vm_operations_struct drm_vm_dma_ops = {
19295 .fault = drm_vm_dma_fault,
19296 .open = drm_vm_open,
19297 .close = drm_vm_close,
19298 };
19299
19300 /** Scatter-gather virtual memory operations */
19301 -static struct vm_operations_struct drm_vm_sg_ops = {
19302 +static const struct vm_operations_struct drm_vm_sg_ops = {
19303 .fault = drm_vm_sg_fault,
19304 .open = drm_vm_open,
19305 .close = drm_vm_close,
19306 diff -urNp linux-2.6.31.1/drivers/gpu/drm/i810/i810_dma.c linux-2.6.31.1/drivers/gpu/drm/i810/i810_dma.c
19307 --- linux-2.6.31.1/drivers/gpu/drm/i810/i810_dma.c 2009-09-24 11:45:25.000000000 -0400
19308 +++ linux-2.6.31.1/drivers/gpu/drm/i810/i810_dma.c 2009-10-01 20:12:43.000000000 -0400
19309 @@ -952,8 +952,8 @@ static int i810_dma_vertex(struct drm_de
19310 dma->buflist[vertex->idx],
19311 vertex->discard, vertex->used);
19312
19313 - atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
19314 - atomic_inc(&dev->counts[_DRM_STAT_DMA]);
19315 + atomic_add_unchecked(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
19316 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]);
19317 sarea_priv->last_enqueue = dev_priv->counter - 1;
19318 sarea_priv->last_dispatch = (int)hw_status[5];
19319
19320 @@ -1115,8 +1115,8 @@ static int i810_dma_mc(struct drm_device
19321 i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used,
19322 mc->last_render);
19323
19324 - atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
19325 - atomic_inc(&dev->counts[_DRM_STAT_DMA]);
19326 + atomic_add_unchecked(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
19327 + atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]);
19328 sarea_priv->last_enqueue = dev_priv->counter - 1;
19329 sarea_priv->last_dispatch = (int)hw_status[5];
19330
19331 diff -urNp linux-2.6.31.1/drivers/gpu/drm/i915/i915_drv.c linux-2.6.31.1/drivers/gpu/drm/i915/i915_drv.c
19332 --- linux-2.6.31.1/drivers/gpu/drm/i915/i915_drv.c 2009-09-24 11:45:25.000000000 -0400
19333 +++ linux-2.6.31.1/drivers/gpu/drm/i915/i915_drv.c 2009-10-01 20:12:43.000000000 -0400
19334 @@ -154,7 +154,7 @@ i915_pci_resume(struct pci_dev *pdev)
19335 return i915_resume(dev);
19336 }
19337
19338 -static struct vm_operations_struct i915_gem_vm_ops = {
19339 +static const struct vm_operations_struct i915_gem_vm_ops = {
19340 .fault = i915_gem_fault,
19341 .open = drm_gem_vm_open,
19342 .close = drm_gem_vm_close,
19343 diff -urNp linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_atombios.c linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_atombios.c
19344 --- linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_atombios.c 2009-09-24 11:45:25.000000000 -0400
19345 +++ linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_atombios.c 2009-10-01 20:12:43.000000000 -0400
19346 @@ -425,13 +425,13 @@ bool radeon_get_atom_connector_info_from
19347 return true;
19348 }
19349
19350 -struct bios_connector {
19351 +static struct bios_connector {
19352 bool valid;
19353 uint8_t line_mux;
19354 uint16_t devices;
19355 int connector_type;
19356 struct radeon_i2c_bus_rec ddc_bus;
19357 -};
19358 +} bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];;
19359
19360 bool radeon_get_atom_connector_info_from_supported_devices_table(struct
19361 drm_device
19362 @@ -447,7 +447,6 @@ bool radeon_get_atom_connector_info_from
19363 uint8_t dac;
19364 union atom_supported_devices *supported_devices;
19365 int i, j;
19366 - struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];
19367
19368 atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
19369
19370 diff -urNp linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_state.c linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_state.c
19371 --- linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_state.c 2009-09-24 11:45:25.000000000 -0400
19372 +++ linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_state.c 2009-10-01 20:12:43.000000000 -0400
19373 @@ -3007,7 +3007,7 @@ static int radeon_cp_getparam(struct drm
19374 {
19375 drm_radeon_private_t *dev_priv = dev->dev_private;
19376 drm_radeon_getparam_t *param = data;
19377 - int value;
19378 + int value = 0;
19379
19380 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
19381
19382 diff -urNp linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_ttm.c linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_ttm.c
19383 --- linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_ttm.c 2009-09-24 11:45:25.000000000 -0400
19384 +++ linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_ttm.c 2009-10-01 20:12:43.000000000 -0400
19385 @@ -500,27 +500,10 @@ void radeon_ttm_fini(struct radeon_devic
19386 DRM_INFO("radeon: ttm finalized\n");
19387 }
19388
19389 -static struct vm_operations_struct radeon_ttm_vm_ops;
19390 -static struct vm_operations_struct *ttm_vm_ops = NULL;
19391 -
19392 -static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
19393 -{
19394 - struct ttm_buffer_object *bo;
19395 - int r;
19396 -
19397 - bo = (struct ttm_buffer_object *)vma->vm_private_data;
19398 - if (bo == NULL) {
19399 - return VM_FAULT_NOPAGE;
19400 - }
19401 - r = ttm_vm_ops->fault(vma, vmf);
19402 - return r;
19403 -}
19404 -
19405 int radeon_mmap(struct file *filp, struct vm_area_struct *vma)
19406 {
19407 struct drm_file *file_priv;
19408 struct radeon_device *rdev;
19409 - int r;
19410
19411 if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) {
19412 return drm_mmap(filp, vma);
19413 @@ -528,20 +511,9 @@ int radeon_mmap(struct file *filp, struc
19414
19415 file_priv = (struct drm_file *)filp->private_data;
19416 rdev = file_priv->minor->dev->dev_private;
19417 - if (rdev == NULL) {
19418 + if (!rdev)
19419 return -EINVAL;
19420 - }
19421 - r = ttm_bo_mmap(filp, vma, &rdev->mman.bdev);
19422 - if (unlikely(r != 0)) {
19423 - return r;
19424 - }
19425 - if (unlikely(ttm_vm_ops == NULL)) {
19426 - ttm_vm_ops = vma->vm_ops;
19427 - radeon_ttm_vm_ops = *ttm_vm_ops;
19428 - radeon_ttm_vm_ops.fault = &radeon_ttm_fault;
19429 - }
19430 - vma->vm_ops = &radeon_ttm_vm_ops;
19431 - return 0;
19432 + return ttm_bo_mmap(filp, vma, &rdev->mman.bdev);
19433 }
19434
19435
19436 diff -urNp linux-2.6.31.1/drivers/gpu/drm/ttm/ttm_bo_vm.c linux-2.6.31.1/drivers/gpu/drm/ttm/ttm_bo_vm.c
19437 --- linux-2.6.31.1/drivers/gpu/drm/ttm/ttm_bo_vm.c 2009-09-24 11:45:25.000000000 -0400
19438 +++ linux-2.6.31.1/drivers/gpu/drm/ttm/ttm_bo_vm.c 2009-10-01 20:12:43.000000000 -0400
19439 @@ -73,7 +73,7 @@ static int ttm_bo_vm_fault(struct vm_are
19440 {
19441 struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
19442 vma->vm_private_data;
19443 - struct ttm_bo_device *bdev = bo->bdev;
19444 + struct ttm_bo_device *bdev;
19445 unsigned long bus_base;
19446 unsigned long bus_offset;
19447 unsigned long bus_size;
19448 @@ -88,6 +88,10 @@ static int ttm_bo_vm_fault(struct vm_are
19449 unsigned long address = (unsigned long)vmf->virtual_address;
19450 int retval = VM_FAULT_NOPAGE;
19451
19452 + if (!bo)
19453 + return VM_FAULT_NOPAGE;
19454 + bdev = bo->bdev;
19455 +
19456 /*
19457 * Work around locking order reversal in fault / nopfn
19458 * between mmap_sem and bo_reserve: Perform a trylock operation
19459 @@ -228,7 +232,7 @@ static void ttm_bo_vm_close(struct vm_ar
19460 vma->vm_private_data = NULL;
19461 }
19462
19463 -static struct vm_operations_struct ttm_bo_vm_ops = {
19464 +static const struct vm_operations_struct ttm_bo_vm_ops = {
19465 .fault = ttm_bo_vm_fault,
19466 .open = ttm_bo_vm_open,
19467 .close = ttm_bo_vm_close
19468 diff -urNp linux-2.6.31.1/drivers/hwmon/fschmd.c linux-2.6.31.1/drivers/hwmon/fschmd.c
19469 --- linux-2.6.31.1/drivers/hwmon/fschmd.c 2009-09-24 11:45:25.000000000 -0400
19470 +++ linux-2.6.31.1/drivers/hwmon/fschmd.c 2009-10-01 20:12:43.000000000 -0400
19471 @@ -915,7 +915,7 @@ static int watchdog_ioctl(struct inode *
19472 return ret;
19473 }
19474
19475 -static struct file_operations watchdog_fops = {
19476 +static const struct file_operations watchdog_fops = {
19477 .owner = THIS_MODULE,
19478 .llseek = no_llseek,
19479 .open = watchdog_open,
19480 diff -urNp linux-2.6.31.1/drivers/hwmon/fscpos.c linux-2.6.31.1/drivers/hwmon/fscpos.c
19481 --- linux-2.6.31.1/drivers/hwmon/fscpos.c 2009-09-24 11:45:25.000000000 -0400
19482 +++ linux-2.6.31.1/drivers/hwmon/fscpos.c 2009-10-01 20:12:43.000000000 -0400
19483 @@ -240,7 +240,6 @@ static ssize_t set_pwm(struct i2c_client
19484 unsigned long v = simple_strtoul(buf, NULL, 10);
19485
19486 /* Range: 0..255 */
19487 - if (v < 0) v = 0;
19488 if (v > 255) v = 255;
19489
19490 mutex_lock(&data->update_lock);
19491 diff -urNp linux-2.6.31.1/drivers/hwmon/k8temp.c linux-2.6.31.1/drivers/hwmon/k8temp.c
19492 --- linux-2.6.31.1/drivers/hwmon/k8temp.c 2009-09-24 11:45:25.000000000 -0400
19493 +++ linux-2.6.31.1/drivers/hwmon/k8temp.c 2009-10-01 20:12:43.000000000 -0400
19494 @@ -138,7 +138,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
19495
19496 static struct pci_device_id k8temp_ids[] = {
19497 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
19498 - { 0 },
19499 + { 0, 0, 0, 0, 0, 0, 0 },
19500 };
19501
19502 MODULE_DEVICE_TABLE(pci, k8temp_ids);
19503 diff -urNp linux-2.6.31.1/drivers/hwmon/sis5595.c linux-2.6.31.1/drivers/hwmon/sis5595.c
19504 --- linux-2.6.31.1/drivers/hwmon/sis5595.c 2009-09-24 11:45:25.000000000 -0400
19505 +++ linux-2.6.31.1/drivers/hwmon/sis5595.c 2009-10-01 20:12:43.000000000 -0400
19506 @@ -699,7 +699,7 @@ static struct sis5595_data *sis5595_upda
19507
19508 static struct pci_device_id sis5595_pci_ids[] = {
19509 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
19510 - { 0, }
19511 + { 0, 0, 0, 0, 0, 0, 0 }
19512 };
19513
19514 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
19515 diff -urNp linux-2.6.31.1/drivers/hwmon/via686a.c linux-2.6.31.1/drivers/hwmon/via686a.c
19516 --- linux-2.6.31.1/drivers/hwmon/via686a.c 2009-09-24 11:45:25.000000000 -0400
19517 +++ linux-2.6.31.1/drivers/hwmon/via686a.c 2009-10-01 20:12:43.000000000 -0400
19518 @@ -769,7 +769,7 @@ static struct via686a_data *via686a_upda
19519
19520 static struct pci_device_id via686a_pci_ids[] = {
19521 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
19522 - { 0, }
19523 + { 0, 0, 0, 0, 0, 0, 0 }
19524 };
19525
19526 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
19527 diff -urNp linux-2.6.31.1/drivers/hwmon/vt8231.c linux-2.6.31.1/drivers/hwmon/vt8231.c
19528 --- linux-2.6.31.1/drivers/hwmon/vt8231.c 2009-09-24 11:45:25.000000000 -0400
19529 +++ linux-2.6.31.1/drivers/hwmon/vt8231.c 2009-10-01 20:12:43.000000000 -0400
19530 @@ -699,7 +699,7 @@ static struct platform_driver vt8231_dri
19531
19532 static struct pci_device_id vt8231_pci_ids[] = {
19533 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
19534 - { 0, }
19535 + { 0, 0, 0, 0, 0, 0, 0 }
19536 };
19537
19538 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
19539 diff -urNp linux-2.6.31.1/drivers/hwmon/w83791d.c linux-2.6.31.1/drivers/hwmon/w83791d.c
19540 --- linux-2.6.31.1/drivers/hwmon/w83791d.c 2009-09-24 11:45:25.000000000 -0400
19541 +++ linux-2.6.31.1/drivers/hwmon/w83791d.c 2009-10-01 20:12:43.000000000 -0400
19542 @@ -330,8 +330,8 @@ static int w83791d_detect(struct i2c_cli
19543 struct i2c_board_info *info);
19544 static int w83791d_remove(struct i2c_client *client);
19545
19546 -static int w83791d_read(struct i2c_client *client, u8 register);
19547 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
19548 +static int w83791d_read(struct i2c_client *client, u8 reg);
19549 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
19550 static struct w83791d_data *w83791d_update_device(struct device *dev);
19551
19552 #ifdef DEBUG
19553 diff -urNp linux-2.6.31.1/drivers/i2c/busses/i2c-i801.c linux-2.6.31.1/drivers/i2c/busses/i2c-i801.c
19554 --- linux-2.6.31.1/drivers/i2c/busses/i2c-i801.c 2009-09-24 11:45:25.000000000 -0400
19555 +++ linux-2.6.31.1/drivers/i2c/busses/i2c-i801.c 2009-10-01 20:12:43.000000000 -0400
19556 @@ -578,7 +578,7 @@ static struct pci_device_id i801_ids[] =
19557 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
19558 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
19559 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH_SMBUS) },
19560 - { 0, }
19561 + { 0, 0, 0, 0, 0, 0, 0 }
19562 };
19563
19564 MODULE_DEVICE_TABLE (pci, i801_ids);
19565 diff -urNp linux-2.6.31.1/drivers/i2c/busses/i2c-piix4.c linux-2.6.31.1/drivers/i2c/busses/i2c-piix4.c
19566 --- linux-2.6.31.1/drivers/i2c/busses/i2c-piix4.c 2009-09-24 11:45:25.000000000 -0400
19567 +++ linux-2.6.31.1/drivers/i2c/busses/i2c-piix4.c 2009-10-01 20:12:43.000000000 -0400
19568 @@ -123,7 +123,7 @@ static struct dmi_system_id __devinitdat
19569 .ident = "IBM",
19570 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
19571 },
19572 - { },
19573 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
19574 };
19575
19576 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
19577 @@ -489,7 +489,7 @@ static struct pci_device_id piix4_ids[]
19578 PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
19579 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
19580 PCI_DEVICE_ID_SERVERWORKS_HT1100LD) },
19581 - { 0, }
19582 + { 0, 0, 0, 0, 0, 0, 0 }
19583 };
19584
19585 MODULE_DEVICE_TABLE (pci, piix4_ids);
19586 diff -urNp linux-2.6.31.1/drivers/i2c/busses/i2c-sis630.c linux-2.6.31.1/drivers/i2c/busses/i2c-sis630.c
19587 --- linux-2.6.31.1/drivers/i2c/busses/i2c-sis630.c 2009-09-24 11:45:25.000000000 -0400
19588 +++ linux-2.6.31.1/drivers/i2c/busses/i2c-sis630.c 2009-10-01 20:12:43.000000000 -0400
19589 @@ -471,7 +471,7 @@ static struct i2c_adapter sis630_adapter
19590 static struct pci_device_id sis630_ids[] __devinitdata = {
19591 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
19592 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
19593 - { 0, }
19594 + { 0, 0, 0, 0, 0, 0, 0 }
19595 };
19596
19597 MODULE_DEVICE_TABLE (pci, sis630_ids);
19598 diff -urNp linux-2.6.31.1/drivers/i2c/busses/i2c-sis96x.c linux-2.6.31.1/drivers/i2c/busses/i2c-sis96x.c
19599 --- linux-2.6.31.1/drivers/i2c/busses/i2c-sis96x.c 2009-09-24 11:45:25.000000000 -0400
19600 +++ linux-2.6.31.1/drivers/i2c/busses/i2c-sis96x.c 2009-10-01 20:12:43.000000000 -0400
19601 @@ -247,7 +247,7 @@ static struct i2c_adapter sis96x_adapter
19602
19603 static struct pci_device_id sis96x_ids[] = {
19604 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
19605 - { 0, }
19606 + { 0, 0, 0, 0, 0, 0, 0 }
19607 };
19608
19609 MODULE_DEVICE_TABLE (pci, sis96x_ids);
19610 diff -urNp linux-2.6.31.1/drivers/ieee1394/dma.c linux-2.6.31.1/drivers/ieee1394/dma.c
19611 --- linux-2.6.31.1/drivers/ieee1394/dma.c 2009-09-24 11:45:25.000000000 -0400
19612 +++ linux-2.6.31.1/drivers/ieee1394/dma.c 2009-10-01 20:12:43.000000000 -0400
19613 @@ -247,7 +247,7 @@ static int dma_region_pagefault(struct v
19614 return 0;
19615 }
19616
19617 -static struct vm_operations_struct dma_region_vm_ops = {
19618 +static const struct vm_operations_struct dma_region_vm_ops = {
19619 .fault = dma_region_pagefault,
19620 };
19621
19622 diff -urNp linux-2.6.31.1/drivers/ieee1394/dv1394.c linux-2.6.31.1/drivers/ieee1394/dv1394.c
19623 --- linux-2.6.31.1/drivers/ieee1394/dv1394.c 2009-09-24 11:45:25.000000000 -0400
19624 +++ linux-2.6.31.1/drivers/ieee1394/dv1394.c 2009-10-01 20:12:43.000000000 -0400
19625 @@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
19626 based upon DIF section and sequence
19627 */
19628
19629 -static void inline
19630 +static inline void
19631 frame_put_packet (struct frame *f, struct packet *p)
19632 {
19633 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
19634 @@ -2178,7 +2178,7 @@ static const struct ieee1394_device_id d
19635 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
19636 .version = AVC_SW_VERSION_ENTRY & 0xffffff
19637 },
19638 - { }
19639 + { 0, 0, 0, 0, 0, 0 }
19640 };
19641
19642 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
19643 diff -urNp linux-2.6.31.1/drivers/ieee1394/eth1394.c linux-2.6.31.1/drivers/ieee1394/eth1394.c
19644 --- linux-2.6.31.1/drivers/ieee1394/eth1394.c 2009-09-24 11:45:25.000000000 -0400
19645 +++ linux-2.6.31.1/drivers/ieee1394/eth1394.c 2009-10-01 20:12:43.000000000 -0400
19646 @@ -445,7 +445,7 @@ static const struct ieee1394_device_id e
19647 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
19648 .version = ETHER1394_GASP_VERSION,
19649 },
19650 - {}
19651 + { 0, 0, 0, 0, 0, 0 }
19652 };
19653
19654 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
19655 diff -urNp linux-2.6.31.1/drivers/ieee1394/hosts.c linux-2.6.31.1/drivers/ieee1394/hosts.c
19656 --- linux-2.6.31.1/drivers/ieee1394/hosts.c 2009-09-24 11:45:25.000000000 -0400
19657 +++ linux-2.6.31.1/drivers/ieee1394/hosts.c 2009-10-01 20:12:43.000000000 -0400
19658 @@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
19659 }
19660
19661 static struct hpsb_host_driver dummy_driver = {
19662 + .name = "dummy",
19663 .transmit_packet = dummy_transmit_packet,
19664 .devctl = dummy_devctl,
19665 .isoctl = dummy_isoctl
19666 diff -urNp linux-2.6.31.1/drivers/ieee1394/ohci1394.c linux-2.6.31.1/drivers/ieee1394/ohci1394.c
19667 --- linux-2.6.31.1/drivers/ieee1394/ohci1394.c 2009-09-24 11:45:25.000000000 -0400
19668 +++ linux-2.6.31.1/drivers/ieee1394/ohci1394.c 2009-10-01 20:12:43.000000000 -0400
19669 @@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
19670 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
19671
19672 /* Module Parameters */
19673 -static int phys_dma = 1;
19674 +static int phys_dma;
19675 module_param(phys_dma, int, 0444);
19676 -MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
19677 +MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
19678
19679 static void dma_trm_tasklet(unsigned long data);
19680 static void dma_trm_reset(struct dma_trm_ctx *d);
19681 @@ -3449,7 +3449,7 @@ static struct pci_device_id ohci1394_pci
19682 .subvendor = PCI_ANY_ID,
19683 .subdevice = PCI_ANY_ID,
19684 },
19685 - { 0, },
19686 + { 0, 0, 0, 0, 0, 0, 0 },
19687 };
19688
19689 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
19690 diff -urNp linux-2.6.31.1/drivers/ieee1394/raw1394.c linux-2.6.31.1/drivers/ieee1394/raw1394.c
19691 --- linux-2.6.31.1/drivers/ieee1394/raw1394.c 2009-09-24 11:45:25.000000000 -0400
19692 +++ linux-2.6.31.1/drivers/ieee1394/raw1394.c 2009-10-01 20:12:43.000000000 -0400
19693 @@ -2999,7 +2999,7 @@ static const struct ieee1394_device_id r
19694 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
19695 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
19696 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
19697 - {}
19698 + { 0, 0, 0, 0, 0, 0 }
19699 };
19700
19701 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
19702 diff -urNp linux-2.6.31.1/drivers/ieee1394/sbp2.c linux-2.6.31.1/drivers/ieee1394/sbp2.c
19703 --- linux-2.6.31.1/drivers/ieee1394/sbp2.c 2009-09-24 11:45:25.000000000 -0400
19704 +++ linux-2.6.31.1/drivers/ieee1394/sbp2.c 2009-10-01 20:12:43.000000000 -0400
19705 @@ -290,7 +290,7 @@ static const struct ieee1394_device_id s
19706 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
19707 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
19708 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
19709 - {}
19710 + { 0, 0, 0, 0, 0, 0 }
19711 };
19712 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
19713
19714 @@ -2112,7 +2112,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
19715 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
19716 MODULE_LICENSE("GPL");
19717
19718 -static int sbp2_module_init(void)
19719 +static int __init sbp2_module_init(void)
19720 {
19721 int ret;
19722
19723 diff -urNp linux-2.6.31.1/drivers/ieee1394/video1394.c linux-2.6.31.1/drivers/ieee1394/video1394.c
19724 --- linux-2.6.31.1/drivers/ieee1394/video1394.c 2009-09-24 11:45:25.000000000 -0400
19725 +++ linux-2.6.31.1/drivers/ieee1394/video1394.c 2009-10-01 20:12:43.000000000 -0400
19726 @@ -1310,7 +1310,7 @@ static const struct ieee1394_device_id v
19727 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
19728 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
19729 },
19730 - { }
19731 + { 0, 0, 0, 0, 0, 0 }
19732 };
19733
19734 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
19735 diff -urNp linux-2.6.31.1/drivers/infiniband/hw/ehca/ehca_uverbs.c linux-2.6.31.1/drivers/infiniband/hw/ehca/ehca_uverbs.c
19736 --- linux-2.6.31.1/drivers/infiniband/hw/ehca/ehca_uverbs.c 2009-09-24 11:45:25.000000000 -0400
19737 +++ linux-2.6.31.1/drivers/infiniband/hw/ehca/ehca_uverbs.c 2009-10-01 20:12:43.000000000 -0400
19738 @@ -95,7 +95,7 @@ static void ehca_mm_close(struct vm_area
19739 vma->vm_start, vma->vm_end, *count);
19740 }
19741
19742 -static struct vm_operations_struct vm_ops = {
19743 +static const struct vm_operations_struct vm_ops = {
19744 .open = ehca_mm_open,
19745 .close = ehca_mm_close,
19746 };
19747 diff -urNp linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_file_ops.c linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_file_ops.c
19748 --- linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_file_ops.c 2009-09-24 11:45:25.000000000 -0400
19749 +++ linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_file_ops.c 2009-10-01 20:12:43.000000000 -0400
19750 @@ -1151,7 +1151,7 @@ static int ipath_file_vma_fault(struct v
19751 return 0;
19752 }
19753
19754 -static struct vm_operations_struct ipath_file_vm_ops = {
19755 +static const struct vm_operations_struct ipath_file_vm_ops = {
19756 .fault = ipath_file_vma_fault,
19757 };
19758
19759 diff -urNp linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_mmap.c linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_mmap.c
19760 --- linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_mmap.c 2009-09-24 11:45:25.000000000 -0400
19761 +++ linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_mmap.c 2009-10-01 20:12:43.000000000 -0400
19762 @@ -74,7 +74,7 @@ static void ipath_vma_close(struct vm_ar
19763 kref_put(&ip->ref, ipath_release_mmap_info);
19764 }
19765
19766 -static struct vm_operations_struct ipath_vm_ops = {
19767 +static const struct vm_operations_struct ipath_vm_ops = {
19768 .open = ipath_vma_open,
19769 .close = ipath_vma_close,
19770 };
19771 diff -urNp linux-2.6.31.1/drivers/input/keyboard/atkbd.c linux-2.6.31.1/drivers/input/keyboard/atkbd.c
19772 --- linux-2.6.31.1/drivers/input/keyboard/atkbd.c 2009-09-24 11:45:25.000000000 -0400
19773 +++ linux-2.6.31.1/drivers/input/keyboard/atkbd.c 2009-10-01 20:12:43.000000000 -0400
19774 @@ -1188,7 +1188,7 @@ static struct serio_device_id atkbd_seri
19775 .id = SERIO_ANY,
19776 .extra = SERIO_ANY,
19777 },
19778 - { 0 }
19779 + { 0, 0, 0, 0 }
19780 };
19781
19782 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
19783 diff -urNp linux-2.6.31.1/drivers/input/mouse/lifebook.c linux-2.6.31.1/drivers/input/mouse/lifebook.c
19784 --- linux-2.6.31.1/drivers/input/mouse/lifebook.c 2009-09-24 11:45:25.000000000 -0400
19785 +++ linux-2.6.31.1/drivers/input/mouse/lifebook.c 2009-10-01 20:12:43.000000000 -0400
19786 @@ -116,7 +116,7 @@ static const struct dmi_system_id lifebo
19787 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
19788 },
19789 },
19790 - { }
19791 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
19792 };
19793
19794 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
19795 diff -urNp linux-2.6.31.1/drivers/input/mouse/psmouse-base.c linux-2.6.31.1/drivers/input/mouse/psmouse-base.c
19796 --- linux-2.6.31.1/drivers/input/mouse/psmouse-base.c 2009-09-24 11:45:25.000000000 -0400
19797 +++ linux-2.6.31.1/drivers/input/mouse/psmouse-base.c 2009-10-01 20:12:43.000000000 -0400
19798 @@ -1380,7 +1380,7 @@ static struct serio_device_id psmouse_se
19799 .id = SERIO_ANY,
19800 .extra = SERIO_ANY,
19801 },
19802 - { 0 }
19803 + { 0, 0, 0, 0 }
19804 };
19805
19806 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
19807 diff -urNp linux-2.6.31.1/drivers/input/mouse/synaptics.c linux-2.6.31.1/drivers/input/mouse/synaptics.c
19808 --- linux-2.6.31.1/drivers/input/mouse/synaptics.c 2009-09-24 11:45:25.000000000 -0400
19809 +++ linux-2.6.31.1/drivers/input/mouse/synaptics.c 2009-10-01 20:12:43.000000000 -0400
19810 @@ -437,7 +437,7 @@ static void synaptics_process_packet(str
19811 break;
19812 case 2:
19813 if (SYN_MODEL_PEN(priv->model_id))
19814 - ; /* Nothing, treat a pen as a single finger */
19815 + break; /* Nothing, treat a pen as a single finger */
19816 break;
19817 case 4 ... 15:
19818 if (SYN_CAP_PALMDETECT(priv->capabilities))
19819 @@ -653,7 +653,7 @@ static const struct dmi_system_id toshib
19820 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
19821 },
19822 },
19823 - { }
19824 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19825 };
19826 #endif
19827
19828 diff -urNp linux-2.6.31.1/drivers/input/mousedev.c linux-2.6.31.1/drivers/input/mousedev.c
19829 --- linux-2.6.31.1/drivers/input/mousedev.c 2009-09-24 11:45:25.000000000 -0400
19830 +++ linux-2.6.31.1/drivers/input/mousedev.c 2009-10-01 20:12:43.000000000 -0400
19831 @@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han
19832
19833 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
19834 static struct miscdevice psaux_mouse = {
19835 - PSMOUSE_MINOR, "psaux", &mousedev_fops
19836 + PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
19837 };
19838 static int psaux_registered;
19839 #endif
19840 diff -urNp linux-2.6.31.1/drivers/input/serio/i8042-x86ia64io.h linux-2.6.31.1/drivers/input/serio/i8042-x86ia64io.h
19841 --- linux-2.6.31.1/drivers/input/serio/i8042-x86ia64io.h 2009-09-24 11:45:25.000000000 -0400
19842 +++ linux-2.6.31.1/drivers/input/serio/i8042-x86ia64io.h 2009-10-01 20:12:43.000000000 -0400
19843 @@ -167,7 +167,7 @@ static struct dmi_system_id __initdata i
19844 DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
19845 },
19846 },
19847 - { }
19848 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19849 };
19850
19851 /*
19852 @@ -390,7 +390,7 @@ static struct dmi_system_id __initdata i
19853 DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
19854 },
19855 },
19856 - { }
19857 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19858 };
19859
19860 static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
19861 @@ -436,7 +436,7 @@ static struct dmi_system_id __initdata i
19862 DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
19863 },
19864 },
19865 - { }
19866 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19867 };
19868
19869 #ifdef CONFIG_PNP
19870 @@ -455,7 +455,7 @@ static struct dmi_system_id __initdata i
19871 DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
19872 },
19873 },
19874 - { }
19875 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19876 };
19877 #endif
19878
19879 @@ -522,7 +522,7 @@ static struct dmi_system_id __initdata i
19880 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
19881 },
19882 },
19883 - { }
19884 + { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
19885 };
19886
19887 #endif /* CONFIG_X86 */
19888 diff -urNp linux-2.6.31.1/drivers/input/serio/serio_raw.c linux-2.6.31.1/drivers/input/serio/serio_raw.c
19889 --- linux-2.6.31.1/drivers/input/serio/serio_raw.c 2009-09-24 11:45:25.000000000 -0400
19890 +++ linux-2.6.31.1/drivers/input/serio/serio_raw.c 2009-10-01 20:12:43.000000000 -0400
19891 @@ -376,7 +376,7 @@ static struct serio_device_id serio_raw_
19892 .id = SERIO_ANY,
19893 .extra = SERIO_ANY,
19894 },
19895 - { 0 }
19896 + { 0, 0, 0, 0 }
19897 };
19898
19899 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
19900 diff -urNp linux-2.6.31.1/drivers/isdn/capi/kcapi_proc.c linux-2.6.31.1/drivers/isdn/capi/kcapi_proc.c
19901 --- linux-2.6.31.1/drivers/isdn/capi/kcapi_proc.c 2009-09-24 11:45:25.000000000 -0400
19902 +++ linux-2.6.31.1/drivers/isdn/capi/kcapi_proc.c 2009-10-01 20:12:43.000000000 -0400
19903 @@ -89,14 +89,14 @@ static int contrstats_show(struct seq_fi
19904 return 0;
19905 }
19906
19907 -static struct seq_operations seq_controller_ops = {
19908 +static const struct seq_operations seq_controller_ops = {
19909 .start = controller_start,
19910 .next = controller_next,
19911 .stop = controller_stop,
19912 .show = controller_show,
19913 };
19914
19915 -static struct seq_operations seq_contrstats_ops = {
19916 +static const struct seq_operations seq_contrstats_ops = {
19917 .start = controller_start,
19918 .next = controller_next,
19919 .stop = controller_stop,
19920 @@ -194,14 +194,14 @@ applstats_show(struct seq_file *seq, voi
19921 return 0;
19922 }
19923
19924 -static struct seq_operations seq_applications_ops = {
19925 +static const struct seq_operations seq_applications_ops = {
19926 .start = applications_start,
19927 .next = applications_next,
19928 .stop = applications_stop,
19929 .show = applications_show,
19930 };
19931
19932 -static struct seq_operations seq_applstats_ops = {
19933 +static const struct seq_operations seq_applstats_ops = {
19934 .start = applications_start,
19935 .next = applications_next,
19936 .stop = applications_stop,
19937 @@ -264,7 +264,7 @@ static int capi_driver_show(struct seq_f
19938 return 0;
19939 }
19940
19941 -static struct seq_operations seq_capi_driver_ops = {
19942 +static const struct seq_operations seq_capi_driver_ops = {
19943 .start = capi_driver_start,
19944 .next = capi_driver_next,
19945 .stop = capi_driver_stop,
19946 diff -urNp linux-2.6.31.1/drivers/isdn/gigaset/common.c linux-2.6.31.1/drivers/isdn/gigaset/common.c
19947 --- linux-2.6.31.1/drivers/isdn/gigaset/common.c 2009-09-24 11:45:25.000000000 -0400
19948 +++ linux-2.6.31.1/drivers/isdn/gigaset/common.c 2009-10-01 20:12:43.000000000 -0400
19949 @@ -665,7 +665,7 @@ struct cardstate *gigaset_initcs(struct
19950 cs->commands_pending = 0;
19951 cs->cur_at_seq = 0;
19952 cs->gotfwver = -1;
19953 - cs->open_count = 0;
19954 + atomic_set(&cs->open_count, 0);
19955 cs->dev = NULL;
19956 cs->tty = NULL;
19957 cs->tty_dev = NULL;
19958 diff -urNp linux-2.6.31.1/drivers/isdn/gigaset/gigaset.h linux-2.6.31.1/drivers/isdn/gigaset/gigaset.h
19959 --- linux-2.6.31.1/drivers/isdn/gigaset/gigaset.h 2009-09-24 11:45:25.000000000 -0400
19960 +++ linux-2.6.31.1/drivers/isdn/gigaset/gigaset.h 2009-10-01 20:12:43.000000000 -0400
19961 @@ -446,7 +446,7 @@ struct cardstate {
19962 spinlock_t cmdlock;
19963 unsigned curlen, cmdbytes;
19964
19965 - unsigned open_count;
19966 + atomic_t open_count;
19967 struct tty_struct *tty;
19968 struct tasklet_struct if_wake_tasklet;
19969 unsigned control_state;
19970 diff -urNp linux-2.6.31.1/drivers/isdn/gigaset/interface.c linux-2.6.31.1/drivers/isdn/gigaset/interface.c
19971 --- linux-2.6.31.1/drivers/isdn/gigaset/interface.c 2009-09-24 11:45:25.000000000 -0400
19972 +++ linux-2.6.31.1/drivers/isdn/gigaset/interface.c 2009-10-01 20:12:43.000000000 -0400
19973 @@ -165,9 +165,7 @@ static int if_open(struct tty_struct *tt
19974 return -ERESTARTSYS; // FIXME -EINTR?
19975 tty->driver_data = cs;
19976
19977 - ++cs->open_count;
19978 -
19979 - if (cs->open_count == 1) {
19980 + if (atomic_inc_return(&cs->open_count) == 1) {
19981 spin_lock_irqsave(&cs->lock, flags);
19982 cs->tty = tty;
19983 spin_unlock_irqrestore(&cs->lock, flags);
19984 @@ -195,10 +193,10 @@ static void if_close(struct tty_struct *
19985
19986 if (!cs->connected)
19987 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
19988 - else if (!cs->open_count)
19989 + else if (!atomic_read(&cs->open_count))
19990 dev_warn(cs->dev, "%s: device not opened\n", __func__);
19991 else {
19992 - if (!--cs->open_count) {
19993 + if (!atomic_dec_return(&cs->open_count)) {
19994 spin_lock_irqsave(&cs->lock, flags);
19995 cs->tty = NULL;
19996 spin_unlock_irqrestore(&cs->lock, flags);
19997 @@ -233,7 +231,7 @@ static int if_ioctl(struct tty_struct *t
19998 if (!cs->connected) {
19999 gig_dbg(DEBUG_IF, "not connected");
20000 retval = -ENODEV;
20001 - } else if (!cs->open_count)
20002 + } else if (!atomic_read(&cs->open_count))
20003 dev_warn(cs->dev, "%s: device not opened\n", __func__);
20004 else {
20005 retval = 0;
20006 @@ -361,7 +359,7 @@ static int if_write(struct tty_struct *t
20007 if (!cs->connected) {
20008 gig_dbg(DEBUG_IF, "not connected");
20009 retval = -ENODEV;
20010 - } else if (!cs->open_count)
20011 + } else if (!atomic_read(&cs->open_count))
20012 dev_warn(cs->dev, "%s: device not opened\n", __func__);
20013 else if (cs->mstate != MS_LOCKED) {
20014 dev_warn(cs->dev, "can't write to unlocked device\n");
20015 @@ -395,7 +393,7 @@ static int if_write_room(struct tty_stru
20016 if (!cs->connected) {
20017 gig_dbg(DEBUG_IF, "not connected");
20018 retval = -ENODEV;
20019 - } else if (!cs->open_count)
20020 + } else if (!atomic_read(&cs->open_count))
20021 dev_warn(cs->dev, "%s: device not opened\n", __func__);
20022 else if (cs->mstate != MS_LOCKED) {
20023 dev_warn(cs->dev, "can't write to unlocked device\n");
20024 @@ -429,7 +427,7 @@ static int if_chars_in_buffer(struct tty
20025 if (!cs->connected) {
20026 gig_dbg(DEBUG_IF, "not connected");
20027 retval = -ENODEV;
20028 - } else if (!cs->open_count)
20029 + } else if (!atomic_read(&cs->open_count))
20030 dev_warn(cs->dev, "%s: device not opened\n", __func__);
20031 else if (cs->mstate != MS_LOCKED) {
20032 dev_warn(cs->dev, "can't write to unlocked device\n");
20033 @@ -458,7 +456,7 @@ static void if_throttle(struct tty_struc
20034
20035 if (!cs->connected)
20036 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
20037 - else if (!cs->open_count)
20038 + else if (!atomic_read(&cs->open_count))
20039 dev_warn(cs->dev, "%s: device not opened\n", __func__);
20040 else {
20041 //FIXME
20042 @@ -483,7 +481,7 @@ static void if_unthrottle(struct tty_str
20043
20044 if (!cs->connected)
20045 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
20046 - else if (!cs->open_count)
20047 + else if (!atomic_read(&cs->open_count))
20048 dev_warn(cs->dev, "%s: device not opened\n", __func__);
20049 else {
20050 //FIXME
20051 @@ -515,7 +513,7 @@ static void if_set_termios(struct tty_st
20052 goto out;
20053 }
20054
20055 - if (!cs->open_count) {
20056 + if (!atomic_read(&cs->open_count)) {
20057 dev_warn(cs->dev, "%s: device not opened\n", __func__);
20058 goto out;
20059 }
20060 diff -urNp linux-2.6.31.1/drivers/lguest/core.c linux-2.6.31.1/drivers/lguest/core.c
20061 --- linux-2.6.31.1/drivers/lguest/core.c 2009-09-24 11:45:25.000000000 -0400
20062 +++ linux-2.6.31.1/drivers/lguest/core.c 2009-10-01 20:12:43.000000000 -0400
20063 @@ -92,9 +92,17 @@ static __init int map_switcher(void)
20064 * it's worked so far. The end address needs +1 because __get_vm_area
20065 * allocates an extra guard page, so we need space for that.
20066 */
20067 +
20068 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
20069 + switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
20070 + VM_ALLOC | VM_KERNEXEC, SWITCHER_ADDR, SWITCHER_ADDR
20071 + + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
20072 +#else
20073 switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
20074 VM_ALLOC, SWITCHER_ADDR, SWITCHER_ADDR
20075 + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
20076 +#endif
20077 +
20078 if (!switcher_vma) {
20079 err = -ENOMEM;
20080 printk("lguest: could not map switcher pages high\n");
20081 diff -urNp linux-2.6.31.1/drivers/lguest/lguest_user.c linux-2.6.31.1/drivers/lguest/lguest_user.c
20082 --- linux-2.6.31.1/drivers/lguest/lguest_user.c 2009-09-24 11:45:25.000000000 -0400
20083 +++ linux-2.6.31.1/drivers/lguest/lguest_user.c 2009-10-01 20:12:43.000000000 -0400
20084 @@ -508,7 +508,7 @@ static int close(struct inode *inode, st
20085 * uses: reading and writing a character device called /dev/lguest. All the
20086 * work happens in the read(), write() and close() routines:
20087 */
20088 -static struct file_operations lguest_fops = {
20089 +static const struct file_operations lguest_fops = {
20090 .owner = THIS_MODULE,
20091 .release = close,
20092 .write = write,
20093 diff -urNp linux-2.6.31.1/drivers/md/bitmap.c linux-2.6.31.1/drivers/md/bitmap.c
20094 --- linux-2.6.31.1/drivers/md/bitmap.c 2009-09-24 11:45:25.000000000 -0400
20095 +++ linux-2.6.31.1/drivers/md/bitmap.c 2009-10-01 20:12:43.000000000 -0400
20096 @@ -58,7 +58,7 @@
20097 # if DEBUG > 0
20098 # define PRINTK(x...) printk(KERN_DEBUG x)
20099 # else
20100 -# define PRINTK(x...)
20101 +# define PRINTK(x...) do {} while (0)
20102 # endif
20103 #endif
20104
20105 diff -urNp linux-2.6.31.1/drivers/md/dm-table.c linux-2.6.31.1/drivers/md/dm-table.c
20106 --- linux-2.6.31.1/drivers/md/dm-table.c 2009-09-24 11:45:25.000000000 -0400
20107 +++ linux-2.6.31.1/drivers/md/dm-table.c 2009-10-01 20:12:43.000000000 -0400
20108 @@ -359,7 +359,7 @@ static int device_area_is_invalid(struct
20109 if (!dev_size)
20110 return 0;
20111
20112 - if ((start >= dev_size) || (start + len > dev_size)) {
20113 + if ((start >= dev_size) || (len > dev_size - start)) {
20114 DMWARN("%s: %s too small for target: "
20115 "start=%llu, len=%llu, dev_size=%llu",
20116 dm_device_name(ti->table->md), bdevname(bdev, b),
20117 diff -urNp linux-2.6.31.1/drivers/md/md.c linux-2.6.31.1/drivers/md/md.c
20118 --- linux-2.6.31.1/drivers/md/md.c 2009-09-24 11:45:25.000000000 -0400
20119 +++ linux-2.6.31.1/drivers/md/md.c 2009-10-01 20:12:43.000000000 -0400
20120 @@ -5963,7 +5963,7 @@ static int md_seq_show(struct seq_file *
20121 chunk_kb ? "KB" : "B");
20122 if (bitmap->file) {
20123 seq_printf(seq, ", file: ");
20124 - seq_path(seq, &bitmap->file->f_path, " \t\n");
20125 + seq_path(seq, &bitmap->file->f_path, " \t\n\\");
20126 }
20127
20128 seq_printf(seq, "\n");
20129 @@ -6057,7 +6057,7 @@ static int is_mddev_idle(mddev_t *mddev,
20130 struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
20131 curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
20132 (int)part_stat_read(&disk->part0, sectors[1]) -
20133 - atomic_read(&disk->sync_io);
20134 + atomic_read_unchecked(&disk->sync_io);
20135 /* sync IO will cause sync_io to increase before the disk_stats
20136 * as sync_io is counted when a request starts, and
20137 * disk_stats is counted when it completes.
20138 diff -urNp linux-2.6.31.1/drivers/md/md.h linux-2.6.31.1/drivers/md/md.h
20139 --- linux-2.6.31.1/drivers/md/md.h 2009-09-24 11:45:25.000000000 -0400
20140 +++ linux-2.6.31.1/drivers/md/md.h 2009-10-01 20:12:43.000000000 -0400
20141 @@ -303,7 +303,7 @@ static inline void rdev_dec_pending(mdk_
20142
20143 static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sectors)
20144 {
20145 - atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
20146 + atomic_add_unchecked(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
20147 }
20148
20149 struct mdk_personality
20150 diff -urNp linux-2.6.31.1/drivers/media/dvb/dvb-core/dmxdev.c linux-2.6.31.1/drivers/media/dvb/dvb-core/dmxdev.c
20151 --- linux-2.6.31.1/drivers/media/dvb/dvb-core/dmxdev.c 2009-09-24 11:45:25.000000000 -0400
20152 +++ linux-2.6.31.1/drivers/media/dvb/dvb-core/dmxdev.c 2009-10-01 20:12:43.000000000 -0400
20153 @@ -1086,7 +1086,7 @@ static unsigned int dvb_dvr_poll(struct
20154 return mask;
20155 }
20156
20157 -static struct file_operations dvb_dvr_fops = {
20158 +static const struct file_operations dvb_dvr_fops = {
20159 .owner = THIS_MODULE,
20160 .read = dvb_dvr_read,
20161 .write = dvb_dvr_write,
20162 diff -urNp linux-2.6.31.1/drivers/media/dvb/firewire/firedtv-ci.c linux-2.6.31.1/drivers/media/dvb/firewire/firedtv-ci.c
20163 --- linux-2.6.31.1/drivers/media/dvb/firewire/firedtv-ci.c 2009-09-24 11:45:25.000000000 -0400
20164 +++ linux-2.6.31.1/drivers/media/dvb/firewire/firedtv-ci.c 2009-10-01 20:12:43.000000000 -0400
20165 @@ -215,7 +215,7 @@ static unsigned int fdtv_ca_io_poll(stru
20166 return POLLIN;
20167 }
20168
20169 -static struct file_operations fdtv_ca_fops = {
20170 +static const struct file_operations fdtv_ca_fops = {
20171 .owner = THIS_MODULE,
20172 .ioctl = dvb_generic_ioctl,
20173 .open = dvb_generic_open,
20174 diff -urNp linux-2.6.31.1/drivers/media/video/cafe_ccic.c linux-2.6.31.1/drivers/media/video/cafe_ccic.c
20175 --- linux-2.6.31.1/drivers/media/video/cafe_ccic.c 2009-09-24 11:45:25.000000000 -0400
20176 +++ linux-2.6.31.1/drivers/media/video/cafe_ccic.c 2009-10-01 20:12:43.000000000 -0400
20177 @@ -1326,7 +1326,7 @@ static void cafe_v4l_vm_close(struct vm_
20178 mutex_unlock(&sbuf->cam->s_mutex);
20179 }
20180
20181 -static struct vm_operations_struct cafe_v4l_vm_ops = {
20182 +static const struct vm_operations_struct cafe_v4l_vm_ops = {
20183 .open = cafe_v4l_vm_open,
20184 .close = cafe_v4l_vm_close
20185 };
20186 diff -urNp linux-2.6.31.1/drivers/media/video/et61x251/et61x251_core.c linux-2.6.31.1/drivers/media/video/et61x251/et61x251_core.c
20187 --- linux-2.6.31.1/drivers/media/video/et61x251/et61x251_core.c 2009-09-24 11:45:25.000000000 -0400
20188 +++ linux-2.6.31.1/drivers/media/video/et61x251/et61x251_core.c 2009-10-01 20:12:43.000000000 -0400
20189 @@ -1494,7 +1494,7 @@ static void et61x251_vm_close(struct vm_
20190 }
20191
20192
20193 -static struct vm_operations_struct et61x251_vm_ops = {
20194 +static const struct vm_operations_struct et61x251_vm_ops = {
20195 .open = et61x251_vm_open,
20196 .close = et61x251_vm_close,
20197 };
20198 diff -urNp linux-2.6.31.1/drivers/media/video/gspca/gspca.c linux-2.6.31.1/drivers/media/video/gspca/gspca.c
20199 --- linux-2.6.31.1/drivers/media/video/gspca/gspca.c 2009-09-24 11:45:25.000000000 -0400
20200 +++ linux-2.6.31.1/drivers/media/video/gspca/gspca.c 2009-10-01 20:12:43.000000000 -0400
20201 @@ -99,7 +99,7 @@ static void gspca_vm_close(struct vm_are
20202 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_MAPPED;
20203 }
20204
20205 -static struct vm_operations_struct gspca_vm_ops = {
20206 +static const struct vm_operations_struct gspca_vm_ops = {
20207 .open = gspca_vm_open,
20208 .close = gspca_vm_close,
20209 };
20210 diff -urNp linux-2.6.31.1/drivers/media/video/meye.c linux-2.6.31.1/drivers/media/video/meye.c
20211 --- linux-2.6.31.1/drivers/media/video/meye.c 2009-09-24 11:45:25.000000000 -0400
20212 +++ linux-2.6.31.1/drivers/media/video/meye.c 2009-10-01 20:12:43.000000000 -0400
20213 @@ -1589,7 +1589,7 @@ static void meye_vm_close(struct vm_area
20214 meye.vma_use_count[idx]--;
20215 }
20216
20217 -static struct vm_operations_struct meye_vm_ops = {
20218 +static const struct vm_operations_struct meye_vm_ops = {
20219 .open = meye_vm_open,
20220 .close = meye_vm_close,
20221 };
20222 diff -urNp linux-2.6.31.1/drivers/media/video/sn9c102/sn9c102_core.c linux-2.6.31.1/drivers/media/video/sn9c102/sn9c102_core.c
20223 --- linux-2.6.31.1/drivers/media/video/sn9c102/sn9c102_core.c 2009-09-24 11:45:25.000000000 -0400
20224 +++ linux-2.6.31.1/drivers/media/video/sn9c102/sn9c102_core.c 2009-10-01 20:12:43.000000000 -0400
20225 @@ -2075,7 +2075,7 @@ static void sn9c102_vm_close(struct vm_a
20226 }
20227
20228
20229 -static struct vm_operations_struct sn9c102_vm_ops = {
20230 +static const struct vm_operations_struct sn9c102_vm_ops = {
20231 .open = sn9c102_vm_open,
20232 .close = sn9c102_vm_close,
20233 };
20234 diff -urNp linux-2.6.31.1/drivers/media/video/stk-webcam.c linux-2.6.31.1/drivers/media/video/stk-webcam.c
20235 --- linux-2.6.31.1/drivers/media/video/stk-webcam.c 2009-09-24 11:45:25.000000000 -0400
20236 +++ linux-2.6.31.1/drivers/media/video/stk-webcam.c 2009-10-01 20:12:43.000000000 -0400
20237 @@ -790,7 +790,7 @@ static void stk_v4l_vm_close(struct vm_a
20238 if (sbuf->mapcount == 0)
20239 sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_MAPPED;
20240 }
20241 -static struct vm_operations_struct stk_v4l_vm_ops = {
20242 +static const struct vm_operations_struct stk_v4l_vm_ops = {
20243 .open = stk_v4l_vm_open,
20244 .close = stk_v4l_vm_close
20245 };
20246 diff -urNp linux-2.6.31.1/drivers/media/video/usbvideo/konicawc.c linux-2.6.31.1/drivers/media/video/usbvideo/konicawc.c
20247 --- linux-2.6.31.1/drivers/media/video/usbvideo/konicawc.c 2009-09-24 11:45:25.000000000 -0400
20248 +++ linux-2.6.31.1/drivers/media/video/usbvideo/konicawc.c 2009-10-01 20:12:43.000000000 -0400
20249 @@ -225,7 +225,7 @@ static void konicawc_register_input(stru
20250 int error;
20251
20252 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
20253 - strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
20254 + strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
20255
20256 cam->input = input_dev = input_allocate_device();
20257 if (!input_dev) {
20258 diff -urNp linux-2.6.31.1/drivers/media/video/usbvideo/quickcam_messenger.c linux-2.6.31.1/drivers/media/video/usbvideo/quickcam_messenger.c
20259 --- linux-2.6.31.1/drivers/media/video/usbvideo/quickcam_messenger.c 2009-09-24 11:45:25.000000000 -0400
20260 +++ linux-2.6.31.1/drivers/media/video/usbvideo/quickcam_messenger.c 2009-10-01 20:12:43.000000000 -0400
20261 @@ -89,7 +89,7 @@ static void qcm_register_input(struct qc
20262 int error;
20263
20264 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
20265 - strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
20266 + strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
20267
20268 cam->input = input_dev = input_allocate_device();
20269 if (!input_dev) {
20270 diff -urNp linux-2.6.31.1/drivers/media/video/uvc/uvc_v4l2.c linux-2.6.31.1/drivers/media/video/uvc/uvc_v4l2.c
20271 --- linux-2.6.31.1/drivers/media/video/uvc/uvc_v4l2.c 2009-09-24 11:45:25.000000000 -0400
20272 +++ linux-2.6.31.1/drivers/media/video/uvc/uvc_v4l2.c 2009-10-01 20:12:43.000000000 -0400
20273 @@ -1063,7 +1063,7 @@ static void uvc_vm_close(struct vm_area_
20274 buffer->vma_use_count--;
20275 }
20276
20277 -static struct vm_operations_struct uvc_vm_ops = {
20278 +static const struct vm_operations_struct uvc_vm_ops = {
20279 .open = uvc_vm_open,
20280 .close = uvc_vm_close,
20281 };
20282 diff -urNp linux-2.6.31.1/drivers/media/video/videobuf-dma-contig.c linux-2.6.31.1/drivers/media/video/videobuf-dma-contig.c
20283 --- linux-2.6.31.1/drivers/media/video/videobuf-dma-contig.c 2009-09-24 11:45:25.000000000 -0400
20284 +++ linux-2.6.31.1/drivers/media/video/videobuf-dma-contig.c 2009-10-01 20:12:43.000000000 -0400
20285 @@ -105,7 +105,7 @@ static void videobuf_vm_close(struct vm_
20286 }
20287 }
20288
20289 -static struct vm_operations_struct videobuf_vm_ops = {
20290 +static const struct vm_operations_struct videobuf_vm_ops = {
20291 .open = videobuf_vm_open,
20292 .close = videobuf_vm_close,
20293 };
20294 diff -urNp linux-2.6.31.1/drivers/media/video/vino.c linux-2.6.31.1/drivers/media/video/vino.c
20295 --- linux-2.6.31.1/drivers/media/video/vino.c 2009-09-24 11:45:25.000000000 -0400
20296 +++ linux-2.6.31.1/drivers/media/video/vino.c 2009-10-01 20:12:43.000000000 -0400
20297 @@ -3858,7 +3858,7 @@ static void vino_vm_close(struct vm_area
20298 dprintk("vino_vm_close(): count = %d\n", fb->map_count);
20299 }
20300
20301 -static struct vm_operations_struct vino_vm_ops = {
20302 +static const struct vm_operations_struct vino_vm_ops = {
20303 .open = vino_vm_open,
20304 .close = vino_vm_close,
20305 };
20306 diff -urNp linux-2.6.31.1/drivers/media/video/zc0301/zc0301_core.c linux-2.6.31.1/drivers/media/video/zc0301/zc0301_core.c
20307 --- linux-2.6.31.1/drivers/media/video/zc0301/zc0301_core.c 2009-09-24 11:45:25.000000000 -0400
20308 +++ linux-2.6.31.1/drivers/media/video/zc0301/zc0301_core.c 2009-10-01 20:12:43.000000000 -0400
20309 @@ -933,7 +933,7 @@ static void zc0301_vm_close(struct vm_ar
20310 }
20311
20312
20313 -static struct vm_operations_struct zc0301_vm_ops = {
20314 +static const struct vm_operations_struct zc0301_vm_ops = {
20315 .open = zc0301_vm_open,
20316 .close = zc0301_vm_close,
20317 };
20318 diff -urNp linux-2.6.31.1/drivers/media/video/zoran/zoran_driver.c linux-2.6.31.1/drivers/media/video/zoran/zoran_driver.c
20319 --- linux-2.6.31.1/drivers/media/video/zoran/zoran_driver.c 2009-09-24 11:45:25.000000000 -0400
20320 +++ linux-2.6.31.1/drivers/media/video/zoran/zoran_driver.c 2009-10-01 20:12:43.000000000 -0400
20321 @@ -3172,7 +3172,7 @@ zoran_vm_close (struct vm_area_struct *v
20322 mutex_unlock(&zr->resource_lock);
20323 }
20324
20325 -static struct vm_operations_struct zoran_vm_ops = {
20326 +static const struct vm_operations_struct zoran_vm_ops = {
20327 .open = zoran_vm_open,
20328 .close = zoran_vm_close,
20329 };
20330 diff -urNp linux-2.6.31.1/drivers/message/i2o/i2o_proc.c linux-2.6.31.1/drivers/message/i2o/i2o_proc.c
20331 --- linux-2.6.31.1/drivers/message/i2o/i2o_proc.c 2009-09-24 11:45:25.000000000 -0400
20332 +++ linux-2.6.31.1/drivers/message/i2o/i2o_proc.c 2009-10-01 20:12:43.000000000 -0400
20333 @@ -259,13 +259,6 @@ static char *scsi_devices[] = {
20334 "Array Controller Device"
20335 };
20336
20337 -static char *chtostr(u8 * chars, int n)
20338 -{
20339 - char tmp[256];
20340 - tmp[0] = 0;
20341 - return strncat(tmp, (char *)chars, n);
20342 -}
20343 -
20344 static int i2o_report_query_status(struct seq_file *seq, int block_status,
20345 char *group)
20346 {
20347 @@ -842,8 +835,7 @@ static int i2o_seq_show_ddm_table(struct
20348
20349 seq_printf(seq, "%-#7x", ddm_table.i2o_vendor_id);
20350 seq_printf(seq, "%-#8x", ddm_table.module_id);
20351 - seq_printf(seq, "%-29s",
20352 - chtostr(ddm_table.module_name_version, 28));
20353 + seq_printf(seq, "%-.28s", ddm_table.module_name_version);
20354 seq_printf(seq, "%9d ", ddm_table.data_size);
20355 seq_printf(seq, "%8d", ddm_table.code_size);
20356
20357 @@ -944,8 +936,8 @@ static int i2o_seq_show_drivers_stored(s
20358
20359 seq_printf(seq, "%-#7x", dst->i2o_vendor_id);
20360 seq_printf(seq, "%-#8x", dst->module_id);
20361 - seq_printf(seq, "%-29s", chtostr(dst->module_name_version, 28));
20362 - seq_printf(seq, "%-9s", chtostr(dst->date, 8));
20363 + seq_printf(seq, "%-.28s", dst->module_name_version);
20364 + seq_printf(seq, "%-.8s", dst->date);
20365 seq_printf(seq, "%8d ", dst->module_size);
20366 seq_printf(seq, "%8d ", dst->mpb_size);
20367 seq_printf(seq, "0x%04x", dst->module_flags);
20368 @@ -1276,14 +1268,10 @@ static int i2o_seq_show_dev_identity(str
20369 seq_printf(seq, "Device Class : %s\n", i2o_get_class_name(work16[0]));
20370 seq_printf(seq, "Owner TID : %0#5x\n", work16[2]);
20371 seq_printf(seq, "Parent TID : %0#5x\n", work16[3]);
20372 - seq_printf(seq, "Vendor info : %s\n",
20373 - chtostr((u8 *) (work32 + 2), 16));
20374 - seq_printf(seq, "Product info : %s\n",
20375 - chtostr((u8 *) (work32 + 6), 16));
20376 - seq_printf(seq, "Description : %s\n",
20377 - chtostr((u8 *) (work32 + 10), 16));
20378 - seq_printf(seq, "Product rev. : %s\n",
20379 - chtostr((u8 *) (work32 + 14), 8));
20380 + seq_printf(seq, "Vendor info : %.16s\n", (u8 *) (work32 + 2));
20381 + seq_printf(seq, "Product info : %.16s\n", (u8 *) (work32 + 6));
20382 + seq_printf(seq, "Description : %.16s\n", (u8 *) (work32 + 10));
20383 + seq_printf(seq, "Product rev. : %.8s\n", (u8 *) (work32 + 14));
20384
20385 seq_printf(seq, "Serial number : ");
20386 print_serial_number(seq, (u8 *) (work32 + 16),
20387 @@ -1328,10 +1316,8 @@ static int i2o_seq_show_ddm_identity(str
20388 }
20389
20390 seq_printf(seq, "Registering DDM TID : 0x%03x\n", result.ddm_tid);
20391 - seq_printf(seq, "Module name : %s\n",
20392 - chtostr(result.module_name, 24));
20393 - seq_printf(seq, "Module revision : %s\n",
20394 - chtostr(result.module_rev, 8));
20395 + seq_printf(seq, "Module name : %.24s\n", result.module_name);
20396 + seq_printf(seq, "Module revision : %.8s\n", result.module_rev);
20397
20398 seq_printf(seq, "Serial number : ");
20399 print_serial_number(seq, result.serial_number, sizeof(result) - 36);
20400 @@ -1362,14 +1348,10 @@ static int i2o_seq_show_uinfo(struct seq
20401 return 0;
20402 }
20403
20404 - seq_printf(seq, "Device name : %s\n",
20405 - chtostr(result.device_name, 64));
20406 - seq_printf(seq, "Service name : %s\n",
20407 - chtostr(result.service_name, 64));
20408 - seq_printf(seq, "Physical name : %s\n",
20409 - chtostr(result.physical_location, 64));
20410 - seq_printf(seq, "Instance number : %s\n",
20411 - chtostr(result.instance_number, 4));
20412 + seq_printf(seq, "Device name : %.64s\n", result.device_name);
20413 + seq_printf(seq, "Service name : %.64s\n", result.service_name);
20414 + seq_printf(seq, "Physical name : %.64s\n", result.physical_location);
20415 + seq_printf(seq, "Instance number : %.4s\n", result.instance_number);
20416
20417 return 0;
20418 }
20419 diff -urNp linux-2.6.31.1/drivers/misc/ibmasm/ibmasmfs.c linux-2.6.31.1/drivers/misc/ibmasm/ibmasmfs.c
20420 --- linux-2.6.31.1/drivers/misc/ibmasm/ibmasmfs.c 2009-09-24 11:45:25.000000000 -0400
20421 +++ linux-2.6.31.1/drivers/misc/ibmasm/ibmasmfs.c 2009-10-01 20:12:43.000000000 -0400
20422 @@ -97,7 +97,7 @@ static int ibmasmfs_get_super(struct fil
20423 return get_sb_single(fst, flags, data, ibmasmfs_fill_super, mnt);
20424 }
20425
20426 -static struct super_operations ibmasmfs_s_ops = {
20427 +static const struct super_operations ibmasmfs_s_ops = {
20428 .statfs = simple_statfs,
20429 .drop_inode = generic_delete_inode,
20430 };
20431 diff -urNp linux-2.6.31.1/drivers/misc/phantom.c linux-2.6.31.1/drivers/misc/phantom.c
20432 --- linux-2.6.31.1/drivers/misc/phantom.c 2009-09-24 11:45:25.000000000 -0400
20433 +++ linux-2.6.31.1/drivers/misc/phantom.c 2009-10-01 20:12:43.000000000 -0400
20434 @@ -271,7 +271,7 @@ static unsigned int phantom_poll(struct
20435 return mask;
20436 }
20437
20438 -static struct file_operations phantom_file_ops = {
20439 +static const struct file_operations phantom_file_ops = {
20440 .open = phantom_open,
20441 .release = phantom_release,
20442 .unlocked_ioctl = phantom_ioctl,
20443 diff -urNp linux-2.6.31.1/drivers/misc/sgi-gru/grufile.c linux-2.6.31.1/drivers/misc/sgi-gru/grufile.c
20444 --- linux-2.6.31.1/drivers/misc/sgi-gru/grufile.c 2009-09-24 11:45:25.000000000 -0400
20445 +++ linux-2.6.31.1/drivers/misc/sgi-gru/grufile.c 2009-10-01 20:12:43.000000000 -0400
20446 @@ -53,7 +53,7 @@ struct gru_stats_s gru_stats;
20447 /* Guaranteed user available resources on each node */
20448 static int max_user_cbrs, max_user_dsr_bytes;
20449
20450 -static struct file_operations gru_fops;
20451 +static const struct file_operations gru_fops;
20452 static struct miscdevice gru_miscdev;
20453
20454
20455 @@ -426,7 +426,7 @@ static void __exit gru_exit(void)
20456 gru_proc_exit();
20457 }
20458
20459 -static struct file_operations gru_fops = {
20460 +static const struct file_operations gru_fops = {
20461 .owner = THIS_MODULE,
20462 .unlocked_ioctl = gru_file_unlocked_ioctl,
20463 .mmap = gru_file_mmap,
20464 @@ -438,7 +438,7 @@ static struct miscdevice gru_miscdev = {
20465 .fops = &gru_fops,
20466 };
20467
20468 -struct vm_operations_struct gru_vm_ops = {
20469 +const struct vm_operations_struct gru_vm_ops = {
20470 .close = gru_vma_close,
20471 .fault = gru_fault,
20472 };
20473 diff -urNp linux-2.6.31.1/drivers/misc/sgi-gru/grutables.h linux-2.6.31.1/drivers/misc/sgi-gru/grutables.h
20474 --- linux-2.6.31.1/drivers/misc/sgi-gru/grutables.h 2009-09-24 11:45:25.000000000 -0400
20475 +++ linux-2.6.31.1/drivers/misc/sgi-gru/grutables.h 2009-10-01 20:12:43.000000000 -0400
20476 @@ -624,7 +624,7 @@ static inline int is_kernel_context(stru
20477 */
20478 struct gru_unload_context_req;
20479
20480 -extern struct vm_operations_struct gru_vm_ops;
20481 +extern const struct vm_operations_struct gru_vm_ops;
20482 extern struct device *grudev;
20483
20484 extern struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma,
20485 diff -urNp linux-2.6.31.1/drivers/mmc/core/debugfs.c linux-2.6.31.1/drivers/mmc/core/debugfs.c
20486 --- linux-2.6.31.1/drivers/mmc/core/debugfs.c 2009-09-24 11:45:25.000000000 -0400
20487 +++ linux-2.6.31.1/drivers/mmc/core/debugfs.c 2009-10-01 20:12:43.000000000 -0400
20488 @@ -240,7 +240,7 @@ static int mmc_ext_csd_release(struct in
20489 return 0;
20490 }
20491
20492 -static struct file_operations mmc_dbg_ext_csd_fops = {
20493 +static const struct file_operations mmc_dbg_ext_csd_fops = {
20494 .open = mmc_ext_csd_open,
20495 .read = mmc_ext_csd_read,
20496 .release = mmc_ext_csd_release,
20497 diff -urNp linux-2.6.31.1/drivers/mtd/devices/doc2000.c linux-2.6.31.1/drivers/mtd/devices/doc2000.c
20498 --- linux-2.6.31.1/drivers/mtd/devices/doc2000.c 2009-09-24 11:45:25.000000000 -0400
20499 +++ linux-2.6.31.1/drivers/mtd/devices/doc2000.c 2009-10-01 20:12:43.000000000 -0400
20500 @@ -776,7 +776,7 @@ static int doc_write(struct mtd_info *mt
20501
20502 /* The ECC will not be calculated correctly if less than 512 is written */
20503 /* DBB-
20504 - if (len != 0x200 && eccbuf)
20505 + if (len != 0x200)
20506 printk(KERN_WARNING
20507 "ECC needs a full sector write (adr: %lx size %lx)\n",
20508 (long) to, (long) len);
20509 diff -urNp linux-2.6.31.1/drivers/mtd/devices/doc2001.c linux-2.6.31.1/drivers/mtd/devices/doc2001.c
20510 --- linux-2.6.31.1/drivers/mtd/devices/doc2001.c 2009-09-24 11:45:25.000000000 -0400
20511 +++ linux-2.6.31.1/drivers/mtd/devices/doc2001.c 2009-10-01 20:12:43.000000000 -0400
20512 @@ -395,6 +395,8 @@ static int doc_read (struct mtd_info *mt
20513 /* Don't allow read past end of device */
20514 if (from >= this->totlen)
20515 return -EINVAL;
20516 + if (!len)
20517 + return -EINVAL;
20518
20519 /* Don't allow a single read to cross a 512-byte block boundary */
20520 if (from + len > ((from | 0x1ff) + 1))
20521 diff -urNp linux-2.6.31.1/drivers/mtd/ubi/build.c linux-2.6.31.1/drivers/mtd/ubi/build.c
20522 --- linux-2.6.31.1/drivers/mtd/ubi/build.c 2009-09-24 11:45:25.000000000 -0400
20523 +++ linux-2.6.31.1/drivers/mtd/ubi/build.c 2009-10-01 20:12:43.000000000 -0400
20524 @@ -1257,7 +1257,7 @@ static int __init bytes_str_to_int(const
20525 unsigned long result;
20526
20527 result = simple_strtoul(str, &endp, 0);
20528 - if (str == endp || result < 0) {
20529 + if (str == endp) {
20530 printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
20531 str);
20532 return -EINVAL;
20533 diff -urNp linux-2.6.31.1/drivers/net/irda/vlsi_ir.c linux-2.6.31.1/drivers/net/irda/vlsi_ir.c
20534 --- linux-2.6.31.1/drivers/net/irda/vlsi_ir.c 2009-09-24 11:45:25.000000000 -0400
20535 +++ linux-2.6.31.1/drivers/net/irda/vlsi_ir.c 2009-10-01 20:12:43.000000000 -0400
20536 @@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
20537 /* no race - tx-ring already empty */
20538 vlsi_set_baud(idev, iobase);
20539 netif_wake_queue(ndev);
20540 - }
20541 - else
20542 - ;
20543 + } else {
20544 /* keep the speed change pending like it would
20545 * for any len>0 packet. tx completion interrupt
20546 * will apply it when the tx ring becomes empty.
20547 */
20548 + }
20549 spin_unlock_irqrestore(&idev->lock, flags);
20550 dev_kfree_skb_any(skb);
20551 return 0;
20552 diff -urNp linux-2.6.31.1/drivers/net/pcnet32.c linux-2.6.31.1/drivers/net/pcnet32.c
20553 --- linux-2.6.31.1/drivers/net/pcnet32.c 2009-09-24 11:45:25.000000000 -0400
20554 +++ linux-2.6.31.1/drivers/net/pcnet32.c 2009-10-01 20:12:43.000000000 -0400
20555 @@ -78,7 +78,7 @@ static int cards_found;
20556 /*
20557 * VLB I/O addresses
20558 */
20559 -static unsigned int pcnet32_portlist[] __initdata =
20560 +static unsigned int pcnet32_portlist[] __devinitdata =
20561 { 0x300, 0x320, 0x340, 0x360, 0 };
20562
20563 static int pcnet32_debug = 0;
20564 diff -urNp linux-2.6.31.1/drivers/net/tg3.h linux-2.6.31.1/drivers/net/tg3.h
20565 --- linux-2.6.31.1/drivers/net/tg3.h 2009-09-24 11:45:25.000000000 -0400
20566 +++ linux-2.6.31.1/drivers/net/tg3.h 2009-10-01 20:12:43.000000000 -0400
20567 @@ -89,6 +89,7 @@
20568 #define CHIPREV_ID_5750_A0 0x4000
20569 #define CHIPREV_ID_5750_A1 0x4001
20570 #define CHIPREV_ID_5750_A3 0x4003
20571 +#define CHIPREV_ID_5750_C1 0x4201
20572 #define CHIPREV_ID_5750_C2 0x4202
20573 #define CHIPREV_ID_5752_A0_HW 0x5000
20574 #define CHIPREV_ID_5752_A0 0x6000
20575 diff -urNp linux-2.6.31.1/drivers/net/usb/hso.c linux-2.6.31.1/drivers/net/usb/hso.c
20576 --- linux-2.6.31.1/drivers/net/usb/hso.c 2009-09-24 11:45:25.000000000 -0400
20577 +++ linux-2.6.31.1/drivers/net/usb/hso.c 2009-10-01 20:12:43.000000000 -0400
20578 @@ -258,7 +258,7 @@ struct hso_serial {
20579
20580 /* from usb_serial_port */
20581 struct tty_struct *tty;
20582 - int open_count;
20583 + atomic_t open_count;
20584 spinlock_t serial_lock;
20585
20586 int (*write_data) (struct hso_serial *serial);
20587 @@ -1179,7 +1179,7 @@ static void put_rxbuf_data_and_resubmit_
20588 struct urb *urb;
20589
20590 urb = serial->rx_urb[0];
20591 - if (serial->open_count > 0) {
20592 + if (atomic_read(&serial->open_count) > 0) {
20593 count = put_rxbuf_data(urb, serial);
20594 if (count == -1)
20595 return;
20596 @@ -1215,7 +1215,7 @@ static void hso_std_serial_read_bulk_cal
20597 DUMP1(urb->transfer_buffer, urb->actual_length);
20598
20599 /* Anyone listening? */
20600 - if (serial->open_count == 0)
20601 + if (atomic_read(&serial->open_count) == 0)
20602 return;
20603
20604 if (status == 0) {
20605 @@ -1310,8 +1310,7 @@ static int hso_serial_open(struct tty_st
20606 spin_unlock_irq(&serial->serial_lock);
20607
20608 /* check for port already opened, if not set the termios */
20609 - serial->open_count++;
20610 - if (serial->open_count == 1) {
20611 + if (atomic_inc_return(&serial->open_count) == 1) {
20612 tty->low_latency = 1;
20613 serial->rx_state = RX_IDLE;
20614 /* Force default termio settings */
20615 @@ -1324,7 +1323,7 @@ static int hso_serial_open(struct tty_st
20616 result = hso_start_serial_device(serial->parent, GFP_KERNEL);
20617 if (result) {
20618 hso_stop_serial_device(serial->parent);
20619 - serial->open_count--;
20620 + atomic_dec(&serial->open_count);
20621 kref_put(&serial->parent->ref, hso_serial_ref_free);
20622 }
20623 } else {
20624 @@ -1361,10 +1360,10 @@ static void hso_serial_close(struct tty_
20625
20626 /* reset the rts and dtr */
20627 /* do the actual close */
20628 - serial->open_count--;
20629 + atomic_dec(&serial->open_count);
20630 kref_put(&serial->parent->ref, hso_serial_ref_free);
20631 - if (serial->open_count <= 0) {
20632 - serial->open_count = 0;
20633 + if (atomic_read(&serial->open_count) <= 0) {
20634 + atomic_set(&serial->open_count, 0);
20635 spin_lock_irq(&serial->serial_lock);
20636 if (serial->tty == tty) {
20637 serial->tty->driver_data = NULL;
20638 @@ -1444,7 +1443,7 @@ static void hso_serial_set_termios(struc
20639
20640 /* the actual setup */
20641 spin_lock_irqsave(&serial->serial_lock, flags);
20642 - if (serial->open_count)
20643 + if (atomic_read(&serial->open_count))
20644 _hso_serial_set_termios(tty, old);
20645 else
20646 tty->termios = old;
20647 @@ -3087,7 +3086,7 @@ static int hso_resume(struct usb_interfa
20648 /* Start all serial ports */
20649 for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
20650 if (serial_table[i] && (serial_table[i]->interface == iface)) {
20651 - if (dev2ser(serial_table[i])->open_count) {
20652 + if (atomic_read(&dev2ser(serial_table[i])->open_count)) {
20653 result =
20654 hso_start_serial_device(serial_table[i], GFP_NOIO);
20655 hso_kick_transmit(dev2ser(serial_table[i]));
20656 diff -urNp linux-2.6.31.1/drivers/oprofile/buffer_sync.c linux-2.6.31.1/drivers/oprofile/buffer_sync.c
20657 --- linux-2.6.31.1/drivers/oprofile/buffer_sync.c 2009-09-24 11:45:25.000000000 -0400
20658 +++ linux-2.6.31.1/drivers/oprofile/buffer_sync.c 2009-10-01 20:12:43.000000000 -0400
20659 @@ -341,7 +341,7 @@ static void add_data(struct op_entry *en
20660 if (cookie == NO_COOKIE)
20661 offset = pc;
20662 if (cookie == INVALID_COOKIE) {
20663 - atomic_inc(&oprofile_stats.sample_lost_no_mapping);
20664 + atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
20665 offset = pc;
20666 }
20667 if (cookie != last_cookie) {
20668 @@ -385,14 +385,14 @@ add_sample(struct mm_struct *mm, struct
20669 /* add userspace sample */
20670
20671 if (!mm) {
20672 - atomic_inc(&oprofile_stats.sample_lost_no_mm);
20673 + atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mm);
20674 return 0;
20675 }
20676
20677 cookie = lookup_dcookie(mm, s->eip, &offset);
20678
20679 if (cookie == INVALID_COOKIE) {
20680 - atomic_inc(&oprofile_stats.sample_lost_no_mapping);
20681 + atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
20682 return 0;
20683 }
20684
20685 @@ -561,7 +561,7 @@ void sync_buffer(int cpu)
20686 /* ignore backtraces if failed to add a sample */
20687 if (state == sb_bt_start) {
20688 state = sb_bt_ignore;
20689 - atomic_inc(&oprofile_stats.bt_lost_no_mapping);
20690 + atomic_inc_unchecked(&oprofile_stats.bt_lost_no_mapping);
20691 }
20692 }
20693 release_mm(mm);
20694 diff -urNp linux-2.6.31.1/drivers/oprofile/event_buffer.c linux-2.6.31.1/drivers/oprofile/event_buffer.c
20695 --- linux-2.6.31.1/drivers/oprofile/event_buffer.c 2009-09-24 11:45:25.000000000 -0400
20696 +++ linux-2.6.31.1/drivers/oprofile/event_buffer.c 2009-10-01 20:12:43.000000000 -0400
20697 @@ -42,7 +42,7 @@ static atomic_t buffer_ready = ATOMIC_IN
20698 void add_event_entry(unsigned long value)
20699 {
20700 if (buffer_pos == buffer_size) {
20701 - atomic_inc(&oprofile_stats.event_lost_overflow);
20702 + atomic_inc_unchecked(&oprofile_stats.event_lost_overflow);
20703 return;
20704 }
20705
20706 diff -urNp linux-2.6.31.1/drivers/oprofile/oprofilefs.c linux-2.6.31.1/drivers/oprofile/oprofilefs.c
20707 --- linux-2.6.31.1/drivers/oprofile/oprofilefs.c 2009-09-24 11:45:25.000000000 -0400
20708 +++ linux-2.6.31.1/drivers/oprofile/oprofilefs.c 2009-10-01 20:12:43.000000000 -0400
20709 @@ -35,7 +35,7 @@ static struct inode *oprofilefs_get_inod
20710 }
20711
20712
20713 -static struct super_operations s_ops = {
20714 +static const struct super_operations s_ops = {
20715 .statfs = simple_statfs,
20716 .drop_inode = generic_delete_inode,
20717 };
20718 @@ -187,7 +187,7 @@ static const struct file_operations atom
20719
20720
20721 int oprofilefs_create_ro_atomic(struct super_block *sb, struct dentry *root,
20722 - char const *name, atomic_t *val)
20723 + char const *name, atomic_unchecked_t *val)
20724 {
20725 struct dentry *d = __oprofilefs_create_file(sb, root, name,
20726 &atomic_ro_fops, 0444);
20727 diff -urNp linux-2.6.31.1/drivers/oprofile/oprofile_stats.c linux-2.6.31.1/drivers/oprofile/oprofile_stats.c
20728 --- linux-2.6.31.1/drivers/oprofile/oprofile_stats.c 2009-09-24 11:45:25.000000000 -0400
20729 +++ linux-2.6.31.1/drivers/oprofile/oprofile_stats.c 2009-10-01 20:12:43.000000000 -0400
20730 @@ -30,10 +30,10 @@ void oprofile_reset_stats(void)
20731 cpu_buf->sample_invalid_eip = 0;
20732 }
20733
20734 - atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
20735 - atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
20736 - atomic_set(&oprofile_stats.event_lost_overflow, 0);
20737 - atomic_set(&oprofile_stats.bt_lost_no_mapping, 0);
20738 + atomic_set_unchecked(&oprofile_stats.sample_lost_no_mm, 0);
20739 + atomic_set_unchecked(&oprofile_stats.sample_lost_no_mapping, 0);
20740 + atomic_set_unchecked(&oprofile_stats.event_lost_overflow, 0);
20741 + atomic_set_unchecked(&oprofile_stats.bt_lost_no_mapping, 0);
20742 }
20743
20744
20745 diff -urNp linux-2.6.31.1/drivers/oprofile/oprofile_stats.h linux-2.6.31.1/drivers/oprofile/oprofile_stats.h
20746 --- linux-2.6.31.1/drivers/oprofile/oprofile_stats.h 2009-09-24 11:45:25.000000000 -0400
20747 +++ linux-2.6.31.1/drivers/oprofile/oprofile_stats.h 2009-10-01 20:12:43.000000000 -0400
20748 @@ -13,10 +13,10 @@
20749 #include <asm/atomic.h>
20750
20751 struct oprofile_stat_struct {
20752 - atomic_t sample_lost_no_mm;
20753 - atomic_t sample_lost_no_mapping;
20754 - atomic_t bt_lost_no_mapping;
20755 - atomic_t event_lost_overflow;
20756 + atomic_unchecked_t sample_lost_no_mm;
20757 + atomic_unchecked_t sample_lost_no_mapping;
20758 + atomic_unchecked_t bt_lost_no_mapping;
20759 + atomic_unchecked_t event_lost_overflow;
20760 };
20761
20762 extern struct oprofile_stat_struct oprofile_stats;
20763 diff -urNp linux-2.6.31.1/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.31.1/drivers/pci/hotplug/cpqphp_nvram.c
20764 --- linux-2.6.31.1/drivers/pci/hotplug/cpqphp_nvram.c 2009-09-24 11:45:25.000000000 -0400
20765 +++ linux-2.6.31.1/drivers/pci/hotplug/cpqphp_nvram.c 2009-10-01 20:12:43.000000000 -0400
20766 @@ -428,9 +428,13 @@ static u32 store_HRT (void __iomem *rom_
20767
20768 void compaq_nvram_init (void __iomem *rom_start)
20769 {
20770 +
20771 +#ifndef CONFIG_PAX_KERNEXEC
20772 if (rom_start) {
20773 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
20774 }
20775 +#endif
20776 +
20777 dbg("int15 entry = %p\n", compaq_int15_entry_point);
20778
20779 /* initialize our int15 lock */
20780 diff -urNp linux-2.6.31.1/drivers/pci/pcie/portdrv_pci.c linux-2.6.31.1/drivers/pci/pcie/portdrv_pci.c
20781 --- linux-2.6.31.1/drivers/pci/pcie/portdrv_pci.c 2009-09-24 11:45:25.000000000 -0400
20782 +++ linux-2.6.31.1/drivers/pci/pcie/portdrv_pci.c 2009-10-01 20:12:43.000000000 -0400
20783 @@ -249,7 +249,7 @@ static void pcie_portdrv_err_resume(stru
20784 static const struct pci_device_id port_pci_ids[] = { {
20785 /* handle any PCI-Express port */
20786 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
20787 - }, { /* end: all zeroes */ }
20788 + }, { 0, 0, 0, 0, 0, 0, 0 }
20789 };
20790 MODULE_DEVICE_TABLE(pci, port_pci_ids);
20791
20792 diff -urNp linux-2.6.31.1/drivers/pci/proc.c linux-2.6.31.1/drivers/pci/proc.c
20793 --- linux-2.6.31.1/drivers/pci/proc.c 2009-09-24 11:45:25.000000000 -0400
20794 +++ linux-2.6.31.1/drivers/pci/proc.c 2009-10-01 20:12:43.000000000 -0400
20795 @@ -480,7 +480,16 @@ static const struct file_operations proc
20796 static int __init pci_proc_init(void)
20797 {
20798 struct pci_dev *dev = NULL;
20799 +
20800 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
20801 +#ifdef CONFIG_GRKERNSEC_PROC_USER
20802 + proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
20803 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
20804 + proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
20805 +#endif
20806 +#else
20807 proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
20808 +#endif
20809 proc_create("devices", 0, proc_bus_pci_dir,
20810 &proc_bus_pci_dev_operations);
20811 proc_initialized = 1;
20812 diff -urNp linux-2.6.31.1/drivers/pcmcia/ti113x.h linux-2.6.31.1/drivers/pcmcia/ti113x.h
20813 --- linux-2.6.31.1/drivers/pcmcia/ti113x.h 2009-09-24 11:45:25.000000000 -0400
20814 +++ linux-2.6.31.1/drivers/pcmcia/ti113x.h 2009-10-01 20:12:43.000000000 -0400
20815 @@ -903,7 +903,7 @@ static struct pci_device_id ene_tune_tbl
20816 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
20817 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
20818
20819 - {}
20820 + { 0, 0, 0, 0, 0, 0, 0 }
20821 };
20822
20823 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
20824 diff -urNp linux-2.6.31.1/drivers/pcmcia/yenta_socket.c linux-2.6.31.1/drivers/pcmcia/yenta_socket.c
20825 --- linux-2.6.31.1/drivers/pcmcia/yenta_socket.c 2009-09-24 11:45:25.000000000 -0400
20826 +++ linux-2.6.31.1/drivers/pcmcia/yenta_socket.c 2009-10-01 20:12:43.000000000 -0400
20827 @@ -1366,7 +1366,7 @@ static struct pci_device_id yenta_table
20828
20829 /* match any cardbus bridge */
20830 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
20831 - { /* all zeroes */ }
20832 + { 0, 0, 0, 0, 0, 0, 0 }
20833 };
20834 MODULE_DEVICE_TABLE(pci, yenta_table);
20835
20836 diff -urNp linux-2.6.31.1/drivers/pnp/pnpbios/bioscalls.c linux-2.6.31.1/drivers/pnp/pnpbios/bioscalls.c
20837 --- linux-2.6.31.1/drivers/pnp/pnpbios/bioscalls.c 2009-09-24 11:45:25.000000000 -0400
20838 +++ linux-2.6.31.1/drivers/pnp/pnpbios/bioscalls.c 2009-10-01 20:12:43.000000000 -0400
20839 @@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
20840 set_limit(gdt[(selname) >> 3], size); \
20841 } while(0)
20842
20843 -static struct desc_struct bad_bios_desc;
20844 +static struct desc_struct bad_bios_desc __read_only;
20845
20846 /*
20847 * At some point we want to use this stack frame pointer to unwind
20848 @@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
20849 struct desc_struct save_desc_40;
20850 int cpu;
20851
20852 +#ifdef CONFIG_PAX_KERNEXEC
20853 + unsigned long cr0;
20854 +#endif
20855 +
20856 /*
20857 * PnP BIOSes are generally not terribly re-entrant.
20858 * Also, don't rely on them to save everything correctly.
20859 @@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
20860
20861 cpu = get_cpu();
20862 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
20863 +
20864 +#ifdef CONFIG_PAX_KERNEXEC
20865 + pax_open_kernel(cr0);
20866 +#endif
20867 +
20868 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
20869
20870 +#ifdef CONFIG_PAX_KERNEXEC
20871 + pax_close_kernel(cr0);
20872 +#endif
20873 +
20874 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
20875 spin_lock_irqsave(&pnp_bios_lock, flags);
20876
20877 @@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
20878 :"memory");
20879 spin_unlock_irqrestore(&pnp_bios_lock, flags);
20880
20881 +#ifdef CONFIG_PAX_KERNEXEC
20882 + pax_open_kernel(cr0);
20883 +#endif
20884 +
20885 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
20886 +
20887 +#ifdef CONFIG_PAX_KERNEXEC
20888 + pax_close_kernel(cr0);
20889 +#endif
20890 +
20891 put_cpu();
20892
20893 /* If we get here and this is set then the PnP BIOS faulted on us. */
20894 @@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
20895 return status;
20896 }
20897
20898 -void pnpbios_calls_init(union pnp_bios_install_struct *header)
20899 +void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
20900 {
20901 int i;
20902
20903 +#ifdef CONFIG_PAX_KERNEXEC
20904 + unsigned long cr0;
20905 +#endif
20906 +
20907 spin_lock_init(&pnp_bios_lock);
20908 pnp_bios_callpoint.offset = header->fields.pm16offset;
20909 pnp_bios_callpoint.segment = PNP_CS16;
20910
20911 +#ifdef CONFIG_PAX_KERNEXEC
20912 + pax_open_kernel(cr0);
20913 +#endif
20914 +
20915 bad_bios_desc.a = 0;
20916 - bad_bios_desc.b = 0x00409200;
20917 + bad_bios_desc.b = 0x00409300;
20918
20919 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
20920 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
20921 @@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
20922 set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
20923 __va(header->fields.pm16dseg));
20924 }
20925 +
20926 +#ifdef CONFIG_PAX_KERNEXEC
20927 + pax_close_kernel(cr0);
20928 +#endif
20929 +
20930 }
20931 diff -urNp linux-2.6.31.1/drivers/pnp/quirks.c linux-2.6.31.1/drivers/pnp/quirks.c
20932 --- linux-2.6.31.1/drivers/pnp/quirks.c 2009-09-24 11:45:25.000000000 -0400
20933 +++ linux-2.6.31.1/drivers/pnp/quirks.c 2009-10-01 20:12:43.000000000 -0400
20934 @@ -327,7 +327,7 @@ static struct pnp_fixup pnp_fixups[] = {
20935 /* PnP resources that might overlap PCI BARs */
20936 {"PNP0c01", quirk_system_pci_resources},
20937 {"PNP0c02", quirk_system_pci_resources},
20938 - {""}
20939 + {"", NULL}
20940 };
20941
20942 void pnp_fixup_device(struct pnp_dev *dev)
20943 diff -urNp linux-2.6.31.1/drivers/pnp/resource.c linux-2.6.31.1/drivers/pnp/resource.c
20944 --- linux-2.6.31.1/drivers/pnp/resource.c 2009-09-24 11:45:25.000000000 -0400
20945 +++ linux-2.6.31.1/drivers/pnp/resource.c 2009-10-01 20:12:43.000000000 -0400
20946 @@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
20947 return 1;
20948
20949 /* check if the resource is valid */
20950 - if (*irq < 0 || *irq > 15)
20951 + if (*irq > 15)
20952 return 0;
20953
20954 /* check if the resource is reserved */
20955 @@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
20956 return 1;
20957
20958 /* check if the resource is valid */
20959 - if (*dma < 0 || *dma == 4 || *dma > 7)
20960 + if (*dma == 4 || *dma > 7)
20961 return 0;
20962
20963 /* check if the resource is reserved */
20964 diff -urNp linux-2.6.31.1/drivers/s390/cio/qdio_debug.c linux-2.6.31.1/drivers/s390/cio/qdio_debug.c
20965 --- linux-2.6.31.1/drivers/s390/cio/qdio_debug.c 2009-09-24 11:45:25.000000000 -0400
20966 +++ linux-2.6.31.1/drivers/s390/cio/qdio_debug.c 2009-10-01 20:12:43.000000000 -0400
20967 @@ -144,7 +144,7 @@ static void remove_debugfs_entry(struct
20968 }
20969 }
20970
20971 -static struct file_operations debugfs_fops = {
20972 +static const struct file_operations debugfs_fops = {
20973 .owner = THIS_MODULE,
20974 .open = qstat_seq_open,
20975 .read = seq_read,
20976 diff -urNp linux-2.6.31.1/drivers/s390/cio/qdio_perf.c linux-2.6.31.1/drivers/s390/cio/qdio_perf.c
20977 --- linux-2.6.31.1/drivers/s390/cio/qdio_perf.c 2009-09-24 11:45:25.000000000 -0400
20978 +++ linux-2.6.31.1/drivers/s390/cio/qdio_perf.c 2009-10-01 20:12:43.000000000 -0400
20979 @@ -84,7 +84,7 @@ static int qdio_perf_seq_open(struct ino
20980 return single_open(filp, qdio_perf_proc_show, NULL);
20981 }
20982
20983 -static struct file_operations qdio_perf_proc_fops = {
20984 +static const struct file_operations qdio_perf_proc_fops = {
20985 .owner = THIS_MODULE,
20986 .open = qdio_perf_seq_open,
20987 .read = seq_read,
20988 diff -urNp linux-2.6.31.1/drivers/scsi/libfc/fc_exch.c linux-2.6.31.1/drivers/scsi/libfc/fc_exch.c
20989 --- linux-2.6.31.1/drivers/scsi/libfc/fc_exch.c 2009-09-24 11:45:25.000000000 -0400
20990 +++ linux-2.6.31.1/drivers/scsi/libfc/fc_exch.c 2009-10-01 20:12:43.000000000 -0400
20991 @@ -73,12 +73,12 @@ struct fc_exch_mgr {
20992 * all together if not used XXX
20993 */
20994 struct {
20995 - atomic_t no_free_exch;
20996 - atomic_t no_free_exch_xid;
20997 - atomic_t xid_not_found;
20998 - atomic_t xid_busy;
20999 - atomic_t seq_not_found;
21000 - atomic_t non_bls_resp;
21001 + atomic_unchecked_t no_free_exch;
21002 + atomic_unchecked_t no_free_exch_xid;
21003 + atomic_unchecked_t xid_not_found;
21004 + atomic_unchecked_t xid_busy;
21005 + atomic_unchecked_t seq_not_found;
21006 + atomic_unchecked_t non_bls_resp;
21007 } stats;
21008 struct fc_exch **exches; /* for exch pointers indexed by xid */
21009 };
21010 @@ -523,7 +523,7 @@ struct fc_exch *fc_exch_alloc(struct fc_
21011 /* allocate memory for exchange */
21012 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
21013 if (!ep) {
21014 - atomic_inc(&mp->stats.no_free_exch);
21015 + atomic_inc_unchecked(&mp->stats.no_free_exch);
21016 goto out;
21017 }
21018 memset(ep, 0, sizeof(*ep));
21019 @@ -568,7 +568,7 @@ out:
21020 return ep;
21021 err:
21022 spin_unlock_bh(&mp->em_lock);
21023 - atomic_inc(&mp->stats.no_free_exch_xid);
21024 + atomic_inc_unchecked(&mp->stats.no_free_exch_xid);
21025 mempool_free(ep, mp->ep_pool);
21026 return NULL;
21027 }
21028 @@ -671,7 +671,7 @@ static enum fc_pf_rjt_reason fc_seq_look
21029 xid = ntohs(fh->fh_ox_id); /* we originated exch */
21030 ep = fc_exch_find(mp, xid);
21031 if (!ep) {
21032 - atomic_inc(&mp->stats.xid_not_found);
21033 + atomic_inc_unchecked(&mp->stats.xid_not_found);
21034 reject = FC_RJT_OX_ID;
21035 goto out;
21036 }
21037 @@ -701,7 +701,7 @@ static enum fc_pf_rjt_reason fc_seq_look
21038 ep = fc_exch_find(mp, xid);
21039 if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) {
21040 if (ep) {
21041 - atomic_inc(&mp->stats.xid_busy);
21042 + atomic_inc_unchecked(&mp->stats.xid_busy);
21043 reject = FC_RJT_RX_ID;
21044 goto rel;
21045 }
21046 @@ -712,7 +712,7 @@ static enum fc_pf_rjt_reason fc_seq_look
21047 }
21048 xid = ep->xid; /* get our XID */
21049 } else if (!ep) {
21050 - atomic_inc(&mp->stats.xid_not_found);
21051 + atomic_inc_unchecked(&mp->stats.xid_not_found);
21052 reject = FC_RJT_RX_ID; /* XID not found */
21053 goto out;
21054 }
21055 @@ -733,7 +733,7 @@ static enum fc_pf_rjt_reason fc_seq_look
21056 } else {
21057 sp = &ep->seq;
21058 if (sp->id != fh->fh_seq_id) {
21059 - atomic_inc(&mp->stats.seq_not_found);
21060 + atomic_inc_unchecked(&mp->stats.seq_not_found);
21061 reject = FC_RJT_SEQ_ID; /* sequence/exch should exist */
21062 goto rel;
21063 }
21064 @@ -1145,22 +1145,22 @@ static void fc_exch_recv_seq_resp(struct
21065
21066 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id));
21067 if (!ep) {
21068 - atomic_inc(&mp->stats.xid_not_found);
21069 + atomic_inc_unchecked(&mp->stats.xid_not_found);
21070 goto out;
21071 }
21072 if (ep->esb_stat & ESB_ST_COMPLETE) {
21073 - atomic_inc(&mp->stats.xid_not_found);
21074 + atomic_inc_unchecked(&mp->stats.xid_not_found);
21075 goto out;
21076 }
21077 if (ep->rxid == FC_XID_UNKNOWN)
21078 ep->rxid = ntohs(fh->fh_rx_id);
21079 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) {
21080 - atomic_inc(&mp->stats.xid_not_found);
21081 + atomic_inc_unchecked(&mp->stats.xid_not_found);
21082 goto rel;
21083 }
21084 if (ep->did != ntoh24(fh->fh_s_id) &&
21085 ep->did != FC_FID_FLOGI) {
21086 - atomic_inc(&mp->stats.xid_not_found);
21087 + atomic_inc_unchecked(&mp->stats.xid_not_found);
21088 goto rel;
21089 }
21090 sof = fr_sof(fp);
21091 @@ -1171,7 +1171,7 @@ static void fc_exch_recv_seq_resp(struct
21092 } else {
21093 sp = &ep->seq;
21094 if (sp->id != fh->fh_seq_id) {
21095 - atomic_inc(&mp->stats.seq_not_found);
21096 + atomic_inc_unchecked(&mp->stats.seq_not_found);
21097 goto rel;
21098 }
21099 }
21100 @@ -1230,10 +1230,10 @@ static void fc_exch_recv_resp(struct fc_
21101
21102 sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */
21103 if (!sp) {
21104 - atomic_inc(&mp->stats.xid_not_found);
21105 + atomic_inc_unchecked(&mp->stats.xid_not_found);
21106 FC_EM_DBG(mp, "seq lookup failed\n");
21107 } else {
21108 - atomic_inc(&mp->stats.non_bls_resp);
21109 + atomic_inc_unchecked(&mp->stats.non_bls_resp);
21110 FC_EM_DBG(mp, "non-BLS response to sequence");
21111 }
21112 fc_frame_free(fp);
21113 diff -urNp linux-2.6.31.1/drivers/scsi/scsi_logging.h linux-2.6.31.1/drivers/scsi/scsi_logging.h
21114 --- linux-2.6.31.1/drivers/scsi/scsi_logging.h 2009-09-24 11:45:25.000000000 -0400
21115 +++ linux-2.6.31.1/drivers/scsi/scsi_logging.h 2009-10-01 20:12:43.000000000 -0400
21116 @@ -51,7 +51,7 @@ do { \
21117 } while (0); \
21118 } while (0)
21119 #else
21120 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
21121 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
21122 #endif /* CONFIG_SCSI_LOGGING */
21123
21124 /*
21125 diff -urNp linux-2.6.31.1/drivers/scsi/sg.c linux-2.6.31.1/drivers/scsi/sg.c
21126 --- linux-2.6.31.1/drivers/scsi/sg.c 2009-09-24 11:45:25.000000000 -0400
21127 +++ linux-2.6.31.1/drivers/scsi/sg.c 2009-10-01 20:12:43.000000000 -0400
21128 @@ -1185,7 +1185,7 @@ sg_vma_fault(struct vm_area_struct *vma,
21129 return VM_FAULT_SIGBUS;
21130 }
21131
21132 -static struct vm_operations_struct sg_mmap_vm_ops = {
21133 +static const struct vm_operations_struct sg_mmap_vm_ops = {
21134 .fault = sg_vma_fault,
21135 };
21136
21137 @@ -1317,7 +1317,7 @@ static void sg_rq_end_io(struct request
21138 }
21139 }
21140
21141 -static struct file_operations sg_fops = {
21142 +static const struct file_operations sg_fops = {
21143 .owner = THIS_MODULE,
21144 .read = sg_read,
21145 .write = sg_write,
21146 @@ -2194,8 +2194,11 @@ static int sg_proc_seq_show_int(struct s
21147 static int sg_proc_single_open_adio(struct inode *inode, struct file *file);
21148 static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer,
21149 size_t count, loff_t *off);
21150 -static struct file_operations adio_fops = {
21151 - /* .owner, .read and .llseek added in sg_proc_init() */
21152 +
21153 +static const struct file_operations adio_fops = {
21154 + .owner = THIS_MODULE,
21155 + .read = seq_read,
21156 + .llseek = seq_lseek,
21157 .open = sg_proc_single_open_adio,
21158 .write = sg_proc_write_adio,
21159 .release = single_release,
21160 @@ -2204,7 +2207,10 @@ static struct file_operations adio_fops
21161 static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
21162 static ssize_t sg_proc_write_dressz(struct file *filp,
21163 const char __user *buffer, size_t count, loff_t *off);
21164 -static struct file_operations dressz_fops = {
21165 +static const struct file_operations dressz_fops = {
21166 + .owner = THIS_MODULE,
21167 + .read = seq_read,
21168 + .llseek = seq_lseek,
21169 .open = sg_proc_single_open_dressz,
21170 .write = sg_proc_write_dressz,
21171 .release = single_release,
21172 @@ -2212,14 +2218,20 @@ static struct file_operations dressz_fop
21173
21174 static int sg_proc_seq_show_version(struct seq_file *s, void *v);
21175 static int sg_proc_single_open_version(struct inode *inode, struct file *file);
21176 -static struct file_operations version_fops = {
21177 +static const struct file_operations version_fops = {
21178 + .owner = THIS_MODULE,
21179 + .read = seq_read,
21180 + .llseek = seq_lseek,
21181 .open = sg_proc_single_open_version,
21182 .release = single_release,
21183 };
21184
21185 static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v);
21186 static int sg_proc_single_open_devhdr(struct inode *inode, struct file *file);
21187 -static struct file_operations devhdr_fops = {
21188 +static const struct file_operations devhdr_fops = {
21189 + .owner = THIS_MODULE,
21190 + .read = seq_read,
21191 + .llseek = seq_lseek,
21192 .open = sg_proc_single_open_devhdr,
21193 .release = single_release,
21194 };
21195 @@ -2229,11 +2241,14 @@ static int sg_proc_open_dev(struct inode
21196 static void * dev_seq_start(struct seq_file *s, loff_t *pos);
21197 static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos);
21198 static void dev_seq_stop(struct seq_file *s, void *v);
21199 -static struct file_operations dev_fops = {
21200 +static const struct file_operations dev_fops = {
21201 + .owner = THIS_MODULE,
21202 + .read = seq_read,
21203 + .llseek = seq_lseek,
21204 .open = sg_proc_open_dev,
21205 .release = seq_release,
21206 };
21207 -static struct seq_operations dev_seq_ops = {
21208 +static const struct seq_operations dev_seq_ops = {
21209 .start = dev_seq_start,
21210 .next = dev_seq_next,
21211 .stop = dev_seq_stop,
21212 @@ -2242,11 +2257,14 @@ static struct seq_operations dev_seq_ops
21213
21214 static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v);
21215 static int sg_proc_open_devstrs(struct inode *inode, struct file *file);
21216 -static struct file_operations devstrs_fops = {
21217 +static const struct file_operations devstrs_fops = {
21218 + .owner = THIS_MODULE,
21219 + .read = seq_read,
21220 + .llseek = seq_lseek,
21221 .open = sg_proc_open_devstrs,
21222 .release = seq_release,
21223 };
21224 -static struct seq_operations devstrs_seq_ops = {
21225 +static const struct seq_operations devstrs_seq_ops = {
21226 .start = dev_seq_start,
21227 .next = dev_seq_next,
21228 .stop = dev_seq_stop,
21229 @@ -2255,11 +2273,14 @@ static struct seq_operations devstrs_seq
21230
21231 static int sg_proc_seq_show_debug(struct seq_file *s, void *v);
21232 static int sg_proc_open_debug(struct inode *inode, struct file *file);
21233 -static struct file_operations debug_fops = {
21234 +static const struct file_operations debug_fops = {
21235 + .owner = THIS_MODULE,
21236 + .read = seq_read,
21237 + .llseek = seq_lseek,
21238 .open = sg_proc_open_debug,
21239 .release = seq_release,
21240 };
21241 -static struct seq_operations debug_seq_ops = {
21242 +static const struct seq_operations debug_seq_ops = {
21243 .start = dev_seq_start,
21244 .next = dev_seq_next,
21245 .stop = dev_seq_stop,
21246 @@ -2269,7 +2290,7 @@ static struct seq_operations debug_seq_o
21247
21248 struct sg_proc_leaf {
21249 const char * name;
21250 - struct file_operations * fops;
21251 + const struct file_operations * fops;
21252 };
21253
21254 static struct sg_proc_leaf sg_proc_leaf_arr[] = {
21255 @@ -2295,9 +2316,6 @@ sg_proc_init(void)
21256 for (k = 0; k < num_leaves; ++k) {
21257 leaf = &sg_proc_leaf_arr[k];
21258 mask = leaf->fops->write ? S_IRUGO | S_IWUSR : S_IRUGO;
21259 - leaf->fops->owner = THIS_MODULE;
21260 - leaf->fops->read = seq_read;
21261 - leaf->fops->llseek = seq_lseek;
21262 proc_create(leaf->name, mask, sg_proc_sgp, leaf->fops);
21263 }
21264 return 0;
21265 diff -urNp linux-2.6.31.1/drivers/serial/8250_pci.c linux-2.6.31.1/drivers/serial/8250_pci.c
21266 --- linux-2.6.31.1/drivers/serial/8250_pci.c 2009-09-24 11:45:25.000000000 -0400
21267 +++ linux-2.6.31.1/drivers/serial/8250_pci.c 2009-10-01 20:12:43.000000000 -0400
21268 @@ -3580,7 +3580,7 @@ static struct pci_device_id serial_pci_t
21269 PCI_ANY_ID, PCI_ANY_ID,
21270 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
21271 0xffff00, pbn_default },
21272 - { 0, }
21273 + { 0, 0, 0, 0, 0, 0, 0 }
21274 };
21275
21276 static struct pci_driver serial_pci_driver = {
21277 diff -urNp linux-2.6.31.1/drivers/spi/spidev.c linux-2.6.31.1/drivers/spi/spidev.c
21278 --- linux-2.6.31.1/drivers/spi/spidev.c 2009-09-24 11:45:25.000000000 -0400
21279 +++ linux-2.6.31.1/drivers/spi/spidev.c 2009-10-01 20:12:43.000000000 -0400
21280 @@ -537,7 +537,7 @@ static int spidev_release(struct inode *
21281 return status;
21282 }
21283
21284 -static struct file_operations spidev_fops = {
21285 +static const struct file_operations spidev_fops = {
21286 .owner = THIS_MODULE,
21287 /* REVISIT switch to aio primitives, so that userspace
21288 * gets more complete API coverage. It'll simplify things
21289 diff -urNp linux-2.6.31.1/drivers/staging/android/binder.c linux-2.6.31.1/drivers/staging/android/binder.c
21290 --- linux-2.6.31.1/drivers/staging/android/binder.c 2009-09-24 11:45:25.000000000 -0400
21291 +++ linux-2.6.31.1/drivers/staging/android/binder.c 2009-10-01 20:12:43.000000000 -0400
21292 @@ -2717,7 +2717,7 @@ static void binder_vma_close(struct vm_a
21293 binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
21294 }
21295
21296 -static struct vm_operations_struct binder_vm_ops = {
21297 +static const struct vm_operations_struct binder_vm_ops = {
21298 .open = binder_vma_open,
21299 .close = binder_vma_close,
21300 };
21301 diff -urNp linux-2.6.31.1/drivers/staging/b3dfg/b3dfg.c linux-2.6.31.1/drivers/staging/b3dfg/b3dfg.c
21302 --- linux-2.6.31.1/drivers/staging/b3dfg/b3dfg.c 2009-09-24 11:45:25.000000000 -0400
21303 +++ linux-2.6.31.1/drivers/staging/b3dfg/b3dfg.c 2009-10-01 20:12:43.000000000 -0400
21304 @@ -454,7 +454,7 @@ static int b3dfg_vma_fault(struct vm_are
21305 return VM_FAULT_NOPAGE;
21306 }
21307
21308 -static struct vm_operations_struct b3dfg_vm_ops = {
21309 +static const struct vm_operations_struct b3dfg_vm_ops = {
21310 .fault = b3dfg_vma_fault,
21311 };
21312
21313 @@ -854,7 +854,7 @@ static int b3dfg_mmap(struct file *filp,
21314 return r;
21315 }
21316
21317 -static struct file_operations b3dfg_fops = {
21318 +static const struct file_operations b3dfg_fops = {
21319 .owner = THIS_MODULE,
21320 .open = b3dfg_open,
21321 .release = b3dfg_release,
21322 diff -urNp linux-2.6.31.1/drivers/staging/comedi/comedi_fops.c linux-2.6.31.1/drivers/staging/comedi/comedi_fops.c
21323 --- linux-2.6.31.1/drivers/staging/comedi/comedi_fops.c 2009-09-24 11:45:25.000000000 -0400
21324 +++ linux-2.6.31.1/drivers/staging/comedi/comedi_fops.c 2009-10-01 20:12:43.000000000 -0400
21325 @@ -1370,7 +1370,7 @@ void comedi_unmap(struct vm_area_struct
21326 mutex_unlock(&dev->mutex);
21327 }
21328
21329 -static struct vm_operations_struct comedi_vm_ops = {
21330 +static const struct vm_operations_struct comedi_vm_ops = {
21331 .close = comedi_unmap,
21332 };
21333
21334 diff -urNp linux-2.6.31.1/drivers/staging/cpc-usb/cpc-usb_drv.c linux-2.6.31.1/drivers/staging/cpc-usb/cpc-usb_drv.c
21335 --- linux-2.6.31.1/drivers/staging/cpc-usb/cpc-usb_drv.c 2009-09-24 11:45:25.000000000 -0400
21336 +++ linux-2.6.31.1/drivers/staging/cpc-usb/cpc-usb_drv.c 2009-10-01 20:12:43.000000000 -0400
21337 @@ -104,7 +104,7 @@ static void cpcusb_read_interrupt_callba
21338
21339 static int cpcusb_setup_intrep(CPC_USB_T *card);
21340
21341 -static struct file_operations cpcusb_fops = {
21342 +static const struct file_operations cpcusb_fops = {
21343 /*
21344 * The owner field is part of the module-locking
21345 * mechanism. The idea is that the kernel knows
21346 diff -urNp linux-2.6.31.1/drivers/staging/epl/EplApiLinuxKernel.c linux-2.6.31.1/drivers/staging/epl/EplApiLinuxKernel.c
21347 --- linux-2.6.31.1/drivers/staging/epl/EplApiLinuxKernel.c 2009-09-24 11:45:25.000000000 -0400
21348 +++ linux-2.6.31.1/drivers/staging/epl/EplApiLinuxKernel.c 2009-10-01 20:12:43.000000000 -0400
21349 @@ -203,7 +203,7 @@ static int EplLinIoctl(struct inode *pDe
21350 module_init(EplLinInit);
21351 module_exit(EplLinExit);
21352
21353 -static struct file_operations EplLinFileOps_g = {
21354 +static const struct file_operations EplLinFileOps_g = {
21355 .owner = THIS_MODULE,
21356 .open = EplLinOpen,
21357 .release = EplLinRelease,
21358 diff -urNp linux-2.6.31.1/drivers/staging/go7007/go7007-v4l2.c linux-2.6.31.1/drivers/staging/go7007/go7007-v4l2.c
21359 --- linux-2.6.31.1/drivers/staging/go7007/go7007-v4l2.c 2009-09-24 11:45:25.000000000 -0400
21360 +++ linux-2.6.31.1/drivers/staging/go7007/go7007-v4l2.c 2009-10-01 20:12:43.000000000 -0400
21361 @@ -1717,7 +1717,7 @@ static int go7007_vm_fault(struct vm_are
21362 return 0;
21363 }
21364
21365 -static struct vm_operations_struct go7007_vm_ops = {
21366 +static const struct vm_operations_struct go7007_vm_ops = {
21367 .open = go7007_vm_open,
21368 .close = go7007_vm_close,
21369 .fault = go7007_vm_fault,
21370 diff -urNp linux-2.6.31.1/drivers/staging/panel/panel.c linux-2.6.31.1/drivers/staging/panel/panel.c
21371 --- linux-2.6.31.1/drivers/staging/panel/panel.c 2009-09-24 11:45:25.000000000 -0400
21372 +++ linux-2.6.31.1/drivers/staging/panel/panel.c 2009-10-01 20:12:43.000000000 -0400
21373 @@ -1263,7 +1263,7 @@ static int lcd_release(struct inode *ino
21374 return 0;
21375 }
21376
21377 -static struct file_operations lcd_fops = {
21378 +static const struct file_operations lcd_fops = {
21379 .write = lcd_write,
21380 .open = lcd_open,
21381 .release = lcd_release,
21382 @@ -1519,7 +1519,7 @@ static int keypad_release(struct inode *
21383 return 0;
21384 }
21385
21386 -static struct file_operations keypad_fops = {
21387 +static const struct file_operations keypad_fops = {
21388 .read = keypad_read, /* read */
21389 .open = keypad_open, /* open */
21390 .release = keypad_release, /* close */
21391 diff -urNp linux-2.6.31.1/drivers/staging/poch/poch.c linux-2.6.31.1/drivers/staging/poch/poch.c
21392 --- linux-2.6.31.1/drivers/staging/poch/poch.c 2009-09-24 11:45:25.000000000 -0400
21393 +++ linux-2.6.31.1/drivers/staging/poch/poch.c 2009-10-01 20:12:43.000000000 -0400
21394 @@ -1056,7 +1056,7 @@ static int poch_ioctl(struct inode *inod
21395 return 0;
21396 }
21397
21398 -static struct file_operations poch_fops = {
21399 +static const struct file_operations poch_fops = {
21400 .owner = THIS_MODULE,
21401 .open = poch_open,
21402 .release = poch_release,
21403 diff -urNp linux-2.6.31.1/drivers/staging/rtl8192su/ieee80211/proc.c linux-2.6.31.1/drivers/staging/rtl8192su/ieee80211/proc.c
21404 --- linux-2.6.31.1/drivers/staging/rtl8192su/ieee80211/proc.c 2009-09-24 11:45:25.000000000 -0400
21405 +++ linux-2.6.31.1/drivers/staging/rtl8192su/ieee80211/proc.c 2009-10-01 20:12:43.000000000 -0400
21406 @@ -87,7 +87,7 @@ static int c_show(struct seq_file *m, vo
21407 return 0;
21408 }
21409
21410 -static struct seq_operations crypto_seq_ops = {
21411 +static const struct seq_operations crypto_seq_ops = {
21412 .start = c_start,
21413 .next = c_next,
21414 .stop = c_stop,
21415 @@ -99,7 +99,7 @@ static int crypto_info_open(struct inode
21416 return seq_open(file, &crypto_seq_ops);
21417 }
21418
21419 -static struct file_operations proc_crypto_ops = {
21420 +static const struct file_operations proc_crypto_ops = {
21421 .open = crypto_info_open,
21422 .read = seq_read,
21423 .llseek = seq_lseek,
21424 diff -urNp linux-2.6.31.1/drivers/uio/uio.c linux-2.6.31.1/drivers/uio/uio.c
21425 --- linux-2.6.31.1/drivers/uio/uio.c 2009-09-24 11:45:25.000000000 -0400
21426 +++ linux-2.6.31.1/drivers/uio/uio.c 2009-10-01 20:12:43.000000000 -0400
21427 @@ -658,7 +658,7 @@ static int uio_vma_fault(struct vm_area_
21428 return 0;
21429 }
21430
21431 -static struct vm_operations_struct uio_vm_ops = {
21432 +static const struct vm_operations_struct uio_vm_ops = {
21433 .open = uio_vma_open,
21434 .close = uio_vma_close,
21435 .fault = uio_vma_fault,
21436 diff -urNp linux-2.6.31.1/drivers/usb/atm/usbatm.c linux-2.6.31.1/drivers/usb/atm/usbatm.c
21437 --- linux-2.6.31.1/drivers/usb/atm/usbatm.c 2009-09-24 11:45:25.000000000 -0400
21438 +++ linux-2.6.31.1/drivers/usb/atm/usbatm.c 2009-10-01 20:12:43.000000000 -0400
21439 @@ -333,7 +333,7 @@ static void usbatm_extract_one_cell(stru
21440 if (printk_ratelimit())
21441 atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n",
21442 __func__, vpi, vci);
21443 - atomic_inc(&vcc->stats->rx_err);
21444 + atomic_inc_unchecked(&vcc->stats->rx_err);
21445 return;
21446 }
21447
21448 @@ -361,7 +361,7 @@ static void usbatm_extract_one_cell(stru
21449 if (length > ATM_MAX_AAL5_PDU) {
21450 atm_rldbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n",
21451 __func__, length, vcc);
21452 - atomic_inc(&vcc->stats->rx_err);
21453 + atomic_inc_unchecked(&vcc->stats->rx_err);
21454 goto out;
21455 }
21456
21457 @@ -370,14 +370,14 @@ static void usbatm_extract_one_cell(stru
21458 if (sarb->len < pdu_length) {
21459 atm_rldbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n",
21460 __func__, pdu_length, sarb->len, vcc);
21461 - atomic_inc(&vcc->stats->rx_err);
21462 + atomic_inc_unchecked(&vcc->stats->rx_err);
21463 goto out;
21464 }
21465
21466 if (crc32_be(~0, skb_tail_pointer(sarb) - pdu_length, pdu_length) != 0xc704dd7b) {
21467 atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n",
21468 __func__, vcc);
21469 - atomic_inc(&vcc->stats->rx_err);
21470 + atomic_inc_unchecked(&vcc->stats->rx_err);
21471 goto out;
21472 }
21473
21474 @@ -387,7 +387,7 @@ static void usbatm_extract_one_cell(stru
21475 if (printk_ratelimit())
21476 atm_err(instance, "%s: no memory for skb (length: %u)!\n",
21477 __func__, length);
21478 - atomic_inc(&vcc->stats->rx_drop);
21479 + atomic_inc_unchecked(&vcc->stats->rx_drop);
21480 goto out;
21481 }
21482
21483 @@ -412,7 +412,7 @@ static void usbatm_extract_one_cell(stru
21484
21485 vcc->push(vcc, skb);
21486
21487 - atomic_inc(&vcc->stats->rx);
21488 + atomic_inc_unchecked(&vcc->stats->rx);
21489 out:
21490 skb_trim(sarb, 0);
21491 }
21492 @@ -616,7 +616,7 @@ static void usbatm_tx_process(unsigned l
21493 struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc;
21494
21495 usbatm_pop(vcc, skb);
21496 - atomic_inc(&vcc->stats->tx);
21497 + atomic_inc_unchecked(&vcc->stats->tx);
21498
21499 skb = skb_dequeue(&instance->sndqueue);
21500 }
21501 @@ -775,11 +775,11 @@ static int usbatm_atm_proc_read(struct a
21502 if (!left--)
21503 return sprintf(page,
21504 "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
21505 - atomic_read(&atm_dev->stats.aal5.tx),
21506 - atomic_read(&atm_dev->stats.aal5.tx_err),
21507 - atomic_read(&atm_dev->stats.aal5.rx),
21508 - atomic_read(&atm_dev->stats.aal5.rx_err),
21509 - atomic_read(&atm_dev->stats.aal5.rx_drop));
21510 + atomic_read_unchecked(&atm_dev->stats.aal5.tx),
21511 + atomic_read_unchecked(&atm_dev->stats.aal5.tx_err),
21512 + atomic_read_unchecked(&atm_dev->stats.aal5.rx),
21513 + atomic_read_unchecked(&atm_dev->stats.aal5.rx_err),
21514 + atomic_read_unchecked(&atm_dev->stats.aal5.rx_drop));
21515
21516 if (!left--) {
21517 if (instance->disconnected)
21518 diff -urNp linux-2.6.31.1/drivers/usb/class/cdc-acm.c linux-2.6.31.1/drivers/usb/class/cdc-acm.c
21519 --- linux-2.6.31.1/drivers/usb/class/cdc-acm.c 2009-09-24 11:45:25.000000000 -0400
21520 +++ linux-2.6.31.1/drivers/usb/class/cdc-acm.c 2009-10-01 20:12:43.000000000 -0400
21521 @@ -1529,7 +1529,7 @@ static struct usb_device_id acm_ids[] =
21522 USB_CDC_ACM_PROTO_AT_CDMA) },
21523
21524 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
21525 - { }
21526 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
21527 };
21528
21529 MODULE_DEVICE_TABLE(usb, acm_ids);
21530 diff -urNp linux-2.6.31.1/drivers/usb/class/usblp.c linux-2.6.31.1/drivers/usb/class/usblp.c
21531 --- linux-2.6.31.1/drivers/usb/class/usblp.c 2009-09-24 11:45:25.000000000 -0400
21532 +++ linux-2.6.31.1/drivers/usb/class/usblp.c 2009-10-01 20:12:43.000000000 -0400
21533 @@ -228,7 +228,7 @@ static const struct quirk_printer_struct
21534 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
21535 { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */
21536 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
21537 - { 0, 0 }
21538 + { 0, 0, 0 }
21539 };
21540
21541 static int usblp_wwait(struct usblp *usblp, int nonblock);
21542 @@ -1412,7 +1412,7 @@ static struct usb_device_id usblp_ids []
21543 { USB_INTERFACE_INFO(7, 1, 2) },
21544 { USB_INTERFACE_INFO(7, 1, 3) },
21545 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
21546 - { } /* Terminating entry */
21547 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
21548 };
21549
21550 MODULE_DEVICE_TABLE (usb, usblp_ids);
21551 diff -urNp linux-2.6.31.1/drivers/usb/class/usbtmc.c linux-2.6.31.1/drivers/usb/class/usbtmc.c
21552 --- linux-2.6.31.1/drivers/usb/class/usbtmc.c 2009-09-24 11:45:25.000000000 -0400
21553 +++ linux-2.6.31.1/drivers/usb/class/usbtmc.c 2009-10-01 20:12:43.000000000 -0400
21554 @@ -956,7 +956,7 @@ static long usbtmc_ioctl(struct file *fi
21555 return retval;
21556 }
21557
21558 -static struct file_operations fops = {
21559 +static const struct file_operations fops = {
21560 .owner = THIS_MODULE,
21561 .read = usbtmc_read,
21562 .write = usbtmc_write,
21563 diff -urNp linux-2.6.31.1/drivers/usb/core/hub.c linux-2.6.31.1/drivers/usb/core/hub.c
21564 --- linux-2.6.31.1/drivers/usb/core/hub.c 2009-09-24 11:45:25.000000000 -0400
21565 +++ linux-2.6.31.1/drivers/usb/core/hub.c 2009-10-01 20:12:43.000000000 -0400
21566 @@ -3284,7 +3284,7 @@ static struct usb_device_id hub_id_table
21567 .bDeviceClass = USB_CLASS_HUB},
21568 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
21569 .bInterfaceClass = USB_CLASS_HUB},
21570 - { } /* Terminating entry */
21571 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
21572 };
21573
21574 MODULE_DEVICE_TABLE (usb, hub_id_table);
21575 diff -urNp linux-2.6.31.1/drivers/usb/core/inode.c linux-2.6.31.1/drivers/usb/core/inode.c
21576 --- linux-2.6.31.1/drivers/usb/core/inode.c 2009-09-24 11:45:25.000000000 -0400
21577 +++ linux-2.6.31.1/drivers/usb/core/inode.c 2009-10-01 20:12:43.000000000 -0400
21578 @@ -48,7 +48,7 @@
21579 #define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO)
21580 #define USBFS_DEFAULT_LISTMODE S_IRUGO
21581
21582 -static struct super_operations usbfs_ops;
21583 +static const struct super_operations usbfs_ops;
21584 static const struct file_operations default_file_operations;
21585 static struct vfsmount *usbfs_mount;
21586 static int usbfs_mount_count; /* = 0 */
21587 @@ -449,7 +449,7 @@ static const struct file_operations defa
21588 .llseek = default_file_lseek,
21589 };
21590
21591 -static struct super_operations usbfs_ops = {
21592 +static const struct super_operations usbfs_ops = {
21593 .statfs = simple_statfs,
21594 .drop_inode = generic_delete_inode,
21595 .remount_fs = remount,
21596 diff -urNp linux-2.6.31.1/drivers/usb/core/message.c linux-2.6.31.1/drivers/usb/core/message.c
21597 --- linux-2.6.31.1/drivers/usb/core/message.c 2009-09-24 11:45:25.000000000 -0400
21598 +++ linux-2.6.31.1/drivers/usb/core/message.c 2009-10-01 20:12:43.000000000 -0400
21599 @@ -926,8 +926,8 @@ char *usb_cache_string(struct usb_device
21600 buf = kmalloc(MAX_USB_STRING_SIZE, GFP_KERNEL);
21601 if (buf) {
21602 len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
21603 - if (len > 0) {
21604 - smallbuf = kmalloc(++len, GFP_KERNEL);
21605 + if (len++ > 0) {
21606 + smallbuf = kmalloc(len, GFP_KERNEL);
21607 if (!smallbuf)
21608 return buf;
21609 memcpy(smallbuf, buf, len);
21610 diff -urNp linux-2.6.31.1/drivers/usb/gadget/inode.c linux-2.6.31.1/drivers/usb/gadget/inode.c
21611 --- linux-2.6.31.1/drivers/usb/gadget/inode.c 2009-09-24 11:45:25.000000000 -0400
21612 +++ linux-2.6.31.1/drivers/usb/gadget/inode.c 2009-10-01 20:12:43.000000000 -0400
21613 @@ -2033,7 +2033,7 @@ gadgetfs_create_file (struct super_block
21614 return inode;
21615 }
21616
21617 -static struct super_operations gadget_fs_operations = {
21618 +static const struct super_operations gadget_fs_operations = {
21619 .statfs = simple_statfs,
21620 .drop_inode = generic_delete_inode,
21621 };
21622 diff -urNp linux-2.6.31.1/drivers/usb/gadget/printer.c linux-2.6.31.1/drivers/usb/gadget/printer.c
21623 --- linux-2.6.31.1/drivers/usb/gadget/printer.c 2009-09-24 11:45:25.000000000 -0400
21624 +++ linux-2.6.31.1/drivers/usb/gadget/printer.c 2009-10-01 20:12:43.000000000 -0400
21625 @@ -875,7 +875,7 @@ printer_ioctl(struct file *fd, unsigned
21626 }
21627
21628 /* used after endpoint configuration */
21629 -static struct file_operations printer_io_operations = {
21630 +static const struct file_operations printer_io_operations = {
21631 .owner = THIS_MODULE,
21632 .open = printer_open,
21633 .read = printer_read,
21634 diff -urNp linux-2.6.31.1/drivers/usb/host/ehci-pci.c linux-2.6.31.1/drivers/usb/host/ehci-pci.c
21635 --- linux-2.6.31.1/drivers/usb/host/ehci-pci.c 2009-09-24 11:45:25.000000000 -0400
21636 +++ linux-2.6.31.1/drivers/usb/host/ehci-pci.c 2009-10-01 20:12:43.000000000 -0400
21637 @@ -416,7 +416,7 @@ static const struct pci_device_id pci_id
21638 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
21639 .driver_data = (unsigned long) &ehci_pci_hc_driver,
21640 },
21641 - { /* end: all zeroes */ }
21642 + { 0, 0, 0, 0, 0, 0, 0 }
21643 };
21644 MODULE_DEVICE_TABLE(pci, pci_ids);
21645
21646 diff -urNp linux-2.6.31.1/drivers/usb/host/uhci-hcd.c linux-2.6.31.1/drivers/usb/host/uhci-hcd.c
21647 --- linux-2.6.31.1/drivers/usb/host/uhci-hcd.c 2009-09-24 11:45:25.000000000 -0400
21648 +++ linux-2.6.31.1/drivers/usb/host/uhci-hcd.c 2009-10-01 20:12:43.000000000 -0400
21649 @@ -927,7 +927,7 @@ static const struct pci_device_id uhci_p
21650 /* handle any USB UHCI controller */
21651 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
21652 .driver_data = (unsigned long) &uhci_driver,
21653 - }, { /* end: all zeroes */ }
21654 + }, { 0, 0, 0, 0, 0, 0, 0 }
21655 };
21656
21657 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
21658 diff -urNp linux-2.6.31.1/drivers/usb/host/whci/debug.c linux-2.6.31.1/drivers/usb/host/whci/debug.c
21659 --- linux-2.6.31.1/drivers/usb/host/whci/debug.c 2009-09-24 11:45:25.000000000 -0400
21660 +++ linux-2.6.31.1/drivers/usb/host/whci/debug.c 2009-10-01 20:12:43.000000000 -0400
21661 @@ -134,7 +134,7 @@ static int pzl_open(struct inode *inode,
21662 return single_open(file, pzl_print, inode->i_private);
21663 }
21664
21665 -static struct file_operations di_fops = {
21666 +static const struct file_operations di_fops = {
21667 .open = di_open,
21668 .read = seq_read,
21669 .llseek = seq_lseek,
21670 @@ -142,7 +142,7 @@ static struct file_operations di_fops =
21671 .owner = THIS_MODULE,
21672 };
21673
21674 -static struct file_operations asl_fops = {
21675 +static const struct file_operations asl_fops = {
21676 .open = asl_open,
21677 .read = seq_read,
21678 .llseek = seq_lseek,
21679 @@ -150,7 +150,7 @@ static struct file_operations asl_fops =
21680 .owner = THIS_MODULE,
21681 };
21682
21683 -static struct file_operations pzl_fops = {
21684 +static const struct file_operations pzl_fops = {
21685 .open = pzl_open,
21686 .read = seq_read,
21687 .llseek = seq_lseek,
21688 diff -urNp linux-2.6.31.1/drivers/usb/mon/mon_bin.c linux-2.6.31.1/drivers/usb/mon/mon_bin.c
21689 --- linux-2.6.31.1/drivers/usb/mon/mon_bin.c 2009-09-24 11:45:25.000000000 -0400
21690 +++ linux-2.6.31.1/drivers/usb/mon/mon_bin.c 2009-10-01 20:12:43.000000000 -0400
21691 @@ -1184,7 +1184,7 @@ static int mon_bin_vma_fault(struct vm_a
21692 return 0;
21693 }
21694
21695 -static struct vm_operations_struct mon_bin_vm_ops = {
21696 +static const struct vm_operations_struct mon_bin_vm_ops = {
21697 .open = mon_bin_vma_open,
21698 .close = mon_bin_vma_close,
21699 .fault = mon_bin_vma_fault,
21700 diff -urNp linux-2.6.31.1/drivers/usb/storage/debug.h linux-2.6.31.1/drivers/usb/storage/debug.h
21701 --- linux-2.6.31.1/drivers/usb/storage/debug.h 2009-09-24 11:45:25.000000000 -0400
21702 +++ linux-2.6.31.1/drivers/usb/storage/debug.h 2009-10-01 20:12:43.000000000 -0400
21703 @@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char
21704 #define US_DEBUGPX(x...) printk( x )
21705 #define US_DEBUG(x) x
21706 #else
21707 -#define US_DEBUGP(x...)
21708 -#define US_DEBUGPX(x...)
21709 -#define US_DEBUG(x)
21710 +#define US_DEBUGP(x...) do {} while (0)
21711 +#define US_DEBUGPX(x...) do {} while (0)
21712 +#define US_DEBUG(x) do {} while (0)
21713 #endif
21714
21715 #endif
21716 diff -urNp linux-2.6.31.1/drivers/usb/storage/usb.c linux-2.6.31.1/drivers/usb/storage/usb.c
21717 --- linux-2.6.31.1/drivers/usb/storage/usb.c 2009-09-24 11:45:25.000000000 -0400
21718 +++ linux-2.6.31.1/drivers/usb/storage/usb.c 2009-10-01 20:12:43.000000000 -0400
21719 @@ -118,7 +118,7 @@ MODULE_PARM_DESC(quirks, "supplemental l
21720
21721 static struct us_unusual_dev us_unusual_dev_list[] = {
21722 # include "unusual_devs.h"
21723 - { } /* Terminating entry */
21724 + { NULL, NULL, 0, 0, NULL } /* Terminating entry */
21725 };
21726
21727 #undef UNUSUAL_DEV
21728 diff -urNp linux-2.6.31.1/drivers/usb/storage/usual-tables.c linux-2.6.31.1/drivers/usb/storage/usual-tables.c
21729 --- linux-2.6.31.1/drivers/usb/storage/usual-tables.c 2009-09-24 11:45:25.000000000 -0400
21730 +++ linux-2.6.31.1/drivers/usb/storage/usual-tables.c 2009-10-01 20:12:43.000000000 -0400
21731 @@ -48,7 +48,7 @@
21732
21733 struct usb_device_id usb_storage_usb_ids[] = {
21734 # include "unusual_devs.h"
21735 - { } /* Terminating entry */
21736 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
21737 };
21738 EXPORT_SYMBOL_GPL(usb_storage_usb_ids);
21739
21740 diff -urNp linux-2.6.31.1/drivers/uwb/uwb-debug.c linux-2.6.31.1/drivers/uwb/uwb-debug.c
21741 --- linux-2.6.31.1/drivers/uwb/uwb-debug.c 2009-09-24 11:45:25.000000000 -0400
21742 +++ linux-2.6.31.1/drivers/uwb/uwb-debug.c 2009-10-01 20:12:43.000000000 -0400
21743 @@ -205,7 +205,7 @@ static ssize_t command_write(struct file
21744 return ret < 0 ? ret : len;
21745 }
21746
21747 -static struct file_operations command_fops = {
21748 +static const struct file_operations command_fops = {
21749 .open = command_open,
21750 .write = command_write,
21751 .read = NULL,
21752 @@ -255,7 +255,7 @@ static int reservations_open(struct inod
21753 return single_open(file, reservations_print, inode->i_private);
21754 }
21755
21756 -static struct file_operations reservations_fops = {
21757 +static const struct file_operations reservations_fops = {
21758 .open = reservations_open,
21759 .read = seq_read,
21760 .llseek = seq_lseek,
21761 @@ -283,7 +283,7 @@ static int drp_avail_open(struct inode *
21762 return single_open(file, drp_avail_print, inode->i_private);
21763 }
21764
21765 -static struct file_operations drp_avail_fops = {
21766 +static const struct file_operations drp_avail_fops = {
21767 .open = drp_avail_open,
21768 .read = seq_read,
21769 .llseek = seq_lseek,
21770 diff -urNp linux-2.6.31.1/drivers/uwb/wlp/messages.c linux-2.6.31.1/drivers/uwb/wlp/messages.c
21771 --- linux-2.6.31.1/drivers/uwb/wlp/messages.c 2009-09-24 11:45:25.000000000 -0400
21772 +++ linux-2.6.31.1/drivers/uwb/wlp/messages.c 2009-10-01 20:12:43.000000000 -0400
21773 @@ -903,7 +903,7 @@ int wlp_parse_f0(struct wlp *wlp, struct
21774 size_t len = skb->len;
21775 size_t used;
21776 ssize_t result;
21777 - struct wlp_nonce enonce, rnonce;
21778 + struct wlp_nonce enonce = {{0}}, rnonce = {{0}};
21779 enum wlp_assc_error assc_err;
21780 char enonce_buf[WLP_WSS_NONCE_STRSIZE];
21781 char rnonce_buf[WLP_WSS_NONCE_STRSIZE];
21782 diff -urNp linux-2.6.31.1/drivers/video/fb_defio.c linux-2.6.31.1/drivers/video/fb_defio.c
21783 --- linux-2.6.31.1/drivers/video/fb_defio.c 2009-09-24 11:45:25.000000000 -0400
21784 +++ linux-2.6.31.1/drivers/video/fb_defio.c 2009-10-01 20:12:43.000000000 -0400
21785 @@ -125,7 +125,7 @@ page_already_added:
21786 return 0;
21787 }
21788
21789 -static struct vm_operations_struct fb_deferred_io_vm_ops = {
21790 +static const struct vm_operations_struct fb_deferred_io_vm_ops = {
21791 .fault = fb_deferred_io_fault,
21792 .page_mkwrite = fb_deferred_io_mkwrite,
21793 };
21794 diff -urNp linux-2.6.31.1/drivers/video/fbmem.c linux-2.6.31.1/drivers/video/fbmem.c
21795 --- linux-2.6.31.1/drivers/video/fbmem.c 2009-09-24 11:45:25.000000000 -0400
21796 +++ linux-2.6.31.1/drivers/video/fbmem.c 2009-10-01 20:12:43.000000000 -0400
21797 @@ -403,7 +403,7 @@ static void fb_do_show_logo(struct fb_in
21798 image->dx += image->width + 8;
21799 }
21800 } else if (rotate == FB_ROTATE_UD) {
21801 - for (x = 0; x < num && image->dx >= 0; x++) {
21802 + for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
21803 info->fbops->fb_imageblit(info, image);
21804 image->dx -= image->width + 8;
21805 }
21806 @@ -415,7 +415,7 @@ static void fb_do_show_logo(struct fb_in
21807 image->dy += image->height + 8;
21808 }
21809 } else if (rotate == FB_ROTATE_CCW) {
21810 - for (x = 0; x < num && image->dy >= 0; x++) {
21811 + for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
21812 info->fbops->fb_imageblit(info, image);
21813 image->dy -= image->height + 8;
21814 }
21815 @@ -1108,7 +1108,7 @@ static long do_fb_ioctl(struct fb_info *
21816 return -EFAULT;
21817 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
21818 return -EINVAL;
21819 - if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
21820 + if (con2fb.framebuffer >= FB_MAX)
21821 return -EINVAL;
21822 if (!registered_fb[con2fb.framebuffer])
21823 request_module("fb%d", con2fb.framebuffer);
21824 diff -urNp linux-2.6.31.1/drivers/video/fbmon.c linux-2.6.31.1/drivers/video/fbmon.c
21825 --- linux-2.6.31.1/drivers/video/fbmon.c 2009-09-24 11:45:25.000000000 -0400
21826 +++ linux-2.6.31.1/drivers/video/fbmon.c 2009-10-01 20:12:43.000000000 -0400
21827 @@ -45,7 +45,7 @@
21828 #ifdef DEBUG
21829 #define DPRINTK(fmt, args...) printk(fmt,## args)
21830 #else
21831 -#define DPRINTK(fmt, args...)
21832 +#define DPRINTK(fmt, args...) do {} while (0)
21833 #endif
21834
21835 #define FBMON_FIX_HEADER 1
21836 diff -urNp linux-2.6.31.1/drivers/video/i810/i810_accel.c linux-2.6.31.1/drivers/video/i810/i810_accel.c
21837 --- linux-2.6.31.1/drivers/video/i810/i810_accel.c 2009-09-24 11:45:25.000000000 -0400
21838 +++ linux-2.6.31.1/drivers/video/i810/i810_accel.c 2009-10-01 20:12:43.000000000 -0400
21839 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct
21840 }
21841 }
21842 printk("ringbuffer lockup!!!\n");
21843 + printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
21844 i810_report_error(mmio);
21845 par->dev_flags |= LOCKUP;
21846 info->pixmap.scan_align = 1;
21847 diff -urNp linux-2.6.31.1/drivers/video/i810/i810_main.c linux-2.6.31.1/drivers/video/i810/i810_main.c
21848 --- linux-2.6.31.1/drivers/video/i810/i810_main.c 2009-09-24 11:45:25.000000000 -0400
21849 +++ linux-2.6.31.1/drivers/video/i810/i810_main.c 2009-10-01 20:12:43.000000000 -0400
21850 @@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
21851 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
21852 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
21853 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
21854 - { 0 },
21855 + { 0, 0, 0, 0, 0, 0, 0 },
21856 };
21857
21858 static struct pci_driver i810fb_driver = {
21859 diff -urNp linux-2.6.31.1/drivers/video/modedb.c linux-2.6.31.1/drivers/video/modedb.c
21860 --- linux-2.6.31.1/drivers/video/modedb.c 2009-09-24 11:45:25.000000000 -0400
21861 +++ linux-2.6.31.1/drivers/video/modedb.c 2009-10-01 20:12:43.000000000 -0400
21862 @@ -38,240 +38,240 @@ static const struct fb_videomode modedb[
21863 {
21864 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
21865 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
21866 - 0, FB_VMODE_NONINTERLACED
21867 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21868 }, {
21869 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
21870 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
21871 - 0, FB_VMODE_NONINTERLACED
21872 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21873 }, {
21874 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
21875 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
21876 - 0, FB_VMODE_NONINTERLACED
21877 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21878 }, {
21879 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
21880 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
21881 - 0, FB_VMODE_INTERLACED
21882 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
21883 }, {
21884 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
21885 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
21886 - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
21887 + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21888 }, {
21889 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
21890 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
21891 - 0, FB_VMODE_NONINTERLACED
21892 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21893 }, {
21894 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
21895 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
21896 - 0, FB_VMODE_NONINTERLACED
21897 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21898 }, {
21899 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
21900 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
21901 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
21902 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21903 }, {
21904 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
21905 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
21906 - 0, FB_VMODE_NONINTERLACED
21907 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21908 }, {
21909 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
21910 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
21911 - 0, FB_VMODE_INTERLACED
21912 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
21913 }, {
21914 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
21915 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
21916 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
21917 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21918 }, {
21919 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
21920 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
21921 - 0, FB_VMODE_NONINTERLACED
21922 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21923 }, {
21924 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
21925 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
21926 - 0, FB_VMODE_NONINTERLACED
21927 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21928 }, {
21929 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
21930 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
21931 - 0, FB_VMODE_NONINTERLACED
21932 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21933 }, {
21934 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
21935 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
21936 - 0, FB_VMODE_NONINTERLACED
21937 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21938 }, {
21939 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
21940 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
21941 - 0, FB_VMODE_NONINTERLACED
21942 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21943 }, {
21944 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
21945 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
21946 - 0, FB_VMODE_INTERLACED
21947 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
21948 }, {
21949 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
21950 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
21951 - 0, FB_VMODE_NONINTERLACED
21952 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21953 }, {
21954 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
21955 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
21956 - 0, FB_VMODE_NONINTERLACED
21957 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21958 }, {
21959 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
21960 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
21961 - 0, FB_VMODE_NONINTERLACED
21962 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21963 }, {
21964 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
21965 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
21966 - 0, FB_VMODE_NONINTERLACED
21967 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21968 }, {
21969 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
21970 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
21971 - 0, FB_VMODE_NONINTERLACED
21972 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21973 }, {
21974 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
21975 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
21976 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
21977 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21978 }, {
21979 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
21980 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
21981 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
21982 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21983 }, {
21984 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
21985 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
21986 - 0, FB_VMODE_NONINTERLACED
21987 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21988 }, {
21989 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
21990 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
21991 - 0, FB_VMODE_NONINTERLACED
21992 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21993 }, {
21994 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
21995 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
21996 - 0, FB_VMODE_NONINTERLACED
21997 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
21998 }, {
21999 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
22000 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
22001 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
22002 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22003 }, {
22004 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
22005 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
22006 - 0, FB_VMODE_NONINTERLACED
22007 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22008 }, {
22009 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
22010 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
22011 - 0, FB_VMODE_NONINTERLACED
22012 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22013 }, {
22014 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
22015 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
22016 - 0, FB_VMODE_NONINTERLACED
22017 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22018 }, {
22019 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
22020 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
22021 - 0, FB_VMODE_NONINTERLACED
22022 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22023 }, {
22024 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
22025 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
22026 - 0, FB_VMODE_NONINTERLACED
22027 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22028 }, {
22029 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
22030 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
22031 - 0, FB_VMODE_NONINTERLACED
22032 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22033 }, {
22034 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
22035 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
22036 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
22037 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22038 }, {
22039 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
22040 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
22041 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
22042 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22043 }, {
22044 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
22045 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
22046 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
22047 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22048 }, {
22049 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
22050 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
22051 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
22052 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22053 }, {
22054 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
22055 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
22056 - 0, FB_VMODE_NONINTERLACED
22057 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22058 }, {
22059 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
22060 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
22061 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
22062 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22063 }, {
22064 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
22065 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
22066 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
22067 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22068 }, {
22069 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
22070 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
22071 - 0, FB_VMODE_NONINTERLACED
22072 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22073 }, {
22074 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
22075 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
22076 - 0, FB_VMODE_NONINTERLACED
22077 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22078 }, {
22079 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
22080 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
22081 - 0, FB_VMODE_DOUBLE
22082 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
22083 }, {
22084 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
22085 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
22086 - 0, FB_VMODE_DOUBLE
22087 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
22088 }, {
22089 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
22090 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
22091 - 0, FB_VMODE_DOUBLE
22092 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
22093 }, {
22094 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
22095 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
22096 - 0, FB_VMODE_DOUBLE
22097 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
22098 }, {
22099 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
22100 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
22101 - 0, FB_VMODE_DOUBLE
22102 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
22103 }, {
22104 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
22105 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
22106 - 0, FB_VMODE_DOUBLE
22107 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
22108 }, {
22109 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
22110 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
22111 - 0, FB_VMODE_DOUBLE
22112 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
22113 }, {
22114 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
22115 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
22116 - 0, FB_VMODE_DOUBLE
22117 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
22118 }, {
22119 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
22120 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
22121 - 0, FB_VMODE_DOUBLE
22122 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
22123 }, {
22124 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
22125 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
22126 - 0, FB_VMODE_DOUBLE
22127 + 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
22128 }, {
22129 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
22130 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
22131 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
22132 - FB_VMODE_NONINTERLACED
22133 + FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22134 }, {
22135 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
22136 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
22137 - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
22138 + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22139 }, {
22140 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
22141 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
22142 - 0, FB_VMODE_NONINTERLACED
22143 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22144 }, {
22145 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
22146 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
22147 - 0, FB_VMODE_NONINTERLACED
22148 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
22149 }, {
22150 /* 720x576i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
22151 NULL, 50, 720, 576, 74074, 64, 16, 39, 5, 64, 5,
22152 - 0, FB_VMODE_INTERLACED
22153 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
22154 }, {
22155 /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
22156 NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5,
22157 - 0, FB_VMODE_INTERLACED
22158 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
22159 },
22160 };
22161
22162 diff -urNp linux-2.6.31.1/drivers/video/omap/dispc.c linux-2.6.31.1/drivers/video/omap/dispc.c
22163 --- linux-2.6.31.1/drivers/video/omap/dispc.c 2009-09-24 11:45:25.000000000 -0400
22164 +++ linux-2.6.31.1/drivers/video/omap/dispc.c 2009-10-01 20:12:43.000000000 -0400
22165 @@ -1013,7 +1013,7 @@ static void mmap_user_close(struct vm_ar
22166 atomic_dec(&dispc.map_count[plane]);
22167 }
22168
22169 -static struct vm_operations_struct mmap_user_ops = {
22170 +static const struct vm_operations_struct mmap_user_ops = {
22171 .open = mmap_user_open,
22172 .close = mmap_user_close,
22173 };
22174 diff -urNp linux-2.6.31.1/drivers/video/uvesafb.c linux-2.6.31.1/drivers/video/uvesafb.c
22175 --- linux-2.6.31.1/drivers/video/uvesafb.c 2009-09-24 11:45:25.000000000 -0400
22176 +++ linux-2.6.31.1/drivers/video/uvesafb.c 2009-10-01 20:12:43.000000000 -0400
22177 @@ -18,6 +18,7 @@
22178 #include <linux/fb.h>
22179 #include <linux/io.h>
22180 #include <linux/mutex.h>
22181 +#include <linux/moduleloader.h>
22182 #include <video/edid.h>
22183 #include <video/uvesafb.h>
22184 #ifdef CONFIG_X86
22185 @@ -118,7 +119,7 @@ static int uvesafb_helper_start(void)
22186 NULL,
22187 };
22188
22189 - return call_usermodehelper(v86d_path, argv, envp, 1);
22190 + return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
22191 }
22192
22193 /*
22194 @@ -566,10 +567,34 @@ static int __devinit uvesafb_vbe_getpmi(
22195 if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
22196 par->pmi_setpal = par->ypan = 0;
22197 } else {
22198 +
22199 +#ifdef CONFIG_PAX_KERNEXEC
22200 +#ifdef CONFIG_MODULES
22201 + unsigned long cr0;
22202 +
22203 + par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
22204 +#endif
22205 + if (!par->pmi_code) {
22206 + par->pmi_setpal = par->ypan = 0;
22207 + return 0;
22208 + }
22209 +#endif
22210 +
22211 par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
22212 + task->t.regs.edi);
22213 +
22214 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
22215 + pax_open_kernel(cr0);
22216 + memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
22217 + pax_close_kernel(cr0);
22218 +
22219 + par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
22220 + par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
22221 +#else
22222 par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
22223 par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
22224 +#endif
22225 +
22226 printk(KERN_INFO "uvesafb: protected mode interface info at "
22227 "%04x:%04x\n",
22228 (u16)task->t.regs.es, (u16)task->t.regs.edi);
22229 @@ -1825,6 +1850,11 @@ out:
22230 if (par->vbe_modes)
22231 kfree(par->vbe_modes);
22232
22233 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
22234 + if (par->pmi_code)
22235 + module_free_exec(NULL, par->pmi_code);
22236 +#endif
22237 +
22238 framebuffer_release(info);
22239 return err;
22240 }
22241 @@ -1851,6 +1881,12 @@ static int uvesafb_remove(struct platfor
22242 kfree(par->vbe_state_orig);
22243 if (par->vbe_state_saved)
22244 kfree(par->vbe_state_saved);
22245 +
22246 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
22247 + if (par->pmi_code)
22248 + module_free_exec(NULL, par->pmi_code);
22249 +#endif
22250 +
22251 }
22252
22253 framebuffer_release(info);
22254 diff -urNp linux-2.6.31.1/drivers/video/vesafb.c linux-2.6.31.1/drivers/video/vesafb.c
22255 --- linux-2.6.31.1/drivers/video/vesafb.c 2009-09-24 11:45:25.000000000 -0400
22256 +++ linux-2.6.31.1/drivers/video/vesafb.c 2009-10-01 20:12:43.000000000 -0400
22257 @@ -9,6 +9,7 @@
22258 */
22259
22260 #include <linux/module.h>
22261 +#include <linux/moduleloader.h>
22262 #include <linux/kernel.h>
22263 #include <linux/errno.h>
22264 #include <linux/string.h>
22265 @@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
22266 static int vram_total __initdata; /* Set total amount of memory */
22267 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
22268 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
22269 -static void (*pmi_start)(void) __read_mostly;
22270 -static void (*pmi_pal) (void) __read_mostly;
22271 +static void (*pmi_start)(void) __read_only;
22272 +static void (*pmi_pal) (void) __read_only;
22273 static int depth __read_mostly;
22274 static int vga_compat __read_mostly;
22275 /* --------------------------------------------------------------------- */
22276 @@ -233,6 +234,7 @@ static int __init vesafb_probe(struct pl
22277 unsigned int size_vmode;
22278 unsigned int size_remap;
22279 unsigned int size_total;
22280 + void *pmi_code = NULL;
22281
22282 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
22283 return -ENODEV;
22284 @@ -275,10 +277,6 @@ static int __init vesafb_probe(struct pl
22285 size_remap = size_total;
22286 vesafb_fix.smem_len = size_remap;
22287
22288 -#ifndef __i386__
22289 - screen_info.vesapm_seg = 0;
22290 -#endif
22291 -
22292 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
22293 printk(KERN_WARNING
22294 "vesafb: cannot reserve video memory at 0x%lx\n",
22295 @@ -315,9 +313,21 @@ static int __init vesafb_probe(struct pl
22296 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
22297 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
22298
22299 +#ifdef __i386__
22300 +
22301 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
22302 + pmi_code = module_alloc_exec(screen_info.vesapm_size);
22303 + if (!pmi_code)
22304 +#elif !defined(CONFIG_PAX_KERNEXEC)
22305 + if (0)
22306 +#endif
22307 +
22308 +#endif
22309 + screen_info.vesapm_seg = 0;
22310 +
22311 if (screen_info.vesapm_seg) {
22312 - printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
22313 - screen_info.vesapm_seg,screen_info.vesapm_off);
22314 + printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
22315 + screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
22316 }
22317
22318 if (screen_info.vesapm_seg < 0xc000)
22319 @@ -325,9 +335,29 @@ static int __init vesafb_probe(struct pl
22320
22321 if (ypan || pmi_setpal) {
22322 unsigned short *pmi_base;
22323 - pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
22324 - pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
22325 - pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
22326 +
22327 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
22328 + unsigned long cr0;
22329 +#endif
22330 +
22331 + pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
22332 +
22333 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
22334 + pax_open_kernel(cr0);
22335 + memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
22336 +#else
22337 + pmi_code = pmi_base;
22338 +#endif
22339 +
22340 + pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
22341 + pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
22342 +
22343 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
22344 + pmi_start = ktva_ktla(pmi_start);
22345 + pmi_pal = ktva_ktla(pmi_pal);
22346 + pax_close_kernel(cr0);
22347 +#endif
22348 +
22349 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
22350 if (pmi_base[3]) {
22351 printk(KERN_INFO "vesafb: pmi: ports = ");
22352 @@ -469,6 +499,11 @@ static int __init vesafb_probe(struct pl
22353 info->node, info->fix.id);
22354 return 0;
22355 err:
22356 +
22357 +#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
22358 + module_free_exec(NULL, pmi_code);
22359 +#endif
22360 +
22361 if (info->screen_base)
22362 iounmap(info->screen_base);
22363 framebuffer_release(info);
22364 diff -urNp linux-2.6.31.1/fs/9p/vfs_inode.c linux-2.6.31.1/fs/9p/vfs_inode.c
22365 --- linux-2.6.31.1/fs/9p/vfs_inode.c 2009-09-24 11:45:25.000000000 -0400
22366 +++ linux-2.6.31.1/fs/9p/vfs_inode.c 2009-10-01 20:12:44.000000000 -0400
22367 @@ -1025,7 +1025,7 @@ static void *v9fs_vfs_follow_link(struct
22368 static void
22369 v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
22370 {
22371 - char *s = nd_get_link(nd);
22372 + const char *s = nd_get_link(nd);
22373
22374 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name,
22375 IS_ERR(s) ? "<error>" : s);
22376 diff -urNp linux-2.6.31.1/fs/afs/proc.c linux-2.6.31.1/fs/afs/proc.c
22377 --- linux-2.6.31.1/fs/afs/proc.c 2009-09-24 11:45:25.000000000 -0400
22378 +++ linux-2.6.31.1/fs/afs/proc.c 2009-10-01 20:12:44.000000000 -0400
22379 @@ -28,7 +28,7 @@ static int afs_proc_cells_show(struct se
22380 static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
22381 size_t size, loff_t *_pos);
22382
22383 -static struct seq_operations afs_proc_cells_ops = {
22384 +static const struct seq_operations afs_proc_cells_ops = {
22385 .start = afs_proc_cells_start,
22386 .next = afs_proc_cells_next,
22387 .stop = afs_proc_cells_stop,
22388 @@ -70,7 +70,7 @@ static void *afs_proc_cell_volumes_next(
22389 static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v);
22390 static int afs_proc_cell_volumes_show(struct seq_file *m, void *v);
22391
22392 -static struct seq_operations afs_proc_cell_volumes_ops = {
22393 +static const struct seq_operations afs_proc_cell_volumes_ops = {
22394 .start = afs_proc_cell_volumes_start,
22395 .next = afs_proc_cell_volumes_next,
22396 .stop = afs_proc_cell_volumes_stop,
22397 @@ -95,7 +95,7 @@ static void *afs_proc_cell_vlservers_nex
22398 static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v);
22399 static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v);
22400
22401 -static struct seq_operations afs_proc_cell_vlservers_ops = {
22402 +static const struct seq_operations afs_proc_cell_vlservers_ops = {
22403 .start = afs_proc_cell_vlservers_start,
22404 .next = afs_proc_cell_vlservers_next,
22405 .stop = afs_proc_cell_vlservers_stop,
22406 @@ -119,7 +119,7 @@ static void *afs_proc_cell_servers_next(
22407 static void afs_proc_cell_servers_stop(struct seq_file *p, void *v);
22408 static int afs_proc_cell_servers_show(struct seq_file *m, void *v);
22409
22410 -static struct seq_operations afs_proc_cell_servers_ops = {
22411 +static const struct seq_operations afs_proc_cell_servers_ops = {
22412 .start = afs_proc_cell_servers_start,
22413 .next = afs_proc_cell_servers_next,
22414 .stop = afs_proc_cell_servers_stop,
22415 diff -urNp linux-2.6.31.1/fs/aio.c linux-2.6.31.1/fs/aio.c
22416 --- linux-2.6.31.1/fs/aio.c 2009-09-24 11:45:25.000000000 -0400
22417 +++ linux-2.6.31.1/fs/aio.c 2009-10-01 20:12:44.000000000 -0400
22418 @@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
22419 size += sizeof(struct io_event) * nr_events;
22420 nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
22421
22422 - if (nr_pages < 0)
22423 + if (nr_pages <= 0)
22424 return -EINVAL;
22425
22426 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
22427 diff -urNp linux-2.6.31.1/fs/autofs/root.c linux-2.6.31.1/fs/autofs/root.c
22428 --- linux-2.6.31.1/fs/autofs/root.c 2009-09-24 11:45:25.000000000 -0400
22429 +++ linux-2.6.31.1/fs/autofs/root.c 2009-10-01 20:12:44.000000000 -0400
22430 @@ -299,7 +299,8 @@ static int autofs_root_symlink(struct in
22431 set_bit(n,sbi->symlink_bitmap);
22432 sl = &sbi->symlink[n];
22433 sl->len = strlen(symname);
22434 - sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL);
22435 + slsize = sl->len+1;
22436 + sl->data = kmalloc(slsize, GFP_KERNEL);
22437 if (!sl->data) {
22438 clear_bit(n,sbi->symlink_bitmap);
22439 unlock_kernel();
22440 diff -urNp linux-2.6.31.1/fs/autofs4/symlink.c linux-2.6.31.1/fs/autofs4/symlink.c
22441 --- linux-2.6.31.1/fs/autofs4/symlink.c 2009-09-24 11:45:25.000000000 -0400
22442 +++ linux-2.6.31.1/fs/autofs4/symlink.c 2009-10-01 20:12:44.000000000 -0400
22443 @@ -15,7 +15,7 @@
22444 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
22445 {
22446 struct autofs_info *ino = autofs4_dentry_ino(dentry);
22447 - nd_set_link(nd, (char *)ino->u.symlink);
22448 + nd_set_link(nd, ino->u.symlink);
22449 return NULL;
22450 }
22451
22452 diff -urNp linux-2.6.31.1/fs/befs/linuxvfs.c linux-2.6.31.1/fs/befs/linuxvfs.c
22453 --- linux-2.6.31.1/fs/befs/linuxvfs.c 2009-09-24 11:45:25.000000000 -0400
22454 +++ linux-2.6.31.1/fs/befs/linuxvfs.c 2009-10-01 20:12:44.000000000 -0400
22455 @@ -493,7 +493,7 @@ static void befs_put_link(struct dentry
22456 {
22457 befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
22458 if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
22459 - char *link = nd_get_link(nd);
22460 + const char *link = nd_get_link(nd);
22461 if (!IS_ERR(link))
22462 kfree(link);
22463 }
22464 diff -urNp linux-2.6.31.1/fs/binfmt_aout.c linux-2.6.31.1/fs/binfmt_aout.c
22465 --- linux-2.6.31.1/fs/binfmt_aout.c 2009-09-24 11:45:25.000000000 -0400
22466 +++ linux-2.6.31.1/fs/binfmt_aout.c 2009-10-01 20:12:44.000000000 -0400
22467 @@ -16,6 +16,7 @@
22468 #include <linux/string.h>
22469 #include <linux/fs.h>
22470 #include <linux/file.h>
22471 +#include <linux/security.h>
22472 #include <linux/stat.h>
22473 #include <linux/fcntl.h>
22474 #include <linux/ptrace.h>
22475 @@ -113,10 +114,12 @@ static int aout_core_dump(long signr, st
22476
22477 /* If the size of the dump file exceeds the rlimit, then see what would happen
22478 if we wrote the stack, but not the data area. */
22479 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
22480 if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
22481 dump.u_dsize = 0;
22482
22483 /* Make sure we have enough room to write the stack and data areas. */
22484 + gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
22485 if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
22486 dump.u_ssize = 0;
22487
22488 @@ -249,6 +252,8 @@ static int load_aout_binary(struct linux
22489 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
22490 if (rlim >= RLIM_INFINITY)
22491 rlim = ~0;
22492 +
22493 + gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
22494 if (ex.a_data + ex.a_bss > rlim)
22495 return -ENOMEM;
22496
22497 @@ -276,6 +281,27 @@ static int load_aout_binary(struct linux
22498 install_exec_creds(bprm);
22499 current->flags &= ~PF_FORKNOEXEC;
22500
22501 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
22502 + current->mm->pax_flags = 0UL;
22503 +#endif
22504 +
22505 +#ifdef CONFIG_PAX_PAGEEXEC
22506 + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
22507 + current->mm->pax_flags |= MF_PAX_PAGEEXEC;
22508 +
22509 +#ifdef CONFIG_PAX_EMUTRAMP
22510 + if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
22511 + current->mm->pax_flags |= MF_PAX_EMUTRAMP;
22512 +#endif
22513 +
22514 +#ifdef CONFIG_PAX_MPROTECT
22515 + if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
22516 + current->mm->pax_flags |= MF_PAX_MPROTECT;
22517 +#endif
22518 +
22519 + }
22520 +#endif
22521 +
22522 if (N_MAGIC(ex) == OMAGIC) {
22523 unsigned long text_addr, map_size;
22524 loff_t pos;
22525 @@ -348,7 +374,7 @@ static int load_aout_binary(struct linux
22526
22527 down_write(&current->mm->mmap_sem);
22528 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
22529 - PROT_READ | PROT_WRITE | PROT_EXEC,
22530 + PROT_READ | PROT_WRITE,
22531 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
22532 fd_offset + ex.a_text);
22533 up_write(&current->mm->mmap_sem);
22534 diff -urNp linux-2.6.31.1/fs/binfmt_elf.c linux-2.6.31.1/fs/binfmt_elf.c
22535 --- linux-2.6.31.1/fs/binfmt_elf.c 2009-09-24 11:45:25.000000000 -0400
22536 +++ linux-2.6.31.1/fs/binfmt_elf.c 2009-10-01 20:12:44.000000000 -0400
22537 @@ -35,6 +35,10 @@
22538 #include <asm/param.h>
22539 #include <asm/page.h>
22540
22541 +#ifdef CONFIG_PAX_SEGMEXEC
22542 +#include <asm/desc.h>
22543 +#endif
22544 +
22545 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
22546 static int load_elf_library(struct file *);
22547 static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
22548 @@ -50,6 +54,10 @@ static int elf_core_dump(long signr, str
22549 #define elf_core_dump NULL
22550 #endif
22551
22552 +#ifdef CONFIG_PAX_MPROTECT
22553 +static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags);
22554 +#endif
22555 +
22556 #if ELF_EXEC_PAGESIZE > PAGE_SIZE
22557 #define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE
22558 #else
22559 @@ -69,6 +77,11 @@ static struct linux_binfmt elf_format =
22560 .load_binary = load_elf_binary,
22561 .load_shlib = load_elf_library,
22562 .core_dump = elf_core_dump,
22563 +
22564 +#ifdef CONFIG_PAX_MPROTECT
22565 + .handle_mprotect= elf_handle_mprotect,
22566 +#endif
22567 +
22568 .min_coredump = ELF_EXEC_PAGESIZE,
22569 .hasvdso = 1
22570 };
22571 @@ -77,6 +90,8 @@ static struct linux_binfmt elf_format =
22572
22573 static int set_brk(unsigned long start, unsigned long end)
22574 {
22575 + unsigned long e = end;
22576 +
22577 start = ELF_PAGEALIGN(start);
22578 end = ELF_PAGEALIGN(end);
22579 if (end > start) {
22580 @@ -87,7 +102,7 @@ static int set_brk(unsigned long start,
22581 if (BAD_ADDR(addr))
22582 return addr;
22583 }
22584 - current->mm->start_brk = current->mm->brk = end;
22585 + current->mm->start_brk = current->mm->brk = e;
22586 return 0;
22587 }
22588
22589 @@ -148,7 +163,7 @@ create_elf_tables(struct linux_binprm *b
22590 elf_addr_t __user *u_rand_bytes;
22591 const char *k_platform = ELF_PLATFORM;
22592 const char *k_base_platform = ELF_BASE_PLATFORM;
22593 - unsigned char k_rand_bytes[16];
22594 + u32 k_rand_bytes[4];
22595 int items;
22596 elf_addr_t *elf_info;
22597 int ei_index = 0;
22598 @@ -195,6 +210,10 @@ create_elf_tables(struct linux_binprm *b
22599 * Generate 16 random bytes for userspace PRNG seeding.
22600 */
22601 get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes));
22602 + srandom32(k_rand_bytes[0] ^ random32());
22603 + srandom32(k_rand_bytes[1] ^ random32());
22604 + srandom32(k_rand_bytes[2] ^ random32());
22605 + srandom32(k_rand_bytes[3] ^ random32());
22606 u_rand_bytes = (elf_addr_t __user *)
22607 STACK_ALLOC(p, sizeof(k_rand_bytes));
22608 if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
22609 @@ -385,10 +404,10 @@ static unsigned long load_elf_interp(str
22610 {
22611 struct elf_phdr *elf_phdata;
22612 struct elf_phdr *eppnt;
22613 - unsigned long load_addr = 0;
22614 + unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
22615 int load_addr_set = 0;
22616 unsigned long last_bss = 0, elf_bss = 0;
22617 - unsigned long error = ~0UL;
22618 + unsigned long error = -EINVAL;
22619 unsigned long total_size;
22620 int retval, i, size;
22621
22622 @@ -434,6 +453,11 @@ static unsigned long load_elf_interp(str
22623 goto out_close;
22624 }
22625
22626 +#ifdef CONFIG_PAX_SEGMEXEC
22627 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
22628 + pax_task_size = SEGMEXEC_TASK_SIZE;
22629 +#endif
22630 +
22631 eppnt = elf_phdata;
22632 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
22633 if (eppnt->p_type == PT_LOAD) {
22634 @@ -477,8 +501,8 @@ static unsigned long load_elf_interp(str
22635 k = load_addr + eppnt->p_vaddr;
22636 if (BAD_ADDR(k) ||
22637 eppnt->p_filesz > eppnt->p_memsz ||
22638 - eppnt->p_memsz > TASK_SIZE ||
22639 - TASK_SIZE - eppnt->p_memsz < k) {
22640 + eppnt->p_memsz > pax_task_size ||
22641 + pax_task_size - eppnt->p_memsz < k) {
22642 error = -ENOMEM;
22643 goto out_close;
22644 }
22645 @@ -532,6 +556,177 @@ out:
22646 return error;
22647 }
22648
22649 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
22650 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
22651 +{
22652 + unsigned long pax_flags = 0UL;
22653 +
22654 +#ifdef CONFIG_PAX_PAGEEXEC
22655 + if (elf_phdata->p_flags & PF_PAGEEXEC)
22656 + pax_flags |= MF_PAX_PAGEEXEC;
22657 +#endif
22658 +
22659 +#ifdef CONFIG_PAX_SEGMEXEC
22660 + if (elf_phdata->p_flags & PF_SEGMEXEC)
22661 + pax_flags |= MF_PAX_SEGMEXEC;
22662 +#endif
22663 +
22664 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
22665 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22666 + if (nx_enabled)
22667 + pax_flags &= ~MF_PAX_SEGMEXEC;
22668 + else
22669 + pax_flags &= ~MF_PAX_PAGEEXEC;
22670 + }
22671 +#endif
22672 +
22673 +#ifdef CONFIG_PAX_EMUTRAMP
22674 + if (elf_phdata->p_flags & PF_EMUTRAMP)
22675 + pax_flags |= MF_PAX_EMUTRAMP;
22676 +#endif
22677 +
22678 +#ifdef CONFIG_PAX_MPROTECT
22679 + if (elf_phdata->p_flags & PF_MPROTECT)
22680 + pax_flags |= MF_PAX_MPROTECT;
22681 +#endif
22682 +
22683 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
22684 + if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
22685 + pax_flags |= MF_PAX_RANDMMAP;
22686 +#endif
22687 +
22688 + return pax_flags;
22689 +}
22690 +#endif
22691 +
22692 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
22693 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
22694 +{
22695 + unsigned long pax_flags = 0UL;
22696 +
22697 +#ifdef CONFIG_PAX_PAGEEXEC
22698 + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
22699 + pax_flags |= MF_PAX_PAGEEXEC;
22700 +#endif
22701 +
22702 +#ifdef CONFIG_PAX_SEGMEXEC
22703 + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
22704 + pax_flags |= MF_PAX_SEGMEXEC;
22705 +#endif
22706 +
22707 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
22708 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22709 + if (nx_enabled)
22710 + pax_flags &= ~MF_PAX_SEGMEXEC;
22711 + else
22712 + pax_flags &= ~MF_PAX_PAGEEXEC;
22713 + }
22714 +#endif
22715 +
22716 +#ifdef CONFIG_PAX_EMUTRAMP
22717 + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
22718 + pax_flags |= MF_PAX_EMUTRAMP;
22719 +#endif
22720 +
22721 +#ifdef CONFIG_PAX_MPROTECT
22722 + if (!(elf_phdata->p_flags & PF_NOMPROTECT))
22723 + pax_flags |= MF_PAX_MPROTECT;
22724 +#endif
22725 +
22726 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
22727 + if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
22728 + pax_flags |= MF_PAX_RANDMMAP;
22729 +#endif
22730 +
22731 + return pax_flags;
22732 +}
22733 +#endif
22734 +
22735 +#ifdef CONFIG_PAX_EI_PAX
22736 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
22737 +{
22738 + unsigned long pax_flags = 0UL;
22739 +
22740 +#ifdef CONFIG_PAX_PAGEEXEC
22741 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
22742 + pax_flags |= MF_PAX_PAGEEXEC;
22743 +#endif
22744 +
22745 +#ifdef CONFIG_PAX_SEGMEXEC
22746 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
22747 + pax_flags |= MF_PAX_SEGMEXEC;
22748 +#endif
22749 +
22750 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
22751 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22752 + if (nx_enabled)
22753 + pax_flags &= ~MF_PAX_SEGMEXEC;
22754 + else
22755 + pax_flags &= ~MF_PAX_PAGEEXEC;
22756 + }
22757 +#endif
22758 +
22759 +#ifdef CONFIG_PAX_EMUTRAMP
22760 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
22761 + pax_flags |= MF_PAX_EMUTRAMP;
22762 +#endif
22763 +
22764 +#ifdef CONFIG_PAX_MPROTECT
22765 + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
22766 + pax_flags |= MF_PAX_MPROTECT;
22767 +#endif
22768 +
22769 +#ifdef CONFIG_PAX_ASLR
22770 + if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
22771 + pax_flags |= MF_PAX_RANDMMAP;
22772 +#endif
22773 +
22774 + return pax_flags;
22775 +}
22776 +#endif
22777 +
22778 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
22779 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
22780 +{
22781 + unsigned long pax_flags = 0UL;
22782 +
22783 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
22784 + unsigned long i;
22785 +#endif
22786 +
22787 +#ifdef CONFIG_PAX_EI_PAX
22788 + pax_flags = pax_parse_ei_pax(elf_ex);
22789 +#endif
22790 +
22791 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
22792 + for (i = 0UL; i < elf_ex->e_phnum; i++)
22793 + if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
22794 + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
22795 + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
22796 + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
22797 + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
22798 + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
22799 + return -EINVAL;
22800 +
22801 +#ifdef CONFIG_PAX_SOFTMODE
22802 + if (pax_softmode)
22803 + pax_flags = pax_parse_softmode(&elf_phdata[i]);
22804 + else
22805 +#endif
22806 +
22807 + pax_flags = pax_parse_hardmode(&elf_phdata[i]);
22808 + break;
22809 + }
22810 +#endif
22811 +
22812 + if (0 > pax_check_flags(&pax_flags))
22813 + return -EINVAL;
22814 +
22815 + current->mm->pax_flags = pax_flags;
22816 + return 0;
22817 +}
22818 +#endif
22819 +
22820 /*
22821 * These are the functions used to load ELF style executables and shared
22822 * libraries. There is no binary dependent code anywhere else.
22823 @@ -548,6 +743,11 @@ static unsigned long randomize_stack_top
22824 {
22825 unsigned int random_variable = 0;
22826
22827 +#ifdef CONFIG_PAX_RANDUSTACK
22828 + if (randomize_va_space)
22829 + return stack_top - current->mm->delta_stack;
22830 +#endif
22831 +
22832 if ((current->flags & PF_RANDOMIZE) &&
22833 !(current->personality & ADDR_NO_RANDOMIZE)) {
22834 random_variable = get_random_int() & STACK_RND_MASK;
22835 @@ -566,7 +766,7 @@ static int load_elf_binary(struct linux_
22836 unsigned long load_addr = 0, load_bias = 0;
22837 int load_addr_set = 0;
22838 char * elf_interpreter = NULL;
22839 - unsigned long error;
22840 + unsigned long error = 0;
22841 struct elf_phdr *elf_ppnt, *elf_phdata;
22842 unsigned long elf_bss, elf_brk;
22843 int retval, i;
22844 @@ -576,11 +776,11 @@ static int load_elf_binary(struct linux_
22845 unsigned long start_code, end_code, start_data, end_data;
22846 unsigned long reloc_func_desc = 0;
22847 int executable_stack = EXSTACK_DEFAULT;
22848 - unsigned long def_flags = 0;
22849 struct {
22850 struct elfhdr elf_ex;
22851 struct elfhdr interp_elf_ex;
22852 } *loc;
22853 + unsigned long pax_task_size = TASK_SIZE;
22854
22855 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
22856 if (!loc) {
22857 @@ -742,11 +942,80 @@ static int load_elf_binary(struct linux_
22858
22859 /* OK, This is the point of no return */
22860 current->flags &= ~PF_FORKNOEXEC;
22861 - current->mm->def_flags = def_flags;
22862 +
22863 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
22864 + current->mm->pax_flags = 0UL;
22865 +#endif
22866 +
22867 +#ifdef CONFIG_PAX_DLRESOLVE
22868 + current->mm->call_dl_resolve = 0UL;
22869 +#endif
22870 +
22871 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
22872 + current->mm->call_syscall = 0UL;
22873 +#endif
22874 +
22875 +#ifdef CONFIG_PAX_ASLR
22876 + current->mm->delta_mmap = 0UL;
22877 + current->mm->delta_stack = 0UL;
22878 +#endif
22879 +
22880 + current->mm->def_flags = 0;
22881 +
22882 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
22883 + if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
22884 + send_sig(SIGKILL, current, 0);
22885 + goto out_free_dentry;
22886 + }
22887 +#endif
22888 +
22889 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
22890 + pax_set_initial_flags(bprm);
22891 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
22892 + if (pax_set_initial_flags_func)
22893 + (pax_set_initial_flags_func)(bprm);
22894 +#endif
22895 +
22896 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
22897 + if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
22898 + current->mm->context.user_cs_limit = PAGE_SIZE;
22899 + current->mm->def_flags |= VM_PAGEEXEC;
22900 + }
22901 +#endif
22902 +
22903 +#ifdef CONFIG_PAX_SEGMEXEC
22904 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
22905 + current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
22906 + current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
22907 + pax_task_size = SEGMEXEC_TASK_SIZE;
22908 + }
22909 +#endif
22910 +
22911 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
22912 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22913 + set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
22914 + put_cpu();
22915 + }
22916 +#endif
22917 +
22918 +#ifdef CONFIG_PAX_ASLR
22919 + if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
22920 + current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
22921 + current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
22922 + }
22923 +#endif
22924
22925 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
22926 may depend on the personality. */
22927 SET_PERSONALITY(loc->elf_ex);
22928 +
22929 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22930 + if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22931 + executable_stack = EXSTACK_DISABLE_X;
22932 + current->personality &= ~READ_IMPLIES_EXEC;
22933 + } else
22934 +#endif
22935 +
22936 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
22937 current->personality |= READ_IMPLIES_EXEC;
22938
22939 @@ -827,6 +1096,20 @@ static int load_elf_binary(struct linux_
22940 #else
22941 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
22942 #endif
22943 +
22944 +#ifdef CONFIG_PAX_RANDMMAP
22945 + /* PaX: randomize base address at the default exe base if requested */
22946 + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
22947 +#ifdef CONFIG_SPARC64
22948 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
22949 +#else
22950 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
22951 +#endif
22952 + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
22953 + elf_flags |= MAP_FIXED;
22954 + }
22955 +#endif
22956 +
22957 }
22958
22959 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
22960 @@ -859,9 +1142,9 @@ static int load_elf_binary(struct linux_
22961 * allowed task size. Note that p_filesz must always be
22962 * <= p_memsz so it is only necessary to check p_memsz.
22963 */
22964 - if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
22965 - elf_ppnt->p_memsz > TASK_SIZE ||
22966 - TASK_SIZE - elf_ppnt->p_memsz < k) {
22967 + if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
22968 + elf_ppnt->p_memsz > pax_task_size ||
22969 + pax_task_size - elf_ppnt->p_memsz < k) {
22970 /* set_brk can never work. Avoid overflows. */
22971 send_sig(SIGKILL, current, 0);
22972 retval = -EINVAL;
22973 @@ -889,6 +1172,11 @@ static int load_elf_binary(struct linux_
22974 start_data += load_bias;
22975 end_data += load_bias;
22976
22977 +#ifdef CONFIG_PAX_RANDMMAP
22978 + if (current->mm->pax_flags & MF_PAX_RANDMMAP)
22979 + elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
22980 +#endif
22981 +
22982 /* Calling set_brk effectively mmaps the pages that we need
22983 * for the bss and break sections. We must do this before
22984 * mapping in the interpreter, to make sure it doesn't wind
22985 @@ -900,9 +1188,11 @@ static int load_elf_binary(struct linux_
22986 goto out_free_dentry;
22987 }
22988 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
22989 - send_sig(SIGSEGV, current, 0);
22990 - retval = -EFAULT; /* Nobody gets to see this, but.. */
22991 - goto out_free_dentry;
22992 + /*
22993 + * This bss-zeroing can fail if the ELF
22994 + * file specifies odd protections. So
22995 + * we don't check the return value
22996 + */
22997 }
22998
22999 if (elf_interpreter) {
23000 @@ -1135,8 +1425,10 @@ static int dump_seek(struct file *file,
23001 unsigned long n = off;
23002 if (n > PAGE_SIZE)
23003 n = PAGE_SIZE;
23004 - if (!dump_write(file, buf, n))
23005 + if (!dump_write(file, buf, n)) {
23006 + free_page((unsigned long)buf);
23007 return 0;
23008 + }
23009 off -= n;
23010 }
23011 free_page((unsigned long)buf);
23012 @@ -1148,7 +1440,7 @@ static int dump_seek(struct file *file,
23013 * Decide what to dump of a segment, part, all or none.
23014 */
23015 static unsigned long vma_dump_size(struct vm_area_struct *vma,
23016 - unsigned long mm_flags)
23017 + unsigned long mm_flags, long signr)
23018 {
23019 #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
23020
23021 @@ -1182,7 +1474,7 @@ static unsigned long vma_dump_size(struc
23022 if (vma->vm_file == NULL)
23023 return 0;
23024
23025 - if (FILTER(MAPPED_PRIVATE))
23026 + if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
23027 goto whole;
23028
23029 /*
23030 @@ -1278,8 +1570,11 @@ static int writenote(struct memelfnote *
23031 #undef DUMP_WRITE
23032
23033 #define DUMP_WRITE(addr, nr) \
23034 + do { \
23035 + gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
23036 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
23037 - goto end_coredump;
23038 + goto end_coredump; \
23039 + } while (0);
23040 #define DUMP_SEEK(off) \
23041 if (!dump_seek(file, (off))) \
23042 goto end_coredump;
23043 @@ -1991,7 +2286,7 @@ static int elf_core_dump(long signr, str
23044 phdr.p_offset = offset;
23045 phdr.p_vaddr = vma->vm_start;
23046 phdr.p_paddr = 0;
23047 - phdr.p_filesz = vma_dump_size(vma, mm_flags);
23048 + phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
23049 phdr.p_memsz = vma->vm_end - vma->vm_start;
23050 offset += phdr.p_filesz;
23051 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
23052 @@ -2023,7 +2318,7 @@ static int elf_core_dump(long signr, str
23053 unsigned long addr;
23054 unsigned long end;
23055
23056 - end = vma->vm_start + vma_dump_size(vma, mm_flags);
23057 + end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
23058
23059 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
23060 struct page *page;
23061 @@ -2043,6 +2338,7 @@ static int elf_core_dump(long signr, str
23062 flush_cache_page(tmp_vma, addr,
23063 page_to_pfn(page));
23064 kaddr = kmap(page);
23065 + gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
23066 if ((size += PAGE_SIZE) > limit ||
23067 !dump_write(file, kaddr,
23068 PAGE_SIZE)) {
23069 @@ -2073,6 +2369,97 @@ out:
23070
23071 #endif /* USE_ELF_CORE_DUMP */
23072
23073 +#ifdef CONFIG_PAX_MPROTECT
23074 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
23075 + * therefore we'll grant them VM_MAYWRITE once during their life. Similarly
23076 + * we'll remove VM_MAYWRITE for good on RELRO segments.
23077 + *
23078 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
23079 + * basis because we want to allow the common case and not the special ones.
23080 + */
23081 +static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags)
23082 +{
23083 + struct elfhdr elf_h;
23084 + struct elf_phdr elf_p;
23085 + unsigned long i;
23086 + unsigned long oldflags;
23087 + bool is_textrel_rw, is_textrel_rx, is_relro;
23088 +
23089 + if (!(vma->vm_mm->pax_flags & MF_PAX_MPROTECT))
23090 + return;
23091 +
23092 + oldflags = vma->vm_flags & (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ);
23093 + newflags &= VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ;
23094 +
23095 +#ifdef CONFIG_PAX_NOELFRELOCS
23096 + is_textrel_rw = false;
23097 + is_textrel_rx = false;
23098 +#else
23099 + /* possible TEXTREL */
23100 + is_textrel_rw = vma->vm_file && !vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYREAD | VM_EXEC | VM_READ) && newflags == (VM_WRITE | VM_READ);
23101 + is_textrel_rx = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_WRITE | VM_READ) && newflags == (VM_EXEC | VM_READ);
23102 +#endif
23103 +
23104 + /* possible RELRO */
23105 + is_relro = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ) && newflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ);
23106 +
23107 + if (!is_textrel_rw && !is_textrel_rx && !is_relro)
23108 + return;
23109 +
23110 + if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
23111 + memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
23112 +
23113 +#ifdef CONFIG_PAX_ETEXECRELOCS
23114 + ((is_textrel_rw || is_textrel_rx) && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
23115 +#else
23116 + ((is_textrel_rw || is_textrel_rx) && elf_h.e_type != ET_DYN) ||
23117 +#endif
23118 +
23119 + (is_relro && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
23120 + !elf_check_arch(&elf_h) ||
23121 + elf_h.e_phentsize != sizeof(struct elf_phdr) ||
23122 + elf_h.e_phnum > 65536UL / sizeof(struct elf_phdr))
23123 + return;
23124 +
23125 + for (i = 0UL; i < elf_h.e_phnum; i++) {
23126 + if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
23127 + return;
23128 + switch (elf_p.p_type) {
23129 + case PT_DYNAMIC:
23130 + if (!is_textrel_rw && !is_textrel_rx)
23131 + continue;
23132 + i = 0UL;
23133 + while ((i+1) * sizeof(elf_dyn) <= elf_p.p_filesz) {
23134 + elf_dyn dyn;
23135 +
23136 + if (sizeof(dyn) != kernel_read(vma->vm_file, elf_p.p_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
23137 + return;
23138 + if (dyn.d_tag == DT_NULL)
23139 + return;
23140 + if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
23141 + gr_log_textrel(vma);
23142 + if (is_textrel_rw)
23143 + vma->vm_flags |= VM_MAYWRITE;
23144 + else
23145 + /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
23146 + vma->vm_flags &= ~VM_MAYWRITE;
23147 + return;
23148 + }
23149 + i++;
23150 + }
23151 + return;
23152 +
23153 + case PT_GNU_RELRO:
23154 + if (!is_relro)
23155 + continue;
23156 + if ((elf_p.p_offset >> PAGE_SHIFT) == vma->vm_pgoff && ELF_PAGEALIGN(elf_p.p_memsz) == vma->vm_end - vma->vm_start)
23157 + vma->vm_flags &= ~VM_MAYWRITE;
23158 + return;
23159 + }
23160 + }
23161 +}
23162 +#endif
23163 +
23164 static int __init init_elf_binfmt(void)
23165 {
23166 return register_binfmt(&elf_format);
23167 diff -urNp linux-2.6.31.1/fs/binfmt_flat.c linux-2.6.31.1/fs/binfmt_flat.c
23168 --- linux-2.6.31.1/fs/binfmt_flat.c 2009-09-24 11:45:25.000000000 -0400
23169 +++ linux-2.6.31.1/fs/binfmt_flat.c 2009-10-01 20:12:44.000000000 -0400
23170 @@ -565,7 +565,9 @@ static int load_flat_file(struct linux_b
23171 realdatastart = (unsigned long) -ENOMEM;
23172 printk("Unable to allocate RAM for process data, errno %d\n",
23173 (int)-realdatastart);
23174 + down_write(&current->mm->mmap_sem);
23175 do_munmap(current->mm, textpos, text_len);
23176 + up_write(&current->mm->mmap_sem);
23177 ret = realdatastart;
23178 goto err;
23179 }
23180 @@ -589,8 +591,10 @@ static int load_flat_file(struct linux_b
23181 }
23182 if (result >= (unsigned long)-4096) {
23183 printk("Unable to read data+bss, errno %d\n", (int)-result);
23184 + down_write(&current->mm->mmap_sem);
23185 do_munmap(current->mm, textpos, text_len);
23186 do_munmap(current->mm, realdatastart, data_len + extra);
23187 + up_write(&current->mm->mmap_sem);
23188 ret = result;
23189 goto err;
23190 }
23191 @@ -659,8 +663,10 @@ static int load_flat_file(struct linux_b
23192 }
23193 if (result >= (unsigned long)-4096) {
23194 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
23195 + down_write(&current->mm->mmap_sem);
23196 do_munmap(current->mm, textpos, text_len + data_len + extra +
23197 MAX_SHARED_LIBS * sizeof(unsigned long));
23198 + up_write(&current->mm->mmap_sem);
23199 ret = result;
23200 goto err;
23201 }
23202 diff -urNp linux-2.6.31.1/fs/binfmt_misc.c linux-2.6.31.1/fs/binfmt_misc.c
23203 --- linux-2.6.31.1/fs/binfmt_misc.c 2009-09-24 11:45:25.000000000 -0400
23204 +++ linux-2.6.31.1/fs/binfmt_misc.c 2009-10-01 20:12:44.000000000 -0400
23205 @@ -693,7 +693,7 @@ static int bm_fill_super(struct super_bl
23206 static struct tree_descr bm_files[] = {
23207 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
23208 [3] = {"register", &bm_register_operations, S_IWUSR},
23209 - /* last one */ {""}
23210 + /* last one */ {"", NULL, 0}
23211 };
23212 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
23213 if (!err)
23214 diff -urNp linux-2.6.31.1/fs/btrfs/ctree.h linux-2.6.31.1/fs/btrfs/ctree.h
23215 --- linux-2.6.31.1/fs/btrfs/ctree.h 2009-09-24 11:45:25.000000000 -0400
23216 +++ linux-2.6.31.1/fs/btrfs/ctree.h 2009-10-01 20:12:44.000000000 -0400
23217 @@ -2286,7 +2286,7 @@ int btrfs_sync_file(struct file *file, s
23218 int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
23219 int skip_pinned);
23220 int btrfs_check_file(struct btrfs_root *root, struct inode *inode);
23221 -extern struct file_operations btrfs_file_operations;
23222 +extern const struct file_operations btrfs_file_operations;
23223 int btrfs_drop_extents(struct btrfs_trans_handle *trans,
23224 struct btrfs_root *root, struct inode *inode,
23225 u64 start, u64 end, u64 locked_end,
23226 diff -urNp linux-2.6.31.1/fs/btrfs/disk-io.c linux-2.6.31.1/fs/btrfs/disk-io.c
23227 --- linux-2.6.31.1/fs/btrfs/disk-io.c 2009-09-24 11:45:25.000000000 -0400
23228 +++ linux-2.6.31.1/fs/btrfs/disk-io.c 2009-10-01 20:12:44.000000000 -0400
23229 @@ -772,7 +772,7 @@ static void btree_invalidatepage(struct
23230 }
23231 }
23232
23233 -static struct address_space_operations btree_aops = {
23234 +static const struct address_space_operations btree_aops = {
23235 .readpage = btree_readpage,
23236 .writepage = btree_writepage,
23237 .writepages = btree_writepages,
23238 diff -urNp linux-2.6.31.1/fs/btrfs/file.c linux-2.6.31.1/fs/btrfs/file.c
23239 --- linux-2.6.31.1/fs/btrfs/file.c 2009-09-24 11:45:25.000000000 -0400
23240 +++ linux-2.6.31.1/fs/btrfs/file.c 2009-10-01 20:12:44.000000000 -0400
23241 @@ -1203,7 +1203,7 @@ out:
23242 return ret > 0 ? EIO : ret;
23243 }
23244
23245 -static struct vm_operations_struct btrfs_file_vm_ops = {
23246 +static const struct vm_operations_struct btrfs_file_vm_ops = {
23247 .fault = filemap_fault,
23248 .page_mkwrite = btrfs_page_mkwrite,
23249 };
23250 @@ -1215,7 +1215,7 @@ static int btrfs_file_mmap(struct file *
23251 return 0;
23252 }
23253
23254 -struct file_operations btrfs_file_operations = {
23255 +const struct file_operations btrfs_file_operations = {
23256 .llseek = generic_file_llseek,
23257 .read = do_sync_read,
23258 .aio_read = generic_file_aio_read,
23259 diff -urNp linux-2.6.31.1/fs/btrfs/inode.c linux-2.6.31.1/fs/btrfs/inode.c
23260 --- linux-2.6.31.1/fs/btrfs/inode.c 2009-09-24 11:45:25.000000000 -0400
23261 +++ linux-2.6.31.1/fs/btrfs/inode.c 2009-10-01 20:12:44.000000000 -0400
23262 @@ -55,14 +55,14 @@ struct btrfs_iget_args {
23263 struct btrfs_root *root;
23264 };
23265
23266 -static struct inode_operations btrfs_dir_inode_operations;
23267 -static struct inode_operations btrfs_symlink_inode_operations;
23268 -static struct inode_operations btrfs_dir_ro_inode_operations;
23269 -static struct inode_operations btrfs_special_inode_operations;
23270 -static struct inode_operations btrfs_file_inode_operations;
23271 -static struct address_space_operations btrfs_aops;
23272 -static struct address_space_operations btrfs_symlink_aops;
23273 -static struct file_operations btrfs_dir_file_operations;
23274 +static const struct inode_operations btrfs_dir_inode_operations;
23275 +static const struct inode_operations btrfs_symlink_inode_operations;
23276 +static const struct inode_operations btrfs_dir_ro_inode_operations;
23277 +static const struct inode_operations btrfs_special_inode_operations;
23278 +static const struct inode_operations btrfs_file_inode_operations;
23279 +static const struct address_space_operations btrfs_aops;
23280 +static const struct address_space_operations btrfs_symlink_aops;
23281 +static const struct file_operations btrfs_dir_file_operations;
23282 static struct extent_io_ops btrfs_extent_io_ops;
23283
23284 static struct kmem_cache *btrfs_inode_cachep;
23285 @@ -5201,7 +5201,7 @@ static int btrfs_permission(struct inode
23286 return generic_permission(inode, mask, btrfs_check_acl);
23287 }
23288
23289 -static struct inode_operations btrfs_dir_inode_operations = {
23290 +static const struct inode_operations btrfs_dir_inode_operations = {
23291 .getattr = btrfs_getattr,
23292 .lookup = btrfs_lookup,
23293 .create = btrfs_create,
23294 @@ -5219,11 +5219,11 @@ static struct inode_operations btrfs_dir
23295 .removexattr = btrfs_removexattr,
23296 .permission = btrfs_permission,
23297 };
23298 -static struct inode_operations btrfs_dir_ro_inode_operations = {
23299 +static const struct inode_operations btrfs_dir_ro_inode_operations = {
23300 .lookup = btrfs_lookup,
23301 .permission = btrfs_permission,
23302 };
23303 -static struct file_operations btrfs_dir_file_operations = {
23304 +static const struct file_operations btrfs_dir_file_operations = {
23305 .llseek = generic_file_llseek,
23306 .read = generic_read_dir,
23307 .readdir = btrfs_real_readdir,
23308 @@ -5259,7 +5259,7 @@ static struct extent_io_ops btrfs_extent
23309 *
23310 * For now we're avoiding this by dropping bmap.
23311 */
23312 -static struct address_space_operations btrfs_aops = {
23313 +static const struct address_space_operations btrfs_aops = {
23314 .readpage = btrfs_readpage,
23315 .writepage = btrfs_writepage,
23316 .writepages = btrfs_writepages,
23317 @@ -5271,14 +5271,14 @@ static struct address_space_operations b
23318 .set_page_dirty = btrfs_set_page_dirty,
23319 };
23320
23321 -static struct address_space_operations btrfs_symlink_aops = {
23322 +static const struct address_space_operations btrfs_symlink_aops = {
23323 .readpage = btrfs_readpage,
23324 .writepage = btrfs_writepage,
23325 .invalidatepage = btrfs_invalidatepage,
23326 .releasepage = btrfs_releasepage,
23327 };
23328
23329 -static struct inode_operations btrfs_file_inode_operations = {
23330 +static const struct inode_operations btrfs_file_inode_operations = {
23331 .truncate = btrfs_truncate,
23332 .getattr = btrfs_getattr,
23333 .setattr = btrfs_setattr,
23334 @@ -5290,7 +5290,7 @@ static struct inode_operations btrfs_fil
23335 .fallocate = btrfs_fallocate,
23336 .fiemap = btrfs_fiemap,
23337 };
23338 -static struct inode_operations btrfs_special_inode_operations = {
23339 +static const struct inode_operations btrfs_special_inode_operations = {
23340 .getattr = btrfs_getattr,
23341 .setattr = btrfs_setattr,
23342 .permission = btrfs_permission,
23343 @@ -5299,7 +5299,7 @@ static struct inode_operations btrfs_spe
23344 .listxattr = btrfs_listxattr,
23345 .removexattr = btrfs_removexattr,
23346 };
23347 -static struct inode_operations btrfs_symlink_inode_operations = {
23348 +static const struct inode_operations btrfs_symlink_inode_operations = {
23349 .readlink = generic_readlink,
23350 .follow_link = page_follow_link_light,
23351 .put_link = page_put_link,
23352 diff -urNp linux-2.6.31.1/fs/btrfs/super.c linux-2.6.31.1/fs/btrfs/super.c
23353 --- linux-2.6.31.1/fs/btrfs/super.c 2009-09-24 11:45:25.000000000 -0400
23354 +++ linux-2.6.31.1/fs/btrfs/super.c 2009-10-01 20:12:44.000000000 -0400
23355 @@ -51,7 +51,7 @@
23356 #include "export.h"
23357 #include "compression.h"
23358
23359 -static struct super_operations btrfs_super_ops;
23360 +static const struct super_operations btrfs_super_ops;
23361
23362 static void btrfs_put_super(struct super_block *sb)
23363 {
23364 @@ -675,7 +675,7 @@ static int btrfs_unfreeze(struct super_b
23365 return 0;
23366 }
23367
23368 -static struct super_operations btrfs_super_ops = {
23369 +static const struct super_operations btrfs_super_ops = {
23370 .delete_inode = btrfs_delete_inode,
23371 .put_super = btrfs_put_super,
23372 .sync_fs = btrfs_sync_fs,
23373 diff -urNp linux-2.6.31.1/fs/buffer.c linux-2.6.31.1/fs/buffer.c
23374 --- linux-2.6.31.1/fs/buffer.c 2009-09-24 11:45:25.000000000 -0400
23375 +++ linux-2.6.31.1/fs/buffer.c 2009-10-01 20:12:44.000000000 -0400
23376 @@ -25,6 +25,7 @@
23377 #include <linux/percpu.h>
23378 #include <linux/slab.h>
23379 #include <linux/capability.h>
23380 +#include <linux/security.h>
23381 #include <linux/blkdev.h>
23382 #include <linux/file.h>
23383 #include <linux/quotaops.h>
23384 @@ -2233,6 +2234,7 @@ int generic_cont_expand_simple(struct in
23385
23386 err = -EFBIG;
23387 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
23388 + gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
23389 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
23390 send_sig(SIGXFSZ, current, 0);
23391 goto out;
23392 diff -urNp linux-2.6.31.1/fs/cifs/cifs_dfs_ref.c linux-2.6.31.1/fs/cifs/cifs_dfs_ref.c
23393 --- linux-2.6.31.1/fs/cifs/cifs_dfs_ref.c 2009-09-24 11:45:25.000000000 -0400
23394 +++ linux-2.6.31.1/fs/cifs/cifs_dfs_ref.c 2009-10-01 20:12:44.000000000 -0400
23395 @@ -385,7 +385,7 @@ out_err:
23396 goto out;
23397 }
23398
23399 -struct inode_operations cifs_dfs_referral_inode_operations = {
23400 +const struct inode_operations cifs_dfs_referral_inode_operations = {
23401 .follow_link = cifs_dfs_follow_mountpoint,
23402 };
23403
23404 diff -urNp linux-2.6.31.1/fs/cifs/cifsfs.h linux-2.6.31.1/fs/cifs/cifsfs.h
23405 --- linux-2.6.31.1/fs/cifs/cifsfs.h 2009-09-24 11:45:25.000000000 -0400
23406 +++ linux-2.6.31.1/fs/cifs/cifsfs.h 2009-10-01 20:12:44.000000000 -0400
23407 @@ -67,7 +67,7 @@ extern int cifs_setattr(struct dentry *,
23408
23409 extern const struct inode_operations cifs_file_inode_ops;
23410 extern const struct inode_operations cifs_symlink_inode_ops;
23411 -extern struct inode_operations cifs_dfs_referral_inode_operations;
23412 +extern const struct inode_operations cifs_dfs_referral_inode_operations;
23413
23414
23415 /* Functions related to files and directories */
23416 diff -urNp linux-2.6.31.1/fs/cifs/cifs_uniupr.h linux-2.6.31.1/fs/cifs/cifs_uniupr.h
23417 --- linux-2.6.31.1/fs/cifs/cifs_uniupr.h 2009-09-24 11:45:25.000000000 -0400
23418 +++ linux-2.6.31.1/fs/cifs/cifs_uniupr.h 2009-10-01 20:12:44.000000000 -0400
23419 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
23420 {0x0490, 0x04cc, UniCaseRangeU0490},
23421 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
23422 {0xff40, 0xff5a, UniCaseRangeUff40},
23423 - {0}
23424 + {0, 0, NULL}
23425 };
23426 #endif
23427
23428 diff -urNp linux-2.6.31.1/fs/cifs/link.c linux-2.6.31.1/fs/cifs/link.c
23429 --- linux-2.6.31.1/fs/cifs/link.c 2009-09-24 11:45:25.000000000 -0400
23430 +++ linux-2.6.31.1/fs/cifs/link.c 2009-10-01 20:12:44.000000000 -0400
23431 @@ -215,7 +215,7 @@ cifs_symlink(struct inode *inode, struct
23432
23433 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
23434 {
23435 - char *p = nd_get_link(nd);
23436 + const char *p = nd_get_link(nd);
23437 if (!IS_ERR(p))
23438 kfree(p);
23439 }
23440 diff -urNp linux-2.6.31.1/fs/compat_binfmt_elf.c linux-2.6.31.1/fs/compat_binfmt_elf.c
23441 --- linux-2.6.31.1/fs/compat_binfmt_elf.c 2009-09-24 11:45:25.000000000 -0400
23442 +++ linux-2.6.31.1/fs/compat_binfmt_elf.c 2009-10-01 20:12:44.000000000 -0400
23443 @@ -29,10 +29,12 @@
23444 #undef elfhdr
23445 #undef elf_phdr
23446 #undef elf_note
23447 +#undef elf_dyn
23448 #undef elf_addr_t
23449 #define elfhdr elf32_hdr
23450 #define elf_phdr elf32_phdr
23451 #define elf_note elf32_note
23452 +#define elf_dyn Elf32_Dyn
23453 #define elf_addr_t Elf32_Addr
23454
23455 /*
23456 diff -urNp linux-2.6.31.1/fs/compat.c linux-2.6.31.1/fs/compat.c
23457 --- linux-2.6.31.1/fs/compat.c 2009-09-24 11:45:25.000000000 -0400
23458 +++ linux-2.6.31.1/fs/compat.c 2009-10-01 20:12:44.000000000 -0400
23459 @@ -1417,14 +1417,12 @@ static int compat_copy_strings(int argc,
23460 if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
23461 struct page *page;
23462
23463 -#ifdef CONFIG_STACK_GROWSUP
23464 ret = expand_stack_downwards(bprm->vma, pos);
23465 if (ret < 0) {
23466 /* We've exceed the stack rlimit. */
23467 ret = -E2BIG;
23468 goto out;
23469 }
23470 -#endif
23471 ret = get_user_pages(current, bprm->mm, pos,
23472 1, 1, 1, &page, NULL);
23473 if (ret <= 0) {
23474 @@ -1470,6 +1468,11 @@ int compat_do_execve(char * filename,
23475 compat_uptr_t __user *envp,
23476 struct pt_regs * regs)
23477 {
23478 +#ifdef CONFIG_GRKERNSEC
23479 + struct file *old_exec_file;
23480 + struct acl_subject_label *old_acl;
23481 + struct rlimit old_rlim[RLIM_NLIMITS];
23482 +#endif
23483 struct linux_binprm *bprm;
23484 struct file *file;
23485 struct files_struct *displaced;
23486 @@ -1506,6 +1509,14 @@ int compat_do_execve(char * filename,
23487 bprm->filename = filename;
23488 bprm->interp = filename;
23489
23490 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->cred->user->processes), 1);
23491 + retval = -EAGAIN;
23492 + if (gr_handle_nproc())
23493 + goto out_file;
23494 + retval = -EACCES;
23495 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
23496 + goto out_file;
23497 +
23498 retval = bprm_mm_init(bprm);
23499 if (retval)
23500 goto out_file;
23501 @@ -1535,9 +1546,40 @@ int compat_do_execve(char * filename,
23502 if (retval < 0)
23503 goto out;
23504
23505 + if (!gr_tpe_allow(file)) {
23506 + retval = -EACCES;
23507 + goto out;
23508 + }
23509 +
23510 + if (gr_check_crash_exec(file)) {
23511 + retval = -EACCES;
23512 + goto out;
23513 + }
23514 +
23515 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
23516 +
23517 + gr_handle_exec_args(bprm, (char __user * __user *)argv);
23518 +
23519 +#ifdef CONFIG_GRKERNSEC
23520 + old_acl = current->acl;
23521 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
23522 + old_exec_file = current->exec_file;
23523 + get_file(file);
23524 + current->exec_file = file;
23525 +#endif
23526 +
23527 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
23528 + bprm->unsafe & LSM_UNSAFE_SHARE);
23529 + if (retval < 0)
23530 + goto out_fail;
23531 +
23532 retval = search_binary_handler(bprm, regs);
23533 if (retval < 0)
23534 - goto out;
23535 + goto out_fail;
23536 +#ifdef CONFIG_GRKERNSEC
23537 + if (old_exec_file)
23538 + fput(old_exec_file);
23539 +#endif
23540
23541 /* execve succeeded */
23542 current->fs->in_exec = 0;
23543 @@ -1548,6 +1590,14 @@ int compat_do_execve(char * filename,
23544 put_files_struct(displaced);
23545 return retval;
23546
23547 +out_fail:
23548 +#ifdef CONFIG_GRKERNSEC
23549 + current->acl = old_acl;
23550 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
23551 + fput(current->exec_file);
23552 + current->exec_file = old_exec_file;
23553 +#endif
23554 +
23555 out:
23556 if (bprm->mm)
23557 mmput(bprm->mm);
23558 diff -urNp linux-2.6.31.1/fs/compat_ioctl.c linux-2.6.31.1/fs/compat_ioctl.c
23559 --- linux-2.6.31.1/fs/compat_ioctl.c 2009-09-24 11:45:25.000000000 -0400
23560 +++ linux-2.6.31.1/fs/compat_ioctl.c 2009-10-01 20:12:44.000000000 -0400
23561 @@ -1827,15 +1827,15 @@ struct ioctl_trans {
23562 };
23563
23564 #define HANDLE_IOCTL(cmd,handler) \
23565 - { (cmd), (ioctl_trans_handler_t)(handler) },
23566 + { (cmd), (ioctl_trans_handler_t)(handler), NULL },
23567
23568 /* pointer to compatible structure or no argument */
23569 #define COMPATIBLE_IOCTL(cmd) \
23570 - { (cmd), do_ioctl32_pointer },
23571 + { (cmd), do_ioctl32_pointer, NULL },
23572
23573 /* argument is an unsigned long integer, not a pointer */
23574 #define ULONG_IOCTL(cmd) \
23575 - { (cmd), (ioctl_trans_handler_t)sys_ioctl },
23576 + { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
23577
23578 /* ioctl should not be warned about even if it's not implemented.
23579 Valid reasons to use this:
23580 diff -urNp linux-2.6.31.1/fs/debugfs/inode.c linux-2.6.31.1/fs/debugfs/inode.c
23581 --- linux-2.6.31.1/fs/debugfs/inode.c 2009-09-24 11:45:25.000000000 -0400
23582 +++ linux-2.6.31.1/fs/debugfs/inode.c 2009-10-01 20:12:44.000000000 -0400
23583 @@ -118,7 +118,7 @@ static inline int debugfs_positive(struc
23584
23585 static int debug_fill_super(struct super_block *sb, void *data, int silent)
23586 {
23587 - static struct tree_descr debug_files[] = {{""}};
23588 + static struct tree_descr debug_files[] = {{"", NULL, 0}};
23589
23590 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
23591 }
23592 diff -urNp linux-2.6.31.1/fs/dlm/debug_fs.c linux-2.6.31.1/fs/dlm/debug_fs.c
23593 --- linux-2.6.31.1/fs/dlm/debug_fs.c 2009-09-24 11:45:25.000000000 -0400
23594 +++ linux-2.6.31.1/fs/dlm/debug_fs.c 2009-10-01 20:12:44.000000000 -0400
23595 @@ -386,9 +386,9 @@ static int table_seq_show(struct seq_fil
23596 return rv;
23597 }
23598
23599 -static struct seq_operations format1_seq_ops;
23600 -static struct seq_operations format2_seq_ops;
23601 -static struct seq_operations format3_seq_ops;
23602 +static const struct seq_operations format1_seq_ops;
23603 +static const struct seq_operations format2_seq_ops;
23604 +static const struct seq_operations format3_seq_ops;
23605
23606 static void *table_seq_start(struct seq_file *seq, loff_t *pos)
23607 {
23608 @@ -534,21 +534,21 @@ static void table_seq_stop(struct seq_fi
23609 }
23610 }
23611
23612 -static struct seq_operations format1_seq_ops = {
23613 +static const struct seq_operations format1_seq_ops = {
23614 .start = table_seq_start,
23615 .next = table_seq_next,
23616 .stop = table_seq_stop,
23617 .show = table_seq_show,
23618 };
23619
23620 -static struct seq_operations format2_seq_ops = {
23621 +static const struct seq_operations format2_seq_ops = {
23622 .start = table_seq_start,
23623 .next = table_seq_next,
23624 .stop = table_seq_stop,
23625 .show = table_seq_show,
23626 };
23627
23628 -static struct seq_operations format3_seq_ops = {
23629 +static const struct seq_operations format3_seq_ops = {
23630 .start = table_seq_start,
23631 .next = table_seq_next,
23632 .stop = table_seq_stop,
23633 diff -urNp linux-2.6.31.1/fs/ecryptfs/ecryptfs_kernel.h linux-2.6.31.1/fs/ecryptfs/ecryptfs_kernel.h
23634 --- linux-2.6.31.1/fs/ecryptfs/ecryptfs_kernel.h 2009-09-24 11:45:25.000000000 -0400
23635 +++ linux-2.6.31.1/fs/ecryptfs/ecryptfs_kernel.h 2009-10-01 20:12:44.000000000 -0400
23636 @@ -582,7 +582,7 @@ extern const struct inode_operations ecr
23637 extern const struct inode_operations ecryptfs_symlink_iops;
23638 extern const struct super_operations ecryptfs_sops;
23639 extern const struct dentry_operations ecryptfs_dops;
23640 -extern struct address_space_operations ecryptfs_aops;
23641 +extern const struct address_space_operations ecryptfs_aops;
23642 extern int ecryptfs_verbosity;
23643 extern unsigned int ecryptfs_message_buf_len;
23644 extern signed long ecryptfs_message_wait_timeout;
23645 diff -urNp linux-2.6.31.1/fs/ecryptfs/mmap.c linux-2.6.31.1/fs/ecryptfs/mmap.c
23646 --- linux-2.6.31.1/fs/ecryptfs/mmap.c 2009-09-24 11:45:25.000000000 -0400
23647 +++ linux-2.6.31.1/fs/ecryptfs/mmap.c 2009-10-01 20:12:44.000000000 -0400
23648 @@ -545,7 +545,7 @@ static sector_t ecryptfs_bmap(struct add
23649 return rc;
23650 }
23651
23652 -struct address_space_operations ecryptfs_aops = {
23653 +const struct address_space_operations ecryptfs_aops = {
23654 .writepage = ecryptfs_writepage,
23655 .readpage = ecryptfs_readpage,
23656 .write_begin = ecryptfs_write_begin,
23657 diff -urNp linux-2.6.31.1/fs/exec.c linux-2.6.31.1/fs/exec.c
23658 --- linux-2.6.31.1/fs/exec.c 2009-09-24 11:45:25.000000000 -0400
23659 +++ linux-2.6.31.1/fs/exec.c 2009-10-01 20:12:44.000000000 -0400
23660 @@ -55,12 +55,24 @@
23661 #include <linux/kmod.h>
23662 #include <linux/fsnotify.h>
23663 #include <linux/fs_struct.h>
23664 +#include <linux/random.h>
23665 +#include <linux/seq_file.h>
23666 +
23667 +#ifdef CONFIG_PAX_REFCOUNT
23668 +#include <linux/kallsyms.h>
23669 +#include <linux/kdebug.h>
23670 +#endif
23671
23672 #include <asm/uaccess.h>
23673 #include <asm/mmu_context.h>
23674 #include <asm/tlb.h>
23675 #include "internal.h"
23676
23677 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
23678 +void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
23679 +EXPORT_SYMBOL(pax_set_initial_flags_func);
23680 +#endif
23681 +
23682 int core_uses_pid;
23683 char core_pattern[CORENAME_MAX_SIZE] = "core";
23684 int suid_dumpable = 0;
23685 @@ -113,7 +125,7 @@ SYSCALL_DEFINE1(uselib, const char __use
23686 goto out;
23687
23688 file = do_filp_open(AT_FDCWD, tmp,
23689 - O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
23690 + O_LARGEFILE | O_RDONLY | FMODE_EXEC | FMODE_GREXEC, 0,
23691 MAY_READ | MAY_EXEC | MAY_OPEN);
23692 putname(tmp);
23693 error = PTR_ERR(file);
23694 @@ -161,18 +173,10 @@ static struct page *get_arg_page(struct
23695 int write)
23696 {
23697 struct page *page;
23698 - int ret;
23699
23700 -#ifdef CONFIG_STACK_GROWSUP
23701 - if (write) {
23702 - ret = expand_stack_downwards(bprm->vma, pos);
23703 - if (ret < 0)
23704 - return NULL;
23705 - }
23706 -#endif
23707 - ret = get_user_pages(current, bprm->mm, pos,
23708 - 1, write, 1, &page, NULL);
23709 - if (ret <= 0)
23710 + if (0 > expand_stack_downwards(bprm->vma, pos))
23711 + return NULL;
23712 + if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
23713 return NULL;
23714
23715 if (write) {
23716 @@ -244,6 +248,11 @@ static int __bprm_mm_init(struct linux_b
23717 vma->vm_end = STACK_TOP_MAX;
23718 vma->vm_start = vma->vm_end - PAGE_SIZE;
23719 vma->vm_flags = VM_STACK_FLAGS;
23720 +
23721 +#ifdef CONFIG_PAX_SEGMEXEC
23722 + vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
23723 +#endif
23724 +
23725 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
23726 err = insert_vm_struct(mm, vma);
23727 if (err)
23728 @@ -252,6 +261,12 @@ static int __bprm_mm_init(struct linux_b
23729 mm->stack_vm = mm->total_vm = 1;
23730 up_write(&mm->mmap_sem);
23731 bprm->p = vma->vm_end - sizeof(void *);
23732 +
23733 +#ifdef CONFIG_PAX_RANDUSTACK
23734 + if (randomize_va_space)
23735 + bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
23736 +#endif
23737 +
23738 return 0;
23739 err:
23740 up_write(&mm->mmap_sem);
23741 @@ -503,7 +518,8 @@ static int shift_arg_pages(struct vm_are
23742 unsigned long new_end = old_end - shift;
23743 struct mmu_gather *tlb;
23744
23745 - BUG_ON(new_start > new_end);
23746 + if (new_start >= new_end || new_start < mmap_min_addr)
23747 + return -EFAULT;
23748
23749 /*
23750 * ensure there are no vmas between where we want to go
23751 @@ -512,6 +528,10 @@ static int shift_arg_pages(struct vm_are
23752 if (vma != find_vma(mm, new_start))
23753 return -EFAULT;
23754
23755 +#ifdef CONFIG_PAX_SEGMEXEC
23756 + BUG_ON(pax_find_mirror_vma(vma));
23757 +#endif
23758 +
23759 /*
23760 * cover the whole range: [new_start, old_end)
23761 */
23762 @@ -600,6 +620,14 @@ int setup_arg_pages(struct linux_binprm
23763 bprm->exec -= stack_shift;
23764
23765 down_write(&mm->mmap_sem);
23766 +
23767 + /* Move stack pages down in memory. */
23768 + if (stack_shift) {
23769 + ret = shift_arg_pages(vma, stack_shift);
23770 + if (ret)
23771 + goto out_unlock;
23772 + }
23773 +
23774 vm_flags = VM_STACK_FLAGS;
23775
23776 /*
23777 @@ -613,21 +641,24 @@ int setup_arg_pages(struct linux_binprm
23778 vm_flags &= ~VM_EXEC;
23779 vm_flags |= mm->def_flags;
23780
23781 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
23782 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
23783 + vm_flags &= ~VM_EXEC;
23784 +
23785 +#ifdef CONFIG_PAX_MPROTECT
23786 + if (mm->pax_flags & MF_PAX_MPROTECT)
23787 + vm_flags &= ~VM_MAYEXEC;
23788 +#endif
23789 +
23790 + }
23791 +#endif
23792 +
23793 ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
23794 vm_flags);
23795 if (ret)
23796 goto out_unlock;
23797 BUG_ON(prev != vma);
23798
23799 - /* Move stack pages down in memory. */
23800 - if (stack_shift) {
23801 - ret = shift_arg_pages(vma, stack_shift);
23802 - if (ret) {
23803 - up_write(&mm->mmap_sem);
23804 - return ret;
23805 - }
23806 - }
23807 -
23808 #ifdef CONFIG_STACK_GROWSUP
23809 stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
23810 #else
23811 @@ -639,7 +670,7 @@ int setup_arg_pages(struct linux_binprm
23812
23813 out_unlock:
23814 up_write(&mm->mmap_sem);
23815 - return 0;
23816 + return ret;
23817 }
23818 EXPORT_SYMBOL(setup_arg_pages);
23819
23820 @@ -651,7 +682,7 @@ struct file *open_exec(const char *name)
23821 int err;
23822
23823 file = do_filp_open(AT_FDCWD, name,
23824 - O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
23825 + O_LARGEFILE | O_RDONLY | FMODE_EXEC | FMODE_GREXEC, 0,
23826 MAY_EXEC | MAY_OPEN);
23827 if (IS_ERR(file))
23828 goto out;
23829 @@ -1085,7 +1116,7 @@ int check_unsafe_exec(struct linux_binpr
23830 }
23831 rcu_read_unlock();
23832
23833 - if (p->fs->users > n_fs) {
23834 + if (atomic_read(&p->fs->users) > n_fs) {
23835 bprm->unsafe |= LSM_UNSAFE_SHARE;
23836 } else {
23837 res = -EAGAIN;
23838 @@ -1284,6 +1315,11 @@ int do_execve(char * filename,
23839 char __user *__user *envp,
23840 struct pt_regs * regs)
23841 {
23842 +#ifdef CONFIG_GRKERNSEC
23843 + struct file *old_exec_file;
23844 + struct acl_subject_label *old_acl;
23845 + struct rlimit old_rlim[RLIM_NLIMITS];
23846 +#endif
23847 struct linux_binprm *bprm;
23848 struct file *file;
23849 struct files_struct *displaced;
23850 @@ -1320,6 +1356,18 @@ int do_execve(char * filename,
23851 bprm->filename = filename;
23852 bprm->interp = filename;
23853
23854 + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->cred->user->processes), 1);
23855 +
23856 + if (gr_handle_nproc()) {
23857 + retval = -EAGAIN;
23858 + goto out_file;
23859 + }
23860 +
23861 + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
23862 + retval = -EACCES;
23863 + goto out_file;
23864 + }
23865 +
23866 retval = bprm_mm_init(bprm);
23867 if (retval)
23868 goto out_file;
23869 @@ -1349,10 +1397,41 @@ int do_execve(char * filename,
23870 if (retval < 0)
23871 goto out;
23872
23873 + if (!gr_tpe_allow(file)) {
23874 + retval = -EACCES;
23875 + goto out;
23876 + }
23877 +
23878 + if (gr_check_crash_exec(file)) {
23879 + retval = -EACCES;
23880 + goto out;
23881 + }
23882 +
23883 + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
23884 +
23885 + gr_handle_exec_args(bprm, argv);
23886 +
23887 +#ifdef CONFIG_GRKERNSEC
23888 + old_acl = current->acl;
23889 + memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
23890 + old_exec_file = current->exec_file;
23891 + get_file(file);
23892 + current->exec_file = file;
23893 +#endif
23894 +
23895 + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
23896 + bprm->unsafe & LSM_UNSAFE_SHARE);
23897 + if (retval < 0)
23898 + goto out_fail;
23899 +
23900 current->flags &= ~PF_KTHREAD;
23901 retval = search_binary_handler(bprm,regs);
23902 if (retval < 0)
23903 - goto out;
23904 + goto out_fail;
23905 +#ifdef CONFIG_GRKERNSEC
23906 + if (old_exec_file)
23907 + fput(old_exec_file);
23908 +#endif
23909
23910 /* execve succeeded */
23911 current->fs->in_exec = 0;
23912 @@ -1363,6 +1442,14 @@ int do_execve(char * filename,
23913 put_files_struct(displaced);
23914 return retval;
23915
23916 +out_fail:
23917 +#ifdef CONFIG_GRKERNSEC
23918 + current->acl = old_acl;
23919 + memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
23920 + fput(current->exec_file);
23921 + current->exec_file = old_exec_file;
23922 +#endif
23923 +
23924 out:
23925 if (bprm->mm)
23926 mmput (bprm->mm);
23927 @@ -1528,6 +1615,164 @@ out:
23928 return ispipe;
23929 }
23930
23931 +int pax_check_flags(unsigned long *flags)
23932 +{
23933 + int retval = 0;
23934 +
23935 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
23936 + if (*flags & MF_PAX_SEGMEXEC)
23937 + {
23938 + *flags &= ~MF_PAX_SEGMEXEC;
23939 + retval = -EINVAL;
23940 + }
23941 +#endif
23942 +
23943 + if ((*flags & MF_PAX_PAGEEXEC)
23944 +
23945 +#ifdef CONFIG_PAX_PAGEEXEC
23946 + && (*flags & MF_PAX_SEGMEXEC)
23947 +#endif
23948 +
23949 + )
23950 + {
23951 + *flags &= ~MF_PAX_PAGEEXEC;
23952 + retval = -EINVAL;
23953 + }
23954 +
23955 + if ((*flags & MF_PAX_MPROTECT)
23956 +
23957 +#ifdef CONFIG_PAX_MPROTECT
23958 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
23959 +#endif
23960 +
23961 + )
23962 + {
23963 + *flags &= ~MF_PAX_MPROTECT;
23964 + retval = -EINVAL;
23965 + }
23966 +
23967 + if ((*flags & MF_PAX_EMUTRAMP)
23968 +
23969 +#ifdef CONFIG_PAX_EMUTRAMP
23970 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
23971 +#endif
23972 +
23973 + )
23974 + {
23975 + *flags &= ~MF_PAX_EMUTRAMP;
23976 + retval = -EINVAL;
23977 + }
23978 +
23979 + return retval;
23980 +}
23981 +
23982 +EXPORT_SYMBOL(pax_check_flags);
23983 +
23984 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
23985 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
23986 +{
23987 + struct task_struct *tsk = current;
23988 + struct mm_struct *mm = current->mm;
23989 + char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
23990 + char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
23991 + char *path_exec = NULL;
23992 + char *path_fault = NULL;
23993 + unsigned long start = 0UL, end = 0UL, offset = 0UL;
23994 +
23995 + if (buffer_exec && buffer_fault) {
23996 + struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
23997 +
23998 + down_read(&mm->mmap_sem);
23999 + vma = mm->mmap;
24000 + while (vma && (!vma_exec || !vma_fault)) {
24001 + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
24002 + vma_exec = vma;
24003 + if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
24004 + vma_fault = vma;
24005 + vma = vma->vm_next;
24006 + }
24007 + if (vma_exec) {
24008 + path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
24009 + if (IS_ERR(path_exec))
24010 + path_exec = "<path too long>";
24011 + else {
24012 + path_exec = mangle_path(buffer_exec, path_exec, "\t\n\\");
24013 + if (path_exec) {
24014 + *path_exec = 0;
24015 + path_exec = buffer_exec;
24016 + } else
24017 + path_exec = "<path too long>";
24018 + }
24019 + }
24020 + if (vma_fault) {
24021 + start = vma_fault->vm_start;
24022 + end = vma_fault->vm_end;
24023 + offset = vma_fault->vm_pgoff << PAGE_SHIFT;
24024 + if (vma_fault->vm_file) {
24025 + path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
24026 + if (IS_ERR(path_fault))
24027 + path_fault = "<path too long>";
24028 + else {
24029 + path_fault = mangle_path(buffer_fault, path_fault, "\t\n\\");
24030 + if (path_fault) {
24031 + *path_fault = 0;
24032 + path_fault = buffer_fault;
24033 + } else
24034 + path_fault = "<path too long>";
24035 + }
24036 + } else
24037 + path_fault = "<anonymous mapping>";
24038 + }
24039 + up_read(&mm->mmap_sem);
24040 + }
24041 + if (tsk->signal->curr_ip)
24042 + 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);
24043 + else
24044 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
24045 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
24046 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
24047 + task_uid(tsk), task_euid(tsk), pc, sp);
24048 + free_page((unsigned long)buffer_exec);
24049 + free_page((unsigned long)buffer_fault);
24050 + pax_report_insns(pc, sp);
24051 + do_coredump(SIGKILL, SIGKILL, regs);
24052 +}
24053 +#endif
24054 +
24055 +#ifdef CONFIG_PAX_REFCOUNT
24056 +void pax_report_refcount_overflow(struct pt_regs *regs)
24057 +{
24058 + if (current->signal->curr_ip)
24059 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
24060 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current_uid(), current_euid());
24061 + else
24062 + printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
24063 + current->comm, task_pid_nr(current), current_uid(), current_euid());
24064 + print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
24065 + show_regs(regs);
24066 + force_sig_specific(SIGKILL, current);
24067 +}
24068 +#endif
24069 +
24070 +#ifdef CONFIG_PAX_USERCOPY
24071 +void pax_report_leak_to_user(const void *ptr, unsigned long len)
24072 +{
24073 + if (current->signal->curr_ip)
24074 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: kernel memory leak attempt detected from %p (%lu bytes)\n", NIPQUAD(current->signal->curr_ip), ptr, len);
24075 + else
24076 + printk(KERN_ERR "PAX: kernel memory leak attempt detected from %p (%lu bytes)\n", ptr, len);
24077 + dump_stack();
24078 + do_group_exit(SIGKILL);
24079 +}
24080 +
24081 +void pax_report_overflow_from_user(const void *ptr, unsigned long len)
24082 +{
24083 + printk(KERN_ERR "PAX: kernel memory overflow attempt detected to %p (%lu bytes)\n", ptr, len);
24084 + dump_stack();
24085 + do_group_exit(SIGKILL);
24086 +}
24087 +#endif
24088 +
24089 static int zap_process(struct task_struct *start)
24090 {
24091 struct task_struct *t;
24092 @@ -1787,6 +2032,10 @@ void do_coredump(long signr, int exit_co
24093 */
24094 clear_thread_flag(TIF_SIGPENDING);
24095
24096 + if (signr == SIGKILL || signr == SIGILL)
24097 + gr_handle_brute_attach(current);
24098 + gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
24099 +
24100 /*
24101 * lock_kernel() because format_corename() is controlled by sysctl, which
24102 * uses lock_kernel()
24103 diff -urNp linux-2.6.31.1/fs/ext2/balloc.c linux-2.6.31.1/fs/ext2/balloc.c
24104 --- linux-2.6.31.1/fs/ext2/balloc.c 2009-09-24 11:45:25.000000000 -0400
24105 +++ linux-2.6.31.1/fs/ext2/balloc.c 2009-10-01 20:12:44.000000000 -0400
24106 @@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
24107
24108 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
24109 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
24110 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
24111 + if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
24112 sbi->s_resuid != current_fsuid() &&
24113 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
24114 return 0;
24115 diff -urNp linux-2.6.31.1/fs/ext3/balloc.c linux-2.6.31.1/fs/ext3/balloc.c
24116 --- linux-2.6.31.1/fs/ext3/balloc.c 2009-09-24 11:45:25.000000000 -0400
24117 +++ linux-2.6.31.1/fs/ext3/balloc.c 2009-10-01 20:12:44.000000000 -0400
24118 @@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e
24119
24120 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
24121 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
24122 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
24123 + if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
24124 sbi->s_resuid != current_fsuid() &&
24125 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
24126 return 0;
24127 diff -urNp linux-2.6.31.1/fs/ext3/namei.c linux-2.6.31.1/fs/ext3/namei.c
24128 --- linux-2.6.31.1/fs/ext3/namei.c 2009-09-24 11:45:25.000000000 -0400
24129 +++ linux-2.6.31.1/fs/ext3/namei.c 2009-10-01 20:12:44.000000000 -0400
24130 @@ -1168,7 +1168,7 @@ static struct ext3_dir_entry_2 *do_split
24131 char *data1 = (*bh)->b_data, *data2;
24132 unsigned split, move, size;
24133 struct ext3_dir_entry_2 *de = NULL, *de2;
24134 - int err = 0, i;
24135 + int i, err = 0;
24136
24137 bh2 = ext3_append (handle, dir, &newblock, &err);
24138 if (!(bh2)) {
24139 diff -urNp linux-2.6.31.1/fs/ext3/xattr.c linux-2.6.31.1/fs/ext3/xattr.c
24140 --- linux-2.6.31.1/fs/ext3/xattr.c 2009-09-24 11:45:25.000000000 -0400
24141 +++ linux-2.6.31.1/fs/ext3/xattr.c 2009-10-01 20:12:44.000000000 -0400
24142 @@ -89,8 +89,8 @@
24143 printk("\n"); \
24144 } while (0)
24145 #else
24146 -# define ea_idebug(f...)
24147 -# define ea_bdebug(f...)
24148 +# define ea_idebug(f...) do {} while (0)
24149 +# define ea_bdebug(f...) do {} while (0)
24150 #endif
24151
24152 static void ext3_xattr_cache_insert(struct buffer_head *);
24153 diff -urNp linux-2.6.31.1/fs/ext4/balloc.c linux-2.6.31.1/fs/ext4/balloc.c
24154 --- linux-2.6.31.1/fs/ext4/balloc.c 2009-09-24 11:45:25.000000000 -0400
24155 +++ linux-2.6.31.1/fs/ext4/balloc.c 2009-10-01 20:12:44.000000000 -0400
24156 @@ -573,7 +573,7 @@ int ext4_has_free_blocks(struct ext4_sb_
24157 /* Hm, nope. Are (enough) root reserved blocks available? */
24158 if (sbi->s_resuid == current_fsuid() ||
24159 ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) ||
24160 - capable(CAP_SYS_RESOURCE)) {
24161 + capable_nolog(CAP_SYS_RESOURCE)) {
24162 if (free_blocks >= (nblocks + dirty_blocks))
24163 return 1;
24164 }
24165 diff -urNp linux-2.6.31.1/fs/ext4/file.c linux-2.6.31.1/fs/ext4/file.c
24166 --- linux-2.6.31.1/fs/ext4/file.c 2009-09-24 11:45:25.000000000 -0400
24167 +++ linux-2.6.31.1/fs/ext4/file.c 2009-10-01 20:12:44.000000000 -0400
24168 @@ -130,7 +130,7 @@ force_commit:
24169 return ret;
24170 }
24171
24172 -static struct vm_operations_struct ext4_file_vm_ops = {
24173 +static const struct vm_operations_struct ext4_file_vm_ops = {
24174 .fault = filemap_fault,
24175 .page_mkwrite = ext4_page_mkwrite,
24176 };
24177 diff -urNp linux-2.6.31.1/fs/ext4/mballoc.c linux-2.6.31.1/fs/ext4/mballoc.c
24178 --- linux-2.6.31.1/fs/ext4/mballoc.c 2009-09-24 11:45:25.000000000 -0400
24179 +++ linux-2.6.31.1/fs/ext4/mballoc.c 2009-10-01 20:12:44.000000000 -0400
24180 @@ -2205,7 +2205,7 @@ static void ext4_mb_seq_history_stop(str
24181 {
24182 }
24183
24184 -static struct seq_operations ext4_mb_seq_history_ops = {
24185 +static const struct seq_operations ext4_mb_seq_history_ops = {
24186 .start = ext4_mb_seq_history_start,
24187 .next = ext4_mb_seq_history_next,
24188 .stop = ext4_mb_seq_history_stop,
24189 @@ -2287,7 +2287,7 @@ static ssize_t ext4_mb_seq_history_write
24190 return count;
24191 }
24192
24193 -static struct file_operations ext4_mb_seq_history_fops = {
24194 +static const struct file_operations ext4_mb_seq_history_fops = {
24195 .owner = THIS_MODULE,
24196 .open = ext4_mb_seq_history_open,
24197 .read = seq_read,
24198 @@ -2366,7 +2366,7 @@ static void ext4_mb_seq_groups_stop(stru
24199 {
24200 }
24201
24202 -static struct seq_operations ext4_mb_seq_groups_ops = {
24203 +static const struct seq_operations ext4_mb_seq_groups_ops = {
24204 .start = ext4_mb_seq_groups_start,
24205 .next = ext4_mb_seq_groups_next,
24206 .stop = ext4_mb_seq_groups_stop,
24207 @@ -2387,7 +2387,7 @@ static int ext4_mb_seq_groups_open(struc
24208
24209 }
24210
24211 -static struct file_operations ext4_mb_seq_groups_fops = {
24212 +static const struct file_operations ext4_mb_seq_groups_fops = {
24213 .owner = THIS_MODULE,
24214 .open = ext4_mb_seq_groups_open,
24215 .read = seq_read,
24216 diff -urNp linux-2.6.31.1/fs/ext4/namei.c linux-2.6.31.1/fs/ext4/namei.c
24217 --- linux-2.6.31.1/fs/ext4/namei.c 2009-09-24 11:45:25.000000000 -0400
24218 +++ linux-2.6.31.1/fs/ext4/namei.c 2009-10-01 20:12:44.000000000 -0400
24219 @@ -1203,7 +1203,7 @@ static struct ext4_dir_entry_2 *do_split
24220 char *data1 = (*bh)->b_data, *data2;
24221 unsigned split, move, size;
24222 struct ext4_dir_entry_2 *de = NULL, *de2;
24223 - int err = 0, i;
24224 + int i, err = 0;
24225
24226 bh2 = ext4_append (handle, dir, &newblock, &err);
24227 if (!(bh2)) {
24228 diff -urNp linux-2.6.31.1/fs/fcntl.c linux-2.6.31.1/fs/fcntl.c
24229 --- linux-2.6.31.1/fs/fcntl.c 2009-09-24 11:45:25.000000000 -0400
24230 +++ linux-2.6.31.1/fs/fcntl.c 2009-10-01 20:12:44.000000000 -0400
24231 @@ -271,6 +271,7 @@ static long do_fcntl(int fd, unsigned in
24232 switch (cmd) {
24233 case F_DUPFD:
24234 case F_DUPFD_CLOEXEC:
24235 + gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
24236 if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
24237 break;
24238 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
24239 @@ -421,7 +422,8 @@ static inline int sigio_perm(struct task
24240 ret = ((fown->euid == 0 ||
24241 fown->euid == cred->suid || fown->euid == cred->uid ||
24242 fown->uid == cred->suid || fown->uid == cred->uid) &&
24243 - !security_file_send_sigiotask(p, fown, sig));
24244 + !security_file_send_sigiotask(p, fown, sig) &&
24245 + !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
24246 rcu_read_unlock();
24247 return ret;
24248 }
24249 diff -urNp linux-2.6.31.1/fs/file.c linux-2.6.31.1/fs/file.c
24250 --- linux-2.6.31.1/fs/file.c 2009-09-24 11:45:25.000000000 -0400
24251 +++ linux-2.6.31.1/fs/file.c 2009-10-01 20:12:44.000000000 -0400
24252 @@ -13,6 +13,7 @@
24253 #include <linux/slab.h>
24254 #include <linux/vmalloc.h>
24255 #include <linux/file.h>
24256 +#include <linux/security.h>
24257 #include <linux/fdtable.h>
24258 #include <linux/bitops.h>
24259 #include <linux/interrupt.h>
24260 @@ -256,6 +257,8 @@ int expand_files(struct files_struct *fi
24261 * N.B. For clone tasks sharing a files structure, this test
24262 * will limit the total number of files that can be opened.
24263 */
24264 +
24265 + gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
24266 if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
24267 return -EMFILE;
24268
24269 diff -urNp linux-2.6.31.1/fs/fs_struct.c linux-2.6.31.1/fs/fs_struct.c
24270 --- linux-2.6.31.1/fs/fs_struct.c 2009-09-24 11:45:25.000000000 -0400
24271 +++ linux-2.6.31.1/fs/fs_struct.c 2009-10-01 20:12:44.000000000 -0400
24272 @@ -89,7 +89,7 @@ void exit_fs(struct task_struct *tsk)
24273 task_lock(tsk);
24274 write_lock(&fs->lock);
24275 tsk->fs = NULL;
24276 - kill = !--fs->users;
24277 + kill = !atomic_dec_return(&fs->users);
24278 write_unlock(&fs->lock);
24279 task_unlock(tsk);
24280 if (kill)
24281 @@ -102,7 +102,7 @@ struct fs_struct *copy_fs_struct(struct
24282 struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
24283 /* We don't need to lock fs - think why ;-) */
24284 if (fs) {
24285 - fs->users = 1;
24286 + atomic_set(&fs->users, 1);
24287 fs->in_exec = 0;
24288 rwlock_init(&fs->lock);
24289 fs->umask = old->umask;
24290 @@ -127,7 +127,7 @@ int unshare_fs_struct(void)
24291
24292 task_lock(current);
24293 write_lock(&fs->lock);
24294 - kill = !--fs->users;
24295 + kill = !atomic_dec_return(&fs->users);
24296 current->fs = new_fs;
24297 write_unlock(&fs->lock);
24298 task_unlock(current);
24299 @@ -147,7 +147,7 @@ EXPORT_SYMBOL(current_umask);
24300
24301 /* to be mentioned only in INIT_TASK */
24302 struct fs_struct init_fs = {
24303 - .users = 1,
24304 + .users = ATOMIC_INIT(1),
24305 .lock = __RW_LOCK_UNLOCKED(init_fs.lock),
24306 .umask = 0022,
24307 };
24308 @@ -162,12 +162,12 @@ void daemonize_fs_struct(void)
24309 task_lock(current);
24310
24311 write_lock(&init_fs.lock);
24312 - init_fs.users++;
24313 + atomic_inc(&init_fs.users);
24314 write_unlock(&init_fs.lock);
24315
24316 write_lock(&fs->lock);
24317 current->fs = &init_fs;
24318 - kill = !--fs->users;
24319 + kill = !atomic_dec_return(&fs->users);
24320 write_unlock(&fs->lock);
24321
24322 task_unlock(current);
24323 diff -urNp linux-2.6.31.1/fs/fuse/control.c linux-2.6.31.1/fs/fuse/control.c
24324 --- linux-2.6.31.1/fs/fuse/control.c 2009-09-24 11:45:25.000000000 -0400
24325 +++ linux-2.6.31.1/fs/fuse/control.c 2009-10-01 20:12:44.000000000 -0400
24326 @@ -161,7 +161,7 @@ void fuse_ctl_remove_conn(struct fuse_co
24327
24328 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
24329 {
24330 - struct tree_descr empty_descr = {""};
24331 + struct tree_descr empty_descr = {"", NULL, 0};
24332 struct fuse_conn *fc;
24333 int err;
24334
24335 diff -urNp linux-2.6.31.1/fs/fuse/dev.c linux-2.6.31.1/fs/fuse/dev.c
24336 --- linux-2.6.31.1/fs/fuse/dev.c 2009-09-24 11:45:25.000000000 -0400
24337 +++ linux-2.6.31.1/fs/fuse/dev.c 2009-10-01 20:12:44.000000000 -0400
24338 @@ -885,7 +885,7 @@ static int fuse_notify_inval_entry(struc
24339 {
24340 struct fuse_notify_inval_entry_out outarg;
24341 int err = -EINVAL;
24342 - char buf[FUSE_NAME_MAX+1];
24343 + char *buf = NULL;
24344 struct qstr name;
24345
24346 if (size < sizeof(outarg))
24347 @@ -899,6 +899,11 @@ static int fuse_notify_inval_entry(struc
24348 if (outarg.namelen > FUSE_NAME_MAX)
24349 goto err;
24350
24351 + err = -ENOMEM;
24352 + buf = kmalloc(FUSE_NAME_MAX+1, GFP_KERNEL);
24353 + if (!buf)
24354 + goto err;
24355 +
24356 name.name = buf;
24357 name.len = outarg.namelen;
24358 err = fuse_copy_one(cs, buf, outarg.namelen + 1);
24359 @@ -910,17 +915,15 @@ static int fuse_notify_inval_entry(struc
24360
24361 down_read(&fc->killsb);
24362 err = -ENOENT;
24363 - if (!fc->sb)
24364 - goto err_unlock;
24365 -
24366 - err = fuse_reverse_inval_entry(fc->sb, outarg.parent, &name);
24367 -
24368 -err_unlock:
24369 + if (fc->sb)
24370 + err = fuse_reverse_inval_entry(fc->sb, outarg.parent, &name);
24371 up_read(&fc->killsb);
24372 + kfree(buf);
24373 return err;
24374
24375 err:
24376 fuse_copy_finish(cs);
24377 + kfree(buf);
24378 return err;
24379 }
24380
24381 diff -urNp linux-2.6.31.1/fs/fuse/dir.c linux-2.6.31.1/fs/fuse/dir.c
24382 --- linux-2.6.31.1/fs/fuse/dir.c 2009-09-24 11:45:25.000000000 -0400
24383 +++ linux-2.6.31.1/fs/fuse/dir.c 2009-10-01 20:12:44.000000000 -0400
24384 @@ -1122,7 +1122,7 @@ static char *read_link(struct dentry *de
24385 return link;
24386 }
24387
24388 -static void free_link(char *link)
24389 +static void free_link(const char *link)
24390 {
24391 if (!IS_ERR(link))
24392 free_page((unsigned long) link);
24393 diff -urNp linux-2.6.31.1/fs/fuse/file.c linux-2.6.31.1/fs/fuse/file.c
24394 --- linux-2.6.31.1/fs/fuse/file.c 2009-09-24 11:45:25.000000000 -0400
24395 +++ linux-2.6.31.1/fs/fuse/file.c 2009-10-01 20:12:44.000000000 -0400
24396 @@ -1313,7 +1313,7 @@ static int fuse_page_mkwrite(struct vm_a
24397 return 0;
24398 }
24399
24400 -static struct vm_operations_struct fuse_file_vm_ops = {
24401 +static const struct vm_operations_struct fuse_file_vm_ops = {
24402 .close = fuse_vma_close,
24403 .fault = filemap_fault,
24404 .page_mkwrite = fuse_page_mkwrite,
24405 diff -urNp linux-2.6.31.1/fs/gfs2/file.c linux-2.6.31.1/fs/gfs2/file.c
24406 --- linux-2.6.31.1/fs/gfs2/file.c 2009-09-24 11:45:25.000000000 -0400
24407 +++ linux-2.6.31.1/fs/gfs2/file.c 2009-10-01 20:12:44.000000000 -0400
24408 @@ -419,7 +419,7 @@ out:
24409 return ret;
24410 }
24411
24412 -static struct vm_operations_struct gfs2_vm_ops = {
24413 +static const struct vm_operations_struct gfs2_vm_ops = {
24414 .fault = filemap_fault,
24415 .page_mkwrite = gfs2_page_mkwrite,
24416 };
24417 diff -urNp linux-2.6.31.1/fs/hfs/inode.c linux-2.6.31.1/fs/hfs/inode.c
24418 --- linux-2.6.31.1/fs/hfs/inode.c 2009-09-24 11:45:25.000000000 -0400
24419 +++ linux-2.6.31.1/fs/hfs/inode.c 2009-10-01 20:12:44.000000000 -0400
24420 @@ -423,7 +423,7 @@ int hfs_write_inode(struct inode *inode,
24421
24422 if (S_ISDIR(main_inode->i_mode)) {
24423 if (fd.entrylength < sizeof(struct hfs_cat_dir))
24424 - /* panic? */;
24425 + {/* panic? */}
24426 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
24427 sizeof(struct hfs_cat_dir));
24428 if (rec.type != HFS_CDR_DIR ||
24429 @@ -444,7 +444,7 @@ int hfs_write_inode(struct inode *inode,
24430 sizeof(struct hfs_cat_file));
24431 } else {
24432 if (fd.entrylength < sizeof(struct hfs_cat_file))
24433 - /* panic? */;
24434 + {/* panic? */}
24435 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
24436 sizeof(struct hfs_cat_file));
24437 if (rec.type != HFS_CDR_FIL ||
24438 diff -urNp linux-2.6.31.1/fs/hfsplus/inode.c linux-2.6.31.1/fs/hfsplus/inode.c
24439 --- linux-2.6.31.1/fs/hfsplus/inode.c 2009-09-24 11:45:25.000000000 -0400
24440 +++ linux-2.6.31.1/fs/hfsplus/inode.c 2009-10-01 20:12:44.000000000 -0400
24441 @@ -406,7 +406,7 @@ int hfsplus_cat_read_inode(struct inode
24442 struct hfsplus_cat_folder *folder = &entry.folder;
24443
24444 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
24445 - /* panic? */;
24446 + {/* panic? */}
24447 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
24448 sizeof(struct hfsplus_cat_folder));
24449 hfsplus_get_perms(inode, &folder->permissions, 1);
24450 @@ -423,7 +423,7 @@ int hfsplus_cat_read_inode(struct inode
24451 struct hfsplus_cat_file *file = &entry.file;
24452
24453 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
24454 - /* panic? */;
24455 + {/* panic? */}
24456 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
24457 sizeof(struct hfsplus_cat_file));
24458
24459 @@ -479,7 +479,7 @@ int hfsplus_cat_write_inode(struct inode
24460 struct hfsplus_cat_folder *folder = &entry.folder;
24461
24462 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
24463 - /* panic? */;
24464 + {/* panic? */}
24465 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
24466 sizeof(struct hfsplus_cat_folder));
24467 /* simple node checks? */
24468 @@ -501,7 +501,7 @@ int hfsplus_cat_write_inode(struct inode
24469 struct hfsplus_cat_file *file = &entry.file;
24470
24471 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
24472 - /* panic? */;
24473 + {/* panic? */}
24474 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
24475 sizeof(struct hfsplus_cat_file));
24476 hfsplus_inode_write_fork(inode, &file->data_fork);
24477 diff -urNp linux-2.6.31.1/fs/jbd2/journal.c linux-2.6.31.1/fs/jbd2/journal.c
24478 --- linux-2.6.31.1/fs/jbd2/journal.c 2009-09-24 11:45:25.000000000 -0400
24479 +++ linux-2.6.31.1/fs/jbd2/journal.c 2009-10-01 20:12:44.000000000 -0400
24480 @@ -768,7 +768,7 @@ static void jbd2_seq_history_stop(struct
24481 {
24482 }
24483
24484 -static struct seq_operations jbd2_seq_history_ops = {
24485 +static const struct seq_operations jbd2_seq_history_ops = {
24486 .start = jbd2_seq_history_start,
24487 .next = jbd2_seq_history_next,
24488 .stop = jbd2_seq_history_stop,
24489 @@ -818,7 +818,7 @@ static int jbd2_seq_history_release(stru
24490 return seq_release(inode, file);
24491 }
24492
24493 -static struct file_operations jbd2_seq_history_fops = {
24494 +static const struct file_operations jbd2_seq_history_fops = {
24495 .owner = THIS_MODULE,
24496 .open = jbd2_seq_history_open,
24497 .read = seq_read,
24498 @@ -872,7 +872,7 @@ static void jbd2_seq_info_stop(struct se
24499 {
24500 }
24501
24502 -static struct seq_operations jbd2_seq_info_ops = {
24503 +static const struct seq_operations jbd2_seq_info_ops = {
24504 .start = jbd2_seq_info_start,
24505 .next = jbd2_seq_info_next,
24506 .stop = jbd2_seq_info_stop,
24507 @@ -920,7 +920,7 @@ static int jbd2_seq_info_release(struct
24508 return seq_release(inode, file);
24509 }
24510
24511 -static struct file_operations jbd2_seq_info_fops = {
24512 +static const struct file_operations jbd2_seq_info_fops = {
24513 .owner = THIS_MODULE,
24514 .open = jbd2_seq_info_open,
24515 .read = seq_read,
24516 diff -urNp linux-2.6.31.1/fs/jffs2/debug.h linux-2.6.31.1/fs/jffs2/debug.h
24517 --- linux-2.6.31.1/fs/jffs2/debug.h 2009-09-24 11:45:25.000000000 -0400
24518 +++ linux-2.6.31.1/fs/jffs2/debug.h 2009-10-01 20:12:44.000000000 -0400
24519 @@ -52,13 +52,13 @@
24520 #if CONFIG_JFFS2_FS_DEBUG > 0
24521 #define D1(x) x
24522 #else
24523 -#define D1(x)
24524 +#define D1(x) do {} while (0);
24525 #endif
24526
24527 #if CONFIG_JFFS2_FS_DEBUG > 1
24528 #define D2(x) x
24529 #else
24530 -#define D2(x)
24531 +#define D2(x) do {} while (0);
24532 #endif
24533
24534 /* The prefixes of JFFS2 messages */
24535 @@ -114,73 +114,73 @@
24536 #ifdef JFFS2_DBG_READINODE_MESSAGES
24537 #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24538 #else
24539 -#define dbg_readinode(fmt, ...)
24540 +#define dbg_readinode(fmt, ...) do {} while (0)
24541 #endif
24542 #ifdef JFFS2_DBG_READINODE2_MESSAGES
24543 #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24544 #else
24545 -#define dbg_readinode2(fmt, ...)
24546 +#define dbg_readinode2(fmt, ...) do {} while (0)
24547 #endif
24548
24549 /* Fragtree build debugging messages */
24550 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
24551 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24552 #else
24553 -#define dbg_fragtree(fmt, ...)
24554 +#define dbg_fragtree(fmt, ...) do {} while (0)
24555 #endif
24556 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
24557 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24558 #else
24559 -#define dbg_fragtree2(fmt, ...)
24560 +#define dbg_fragtree2(fmt, ...) do {} while (0)
24561 #endif
24562
24563 /* Directory entry list manilulation debugging messages */
24564 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
24565 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24566 #else
24567 -#define dbg_dentlist(fmt, ...)
24568 +#define dbg_dentlist(fmt, ...) do {} while (0)
24569 #endif
24570
24571 /* Print the messages about manipulating node_refs */
24572 #ifdef JFFS2_DBG_NODEREF_MESSAGES
24573 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24574 #else
24575 -#define dbg_noderef(fmt, ...)
24576 +#define dbg_noderef(fmt, ...) do {} while (0)
24577 #endif
24578
24579 /* Manipulations with the list of inodes (JFFS2 inocache) */
24580 #ifdef JFFS2_DBG_INOCACHE_MESSAGES
24581 #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24582 #else
24583 -#define dbg_inocache(fmt, ...)
24584 +#define dbg_inocache(fmt, ...) do {} while (0)
24585 #endif
24586
24587 /* Summary debugging messages */
24588 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
24589 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24590 #else
24591 -#define dbg_summary(fmt, ...)
24592 +#define dbg_summary(fmt, ...) do {} while (0)
24593 #endif
24594
24595 /* File system build messages */
24596 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
24597 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24598 #else
24599 -#define dbg_fsbuild(fmt, ...)
24600 +#define dbg_fsbuild(fmt, ...) do {} while (0)
24601 #endif
24602
24603 /* Watch the object allocations */
24604 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
24605 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24606 #else
24607 -#define dbg_memalloc(fmt, ...)
24608 +#define dbg_memalloc(fmt, ...) do {} while (0)
24609 #endif
24610
24611 /* Watch the XATTR subsystem */
24612 #ifdef JFFS2_DBG_XATTR_MESSAGES
24613 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
24614 #else
24615 -#define dbg_xattr(fmt, ...)
24616 +#define dbg_xattr(fmt, ...) do {} while (0)
24617 #endif
24618
24619 /* "Sanity" checks */
24620 diff -urNp linux-2.6.31.1/fs/jffs2/erase.c linux-2.6.31.1/fs/jffs2/erase.c
24621 --- linux-2.6.31.1/fs/jffs2/erase.c 2009-09-24 11:45:25.000000000 -0400
24622 +++ linux-2.6.31.1/fs/jffs2/erase.c 2009-10-01 20:12:44.000000000 -0400
24623 @@ -434,7 +434,8 @@ static void jffs2_mark_erased_block(stru
24624 struct jffs2_unknown_node marker = {
24625 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
24626 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
24627 - .totlen = cpu_to_je32(c->cleanmarker_size)
24628 + .totlen = cpu_to_je32(c->cleanmarker_size),
24629 + .hdr_crc = cpu_to_je32(0)
24630 };
24631
24632 jffs2_prealloc_raw_node_refs(c, jeb, 1);
24633 diff -urNp linux-2.6.31.1/fs/jffs2/summary.h linux-2.6.31.1/fs/jffs2/summary.h
24634 --- linux-2.6.31.1/fs/jffs2/summary.h 2009-09-24 11:45:25.000000000 -0400
24635 +++ linux-2.6.31.1/fs/jffs2/summary.h 2009-10-01 20:12:44.000000000 -0400
24636 @@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
24637
24638 #define jffs2_sum_active() (0)
24639 #define jffs2_sum_init(a) (0)
24640 -#define jffs2_sum_exit(a)
24641 -#define jffs2_sum_disable_collecting(a)
24642 +#define jffs2_sum_exit(a) do {} while (0)
24643 +#define jffs2_sum_disable_collecting(a) do {} while (0)
24644 #define jffs2_sum_is_disabled(a) (0)
24645 -#define jffs2_sum_reset_collected(a)
24646 +#define jffs2_sum_reset_collected(a) do {} while (0)
24647 #define jffs2_sum_add_kvec(a,b,c,d) (0)
24648 -#define jffs2_sum_move_collected(a,b)
24649 +#define jffs2_sum_move_collected(a,b) do {} while (0)
24650 #define jffs2_sum_write_sumnode(a) (0)
24651 -#define jffs2_sum_add_padding_mem(a,b)
24652 -#define jffs2_sum_add_inode_mem(a,b,c)
24653 -#define jffs2_sum_add_dirent_mem(a,b,c)
24654 -#define jffs2_sum_add_xattr_mem(a,b,c)
24655 -#define jffs2_sum_add_xref_mem(a,b,c)
24656 +#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
24657 +#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
24658 +#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
24659 +#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
24660 +#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
24661 #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
24662
24663 #endif /* CONFIG_JFFS2_SUMMARY */
24664 diff -urNp linux-2.6.31.1/fs/jffs2/wbuf.c linux-2.6.31.1/fs/jffs2/wbuf.c
24665 --- linux-2.6.31.1/fs/jffs2/wbuf.c 2009-09-24 11:45:25.000000000 -0400
24666 +++ linux-2.6.31.1/fs/jffs2/wbuf.c 2009-10-01 20:12:44.000000000 -0400
24667 @@ -1012,7 +1012,8 @@ static const struct jffs2_unknown_node o
24668 {
24669 .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
24670 .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
24671 - .totlen = constant_cpu_to_je32(8)
24672 + .totlen = constant_cpu_to_je32(8),
24673 + .hdr_crc = constant_cpu_to_je32(0)
24674 };
24675
24676 /*
24677 diff -urNp linux-2.6.31.1/fs/locks.c linux-2.6.31.1/fs/locks.c
24678 --- linux-2.6.31.1/fs/locks.c 2009-09-24 11:45:25.000000000 -0400
24679 +++ linux-2.6.31.1/fs/locks.c 2009-10-01 20:12:44.000000000 -0400
24680 @@ -2007,16 +2007,16 @@ void locks_remove_flock(struct file *fil
24681 return;
24682
24683 if (filp->f_op && filp->f_op->flock) {
24684 - struct file_lock fl = {
24685 + struct file_lock flock = {
24686 .fl_pid = current->tgid,
24687 .fl_file = filp,
24688 .fl_flags = FL_FLOCK,
24689 .fl_type = F_UNLCK,
24690 .fl_end = OFFSET_MAX,
24691 };
24692 - filp->f_op->flock(filp, F_SETLKW, &fl);
24693 - if (fl.fl_ops && fl.fl_ops->fl_release_private)
24694 - fl.fl_ops->fl_release_private(&fl);
24695 + filp->f_op->flock(filp, F_SETLKW, &flock);
24696 + if (flock.fl_ops && flock.fl_ops->fl_release_private)
24697 + flock.fl_ops->fl_release_private(&flock);
24698 }
24699
24700 lock_kernel();
24701 diff -urNp linux-2.6.31.1/fs/namei.c linux-2.6.31.1/fs/namei.c
24702 --- linux-2.6.31.1/fs/namei.c 2009-09-24 11:45:25.000000000 -0400
24703 +++ linux-2.6.31.1/fs/namei.c 2009-10-01 20:12:44.000000000 -0400
24704 @@ -631,7 +631,7 @@ static __always_inline int __do_follow_l
24705 cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
24706 error = PTR_ERR(cookie);
24707 if (!IS_ERR(cookie)) {
24708 - char *s = nd_get_link(nd);
24709 + const char *s = nd_get_link(nd);
24710 error = 0;
24711 if (s)
24712 error = __vfs_follow_link(nd, s);
24713 @@ -662,6 +662,13 @@ static inline int do_follow_link(struct
24714 err = security_inode_follow_link(path->dentry, nd);
24715 if (err)
24716 goto loop;
24717 +
24718 + if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
24719 + path->dentry->d_inode, path->dentry, nd->path.mnt)) {
24720 + err = -EACCES;
24721 + goto loop;
24722 + }
24723 +
24724 current->link_count++;
24725 current->total_link_count++;
24726 nd->depth++;
24727 @@ -1005,11 +1012,18 @@ return_reval:
24728 break;
24729 }
24730 return_base:
24731 + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
24732 + path_put(&nd->path);
24733 + return -ENOENT;
24734 + }
24735 return 0;
24736 out_dput:
24737 path_put_conditional(&next, nd);
24738 break;
24739 }
24740 + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
24741 + err = -ENOENT;
24742 +
24743 path_put(&nd->path);
24744 return_err:
24745 return err;
24746 @@ -1608,12 +1622,19 @@ static int __open_namei_create(struct na
24747 int error;
24748 struct dentry *dir = nd->path.dentry;
24749
24750 + if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
24751 + error = -EACCES;
24752 + goto out_unlock;
24753 + }
24754 +
24755 if (!IS_POSIXACL(dir->d_inode))
24756 mode &= ~current_umask();
24757 error = security_path_mknod(&nd->path, path->dentry, mode, 0);
24758 if (error)
24759 goto out_unlock;
24760 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
24761 + if (!error)
24762 + gr_handle_create(path->dentry, nd->path.mnt);
24763 out_unlock:
24764 mutex_unlock(&dir->d_inode->i_mutex);
24765 dput(nd->path.dentry);
24766 @@ -1696,6 +1717,17 @@ struct file *do_filp_open(int dfd, const
24767 &nd, flag);
24768 if (error)
24769 return ERR_PTR(error);
24770 +
24771 + if (gr_handle_rawio(nd.path.dentry->d_inode)) {
24772 + error = -EPERM;
24773 + goto exit;
24774 + }
24775 +
24776 + if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
24777 + error = -EACCES;
24778 + goto exit;
24779 + }
24780 +
24781 goto ok;
24782 }
24783
24784 @@ -1782,6 +1814,20 @@ do_last:
24785 /*
24786 * It already exists.
24787 */
24788 +
24789 + if (gr_handle_rawio(path.dentry->d_inode)) {
24790 + error = -EPERM;
24791 + goto exit_mutex_unlock;
24792 + }
24793 + if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
24794 + error = -EACCES;
24795 + goto exit_mutex_unlock;
24796 + }
24797 + if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
24798 + error = -EACCES;
24799 + goto exit_mutex_unlock;
24800 + }
24801 +
24802 mutex_unlock(&dir->d_inode->i_mutex);
24803 audit_inode(pathname, path.dentry);
24804
24805 @@ -1874,6 +1920,13 @@ do_link:
24806 error = security_inode_follow_link(path.dentry, &nd);
24807 if (error)
24808 goto exit_dput;
24809 +
24810 + if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
24811 + path.dentry, nd.path.mnt)) {
24812 + error = -EACCES;
24813 + goto exit_dput;
24814 + }
24815 +
24816 error = __do_follow_link(&path, &nd);
24817 if (error) {
24818 /* Does someone understand code flow here? Or it is only
24819 @@ -2048,6 +2101,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
24820 error = may_mknod(mode);
24821 if (error)
24822 goto out_dput;
24823 +
24824 + if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
24825 + error = -EPERM;
24826 + goto out_dput;
24827 + }
24828 +
24829 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
24830 + error = -EACCES;
24831 + goto out_dput;
24832 + }
24833 +
24834 error = mnt_want_write(nd.path.mnt);
24835 if (error)
24836 goto out_dput;
24837 @@ -2068,6 +2132,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
24838 }
24839 out_drop_write:
24840 mnt_drop_write(nd.path.mnt);
24841 +
24842 + if (!error)
24843 + gr_handle_create(dentry, nd.path.mnt);
24844 out_dput:
24845 dput(dentry);
24846 out_unlock:
24847 @@ -2121,6 +2188,11 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
24848 if (IS_ERR(dentry))
24849 goto out_unlock;
24850
24851 + if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
24852 + error = -EACCES;
24853 + goto out_dput;
24854 + }
24855 +
24856 if (!IS_POSIXACL(nd.path.dentry->d_inode))
24857 mode &= ~current_umask();
24858 error = mnt_want_write(nd.path.mnt);
24859 @@ -2132,6 +2204,10 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
24860 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
24861 out_drop_write:
24862 mnt_drop_write(nd.path.mnt);
24863 +
24864 + if (!error)
24865 + gr_handle_create(dentry, nd.path.mnt);
24866 +
24867 out_dput:
24868 dput(dentry);
24869 out_unlock:
24870 @@ -2213,6 +2289,8 @@ static long do_rmdir(int dfd, const char
24871 char * name;
24872 struct dentry *dentry;
24873 struct nameidata nd;
24874 + ino_t saved_ino = 0;
24875 + dev_t saved_dev = 0;
24876
24877 error = user_path_parent(dfd, pathname, &nd, &name);
24878 if (error)
24879 @@ -2237,6 +2315,19 @@ static long do_rmdir(int dfd, const char
24880 error = PTR_ERR(dentry);
24881 if (IS_ERR(dentry))
24882 goto exit2;
24883 +
24884 + if (dentry->d_inode != NULL) {
24885 + if (dentry->d_inode->i_nlink <= 1) {
24886 + saved_ino = dentry->d_inode->i_ino;
24887 + saved_dev = dentry->d_inode->i_sb->s_dev;
24888 + }
24889 +
24890 + if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
24891 + error = -EACCES;
24892 + goto exit3;
24893 + }
24894 + }
24895 +
24896 error = mnt_want_write(nd.path.mnt);
24897 if (error)
24898 goto exit3;
24899 @@ -2244,6 +2335,8 @@ static long do_rmdir(int dfd, const char
24900 if (error)
24901 goto exit4;
24902 error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
24903 + if (!error && (saved_dev || saved_ino))
24904 + gr_handle_delete(saved_ino, saved_dev);
24905 exit4:
24906 mnt_drop_write(nd.path.mnt);
24907 exit3:
24908 @@ -2305,6 +2398,8 @@ static long do_unlinkat(int dfd, const c
24909 struct dentry *dentry;
24910 struct nameidata nd;
24911 struct inode *inode = NULL;
24912 + ino_t saved_ino = 0;
24913 + dev_t saved_dev = 0;
24914
24915 error = user_path_parent(dfd, pathname, &nd, &name);
24916 if (error)
24917 @@ -2324,8 +2419,19 @@ static long do_unlinkat(int dfd, const c
24918 if (nd.last.name[nd.last.len])
24919 goto slashes;
24920 inode = dentry->d_inode;
24921 - if (inode)
24922 + if (inode) {
24923 + if (inode->i_nlink <= 1) {
24924 + saved_ino = inode->i_ino;
24925 + saved_dev = inode->i_sb->s_dev;
24926 + }
24927 +
24928 atomic_inc(&inode->i_count);
24929 +
24930 + if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
24931 + error = -EACCES;
24932 + goto exit2;
24933 + }
24934 + }
24935 error = mnt_want_write(nd.path.mnt);
24936 if (error)
24937 goto exit2;
24938 @@ -2333,6 +2439,8 @@ static long do_unlinkat(int dfd, const c
24939 if (error)
24940 goto exit3;
24941 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
24942 + if (!error && (saved_ino || saved_dev))
24943 + gr_handle_delete(saved_ino, saved_dev);
24944 exit3:
24945 mnt_drop_write(nd.path.mnt);
24946 exit2:
24947 @@ -2411,6 +2519,11 @@ SYSCALL_DEFINE3(symlinkat, const char __
24948 if (IS_ERR(dentry))
24949 goto out_unlock;
24950
24951 + if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
24952 + error = -EACCES;
24953 + goto out_dput;
24954 + }
24955 +
24956 error = mnt_want_write(nd.path.mnt);
24957 if (error)
24958 goto out_dput;
24959 @@ -2418,6 +2531,8 @@ SYSCALL_DEFINE3(symlinkat, const char __
24960 if (error)
24961 goto out_drop_write;
24962 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
24963 + if (!error)
24964 + gr_handle_create(dentry, nd.path.mnt);
24965 out_drop_write:
24966 mnt_drop_write(nd.path.mnt);
24967 out_dput:
24968 @@ -2511,6 +2626,20 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
24969 error = PTR_ERR(new_dentry);
24970 if (IS_ERR(new_dentry))
24971 goto out_unlock;
24972 +
24973 + if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
24974 + old_path.dentry->d_inode,
24975 + old_path.dentry->d_inode->i_mode, to)) {
24976 + error = -EACCES;
24977 + goto out_dput;
24978 + }
24979 +
24980 + if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
24981 + old_path.dentry, old_path.mnt, to)) {
24982 + error = -EACCES;
24983 + goto out_dput;
24984 + }
24985 +
24986 error = mnt_want_write(nd.path.mnt);
24987 if (error)
24988 goto out_dput;
24989 @@ -2518,6 +2647,8 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
24990 if (error)
24991 goto out_drop_write;
24992 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
24993 + if (!error)
24994 + gr_handle_create(new_dentry, nd.path.mnt);
24995 out_drop_write:
24996 mnt_drop_write(nd.path.mnt);
24997 out_dput:
24998 @@ -2751,6 +2882,12 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
24999 if (new_dentry == trap)
25000 goto exit5;
25001
25002 + error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt,
25003 + old_dentry, old_dir->d_inode, oldnd.path.mnt,
25004 + to);
25005 + if (error)
25006 + goto exit5;
25007 +
25008 error = mnt_want_write(oldnd.path.mnt);
25009 if (error)
25010 goto exit5;
25011 @@ -2760,6 +2897,9 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
25012 goto exit6;
25013 error = vfs_rename(old_dir->d_inode, old_dentry,
25014 new_dir->d_inode, new_dentry);
25015 + if (!error)
25016 + gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
25017 + new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
25018 exit6:
25019 mnt_drop_write(oldnd.path.mnt);
25020 exit5:
25021 diff -urNp linux-2.6.31.1/fs/namespace.c linux-2.6.31.1/fs/namespace.c
25022 --- linux-2.6.31.1/fs/namespace.c 2009-09-24 11:45:25.000000000 -0400
25023 +++ linux-2.6.31.1/fs/namespace.c 2009-10-01 20:12:44.000000000 -0400
25024 @@ -1083,6 +1083,9 @@ static int do_umount(struct vfsmount *mn
25025 if (!(sb->s_flags & MS_RDONLY))
25026 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
25027 up_write(&sb->s_umount);
25028 +
25029 + gr_log_remount(mnt->mnt_devname, retval);
25030 +
25031 return retval;
25032 }
25033
25034 @@ -1104,6 +1107,9 @@ static int do_umount(struct vfsmount *mn
25035 security_sb_umount_busy(mnt);
25036 up_write(&namespace_sem);
25037 release_mounts(&umount_list);
25038 +
25039 + gr_log_unmount(mnt->mnt_devname, retval);
25040 +
25041 return retval;
25042 }
25043
25044 @@ -1940,6 +1946,11 @@ long do_mount(char *dev_name, char *dir_
25045 if (retval)
25046 goto dput_out;
25047
25048 + if (gr_handle_chroot_mount(path.dentry, path.mnt, dev_name)) {
25049 + retval = -EPERM;
25050 + goto dput_out;
25051 + }
25052 +
25053 if (flags & MS_REMOUNT)
25054 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
25055 data_page);
25056 @@ -1954,6 +1965,9 @@ long do_mount(char *dev_name, char *dir_
25057 dev_name, data_page);
25058 dput_out:
25059 path_put(&path);
25060 +
25061 + gr_log_mount(dev_name, dir_name, retval);
25062 +
25063 return retval;
25064 }
25065
25066 @@ -2158,6 +2172,12 @@ SYSCALL_DEFINE2(pivot_root, const char _
25067 goto out1;
25068 }
25069
25070 + if (gr_handle_chroot_pivot()) {
25071 + error = -EPERM;
25072 + path_put(&old);
25073 + goto out1;
25074 + }
25075 +
25076 read_lock(&current->fs->lock);
25077 root = current->fs->root;
25078 path_get(&current->fs->root);
25079 diff -urNp linux-2.6.31.1/fs/nfs/client.c linux-2.6.31.1/fs/nfs/client.c
25080 --- linux-2.6.31.1/fs/nfs/client.c 2009-09-24 11:45:25.000000000 -0400
25081 +++ linux-2.6.31.1/fs/nfs/client.c 2009-10-01 20:12:44.000000000 -0400
25082 @@ -1533,7 +1533,7 @@ static void *nfs_server_list_next(struct
25083 static void nfs_server_list_stop(struct seq_file *p, void *v);
25084 static int nfs_server_list_show(struct seq_file *m, void *v);
25085
25086 -static struct seq_operations nfs_server_list_ops = {
25087 +static const struct seq_operations nfs_server_list_ops = {
25088 .start = nfs_server_list_start,
25089 .next = nfs_server_list_next,
25090 .stop = nfs_server_list_stop,
25091 @@ -1554,7 +1554,7 @@ static void *nfs_volume_list_next(struct
25092 static void nfs_volume_list_stop(struct seq_file *p, void *v);
25093 static int nfs_volume_list_show(struct seq_file *m, void *v);
25094
25095 -static struct seq_operations nfs_volume_list_ops = {
25096 +static const struct seq_operations nfs_volume_list_ops = {
25097 .start = nfs_volume_list_start,
25098 .next = nfs_volume_list_next,
25099 .stop = nfs_volume_list_stop,
25100 diff -urNp linux-2.6.31.1/fs/nfs/file.c linux-2.6.31.1/fs/nfs/file.c
25101 --- linux-2.6.31.1/fs/nfs/file.c 2009-09-24 11:45:25.000000000 -0400
25102 +++ linux-2.6.31.1/fs/nfs/file.c 2009-10-01 20:12:44.000000000 -0400
25103 @@ -59,7 +59,7 @@ static int nfs_lock(struct file *filp, i
25104 static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
25105 static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
25106
25107 -static struct vm_operations_struct nfs_file_vm_ops;
25108 +static const struct vm_operations_struct nfs_file_vm_ops;
25109
25110 const struct file_operations nfs_file_operations = {
25111 .llseek = nfs_file_llseek,
25112 @@ -526,7 +526,7 @@ out_unlock:
25113 return VM_FAULT_SIGBUS;
25114 }
25115
25116 -static struct vm_operations_struct nfs_file_vm_ops = {
25117 +static const struct vm_operations_struct nfs_file_vm_ops = {
25118 .fault = filemap_fault,
25119 .page_mkwrite = nfs_vm_page_mkwrite,
25120 };
25121 diff -urNp linux-2.6.31.1/fs/nfs/nfs4proc.c linux-2.6.31.1/fs/nfs/nfs4proc.c
25122 --- linux-2.6.31.1/fs/nfs/nfs4proc.c 2009-09-24 11:45:25.000000000 -0400
25123 +++ linux-2.6.31.1/fs/nfs/nfs4proc.c 2009-10-01 20:12:44.000000000 -0400
25124 @@ -1123,7 +1123,7 @@ static int _nfs4_do_open_reclaim(struct
25125 static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
25126 {
25127 struct nfs_server *server = NFS_SERVER(state->inode);
25128 - struct nfs4_exception exception = { };
25129 + struct nfs4_exception exception = {0, 0};
25130 int err;
25131 do {
25132 err = _nfs4_do_open_reclaim(ctx, state);
25133 @@ -1165,7 +1165,7 @@ static int _nfs4_open_delegation_recall(
25134
25135 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
25136 {
25137 - struct nfs4_exception exception = { };
25138 + struct nfs4_exception exception = {0, 0};
25139 struct nfs_server *server = NFS_SERVER(state->inode);
25140 int err;
25141 do {
25142 @@ -1481,7 +1481,7 @@ static int _nfs4_open_expired(struct nfs
25143 static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
25144 {
25145 struct nfs_server *server = NFS_SERVER(state->inode);
25146 - struct nfs4_exception exception = { };
25147 + struct nfs4_exception exception = {0, 0};
25148 int err;
25149
25150 do {
25151 @@ -1579,7 +1579,7 @@ out_err:
25152
25153 static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred)
25154 {
25155 - struct nfs4_exception exception = { };
25156 + struct nfs4_exception exception = {0, 0};
25157 struct nfs4_state *res;
25158 int status;
25159
25160 @@ -1670,7 +1670,7 @@ static int nfs4_do_setattr(struct inode
25161 struct nfs4_state *state)
25162 {
25163 struct nfs_server *server = NFS_SERVER(inode);
25164 - struct nfs4_exception exception = { };
25165 + struct nfs4_exception exception = {0, 0};
25166 int err;
25167 do {
25168 err = nfs4_handle_exception(server,
25169 @@ -2014,7 +2014,7 @@ static int _nfs4_server_capabilities(str
25170
25171 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
25172 {
25173 - struct nfs4_exception exception = { };
25174 + struct nfs4_exception exception = {0, 0};
25175 int err;
25176 do {
25177 err = nfs4_handle_exception(server,
25178 @@ -2048,7 +2048,7 @@ static int _nfs4_lookup_root(struct nfs_
25179 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
25180 struct nfs_fsinfo *info)
25181 {
25182 - struct nfs4_exception exception = { };
25183 + struct nfs4_exception exception = {0, 0};
25184 int err;
25185 do {
25186 err = nfs4_handle_exception(server,
25187 @@ -2137,7 +2137,7 @@ static int _nfs4_proc_getattr(struct nfs
25188
25189 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
25190 {
25191 - struct nfs4_exception exception = { };
25192 + struct nfs4_exception exception = {0, 0};
25193 int err;
25194 do {
25195 err = nfs4_handle_exception(server,
25196 @@ -2225,7 +2225,7 @@ static int nfs4_proc_lookupfh(struct nfs
25197 struct qstr *name, struct nfs_fh *fhandle,
25198 struct nfs_fattr *fattr)
25199 {
25200 - struct nfs4_exception exception = { };
25201 + struct nfs4_exception exception = {0, 0};
25202 int err;
25203 do {
25204 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
25205 @@ -2254,7 +2254,7 @@ static int _nfs4_proc_lookup(struct inod
25206
25207 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
25208 {
25209 - struct nfs4_exception exception = { };
25210 + struct nfs4_exception exception = {0, 0};
25211 int err;
25212 do {
25213 err = nfs4_handle_exception(NFS_SERVER(dir),
25214 @@ -2318,7 +2318,7 @@ static int _nfs4_proc_access(struct inod
25215
25216 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
25217 {
25218 - struct nfs4_exception exception = { };
25219 + struct nfs4_exception exception = {0, 0};
25220 int err;
25221 do {
25222 err = nfs4_handle_exception(NFS_SERVER(inode),
25223 @@ -2374,7 +2374,7 @@ static int _nfs4_proc_readlink(struct in
25224 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
25225 unsigned int pgbase, unsigned int pglen)
25226 {
25227 - struct nfs4_exception exception = { };
25228 + struct nfs4_exception exception = {0, 0};
25229 int err;
25230 do {
25231 err = nfs4_handle_exception(NFS_SERVER(inode),
25232 @@ -2472,7 +2472,7 @@ static int _nfs4_proc_remove(struct inod
25233
25234 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
25235 {
25236 - struct nfs4_exception exception = { };
25237 + struct nfs4_exception exception = {0, 0};
25238 int err;
25239 do {
25240 err = nfs4_handle_exception(NFS_SERVER(dir),
25241 @@ -2546,7 +2546,7 @@ static int _nfs4_proc_rename(struct inod
25242 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
25243 struct inode *new_dir, struct qstr *new_name)
25244 {
25245 - struct nfs4_exception exception = { };
25246 + struct nfs4_exception exception = {0, 0};
25247 int err;
25248 do {
25249 err = nfs4_handle_exception(NFS_SERVER(old_dir),
25250 @@ -2593,7 +2593,7 @@ static int _nfs4_proc_link(struct inode
25251
25252 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
25253 {
25254 - struct nfs4_exception exception = { };
25255 + struct nfs4_exception exception = {0, 0};
25256 int err;
25257 do {
25258 err = nfs4_handle_exception(NFS_SERVER(inode),
25259 @@ -2685,7 +2685,7 @@ out:
25260 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
25261 struct page *page, unsigned int len, struct iattr *sattr)
25262 {
25263 - struct nfs4_exception exception = { };
25264 + struct nfs4_exception exception = {0, 0};
25265 int err;
25266 do {
25267 err = nfs4_handle_exception(NFS_SERVER(dir),
25268 @@ -2716,7 +2716,7 @@ out:
25269 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
25270 struct iattr *sattr)
25271 {
25272 - struct nfs4_exception exception = { };
25273 + struct nfs4_exception exception = {0, 0};
25274 int err;
25275 do {
25276 err = nfs4_handle_exception(NFS_SERVER(dir),
25277 @@ -2765,7 +2765,7 @@ static int _nfs4_proc_readdir(struct den
25278 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
25279 u64 cookie, struct page *page, unsigned int count, int plus)
25280 {
25281 - struct nfs4_exception exception = { };
25282 + struct nfs4_exception exception = {0, 0};
25283 int err;
25284 do {
25285 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
25286 @@ -2813,7 +2813,7 @@ out:
25287 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
25288 struct iattr *sattr, dev_t rdev)
25289 {
25290 - struct nfs4_exception exception = { };
25291 + struct nfs4_exception exception = {0, 0};
25292 int err;
25293 do {
25294 err = nfs4_handle_exception(NFS_SERVER(dir),
25295 @@ -2845,7 +2845,7 @@ static int _nfs4_proc_statfs(struct nfs_
25296
25297 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
25298 {
25299 - struct nfs4_exception exception = { };
25300 + struct nfs4_exception exception = {0, 0};
25301 int err;
25302 do {
25303 err = nfs4_handle_exception(server,
25304 @@ -2876,7 +2876,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
25305
25306 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
25307 {
25308 - struct nfs4_exception exception = { };
25309 + struct nfs4_exception exception = {0, 0};
25310 int err;
25311
25312 do {
25313 @@ -2922,7 +2922,7 @@ static int _nfs4_proc_pathconf(struct nf
25314 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
25315 struct nfs_pathconf *pathconf)
25316 {
25317 - struct nfs4_exception exception = { };
25318 + struct nfs4_exception exception = {0, 0};
25319 int err;
25320
25321 do {
25322 @@ -3224,7 +3224,7 @@ out_free:
25323
25324 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
25325 {
25326 - struct nfs4_exception exception = { };
25327 + struct nfs4_exception exception = {0, 0};
25328 ssize_t ret;
25329 do {
25330 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
25331 @@ -3280,7 +3280,7 @@ static int __nfs4_proc_set_acl(struct in
25332
25333 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
25334 {
25335 - struct nfs4_exception exception = { };
25336 + struct nfs4_exception exception = {0, 0};
25337 int err;
25338 do {
25339 err = nfs4_handle_exception(NFS_SERVER(inode),
25340 @@ -3545,7 +3545,7 @@ out:
25341 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
25342 {
25343 struct nfs_server *server = NFS_SERVER(inode);
25344 - struct nfs4_exception exception = { };
25345 + struct nfs4_exception exception = {0, 0};
25346 int err;
25347 do {
25348 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
25349 @@ -3618,7 +3618,7 @@ out:
25350
25351 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
25352 {
25353 - struct nfs4_exception exception = { };
25354 + struct nfs4_exception exception = {0, 0};
25355 int err;
25356
25357 do {
25358 @@ -3992,7 +3992,7 @@ static int _nfs4_do_setlk(struct nfs4_st
25359 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
25360 {
25361 struct nfs_server *server = NFS_SERVER(state->inode);
25362 - struct nfs4_exception exception = { };
25363 + struct nfs4_exception exception = {0, 0};
25364 int err;
25365
25366 do {
25367 @@ -4010,7 +4010,7 @@ static int nfs4_lock_reclaim(struct nfs4
25368 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
25369 {
25370 struct nfs_server *server = NFS_SERVER(state->inode);
25371 - struct nfs4_exception exception = { };
25372 + struct nfs4_exception exception = {0, 0};
25373 int err;
25374
25375 err = nfs4_set_lock_state(state, request);
25376 @@ -4065,7 +4065,7 @@ out:
25377
25378 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
25379 {
25380 - struct nfs4_exception exception = { };
25381 + struct nfs4_exception exception = {0, 0};
25382 int err;
25383
25384 do {
25385 @@ -4125,7 +4125,7 @@ nfs4_proc_lock(struct file *filp, int cm
25386 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
25387 {
25388 struct nfs_server *server = NFS_SERVER(state->inode);
25389 - struct nfs4_exception exception = { };
25390 + struct nfs4_exception exception = {0, 0};
25391 int err;
25392
25393 err = nfs4_set_lock_state(state, fl);
25394 diff -urNp linux-2.6.31.1/fs/nfsd/export.c linux-2.6.31.1/fs/nfsd/export.c
25395 --- linux-2.6.31.1/fs/nfsd/export.c 2009-09-24 11:45:25.000000000 -0400
25396 +++ linux-2.6.31.1/fs/nfsd/export.c 2009-10-01 20:12:44.000000000 -0400
25397 @@ -1505,7 +1505,7 @@ static int e_show(struct seq_file *m, vo
25398 return svc_export_show(m, &svc_export_cache, cp);
25399 }
25400
25401 -struct seq_operations nfs_exports_op = {
25402 +const struct seq_operations nfs_exports_op = {
25403 .start = e_start,
25404 .next = e_next,
25405 .stop = e_stop,
25406 diff -urNp linux-2.6.31.1/fs/nfsd/nfsctl.c linux-2.6.31.1/fs/nfsd/nfsctl.c
25407 --- linux-2.6.31.1/fs/nfsd/nfsctl.c 2009-09-24 11:45:25.000000000 -0400
25408 +++ linux-2.6.31.1/fs/nfsd/nfsctl.c 2009-10-01 20:12:44.000000000 -0400
25409 @@ -174,7 +174,7 @@ static const struct file_operations expo
25410
25411 extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
25412
25413 -static struct file_operations pool_stats_operations = {
25414 +static const struct file_operations pool_stats_operations = {
25415 .open = nfsd_pool_stats_open,
25416 .read = seq_read,
25417 .llseek = seq_lseek,
25418 diff -urNp linux-2.6.31.1/fs/nilfs2/btnode.c linux-2.6.31.1/fs/nilfs2/btnode.c
25419 --- linux-2.6.31.1/fs/nilfs2/btnode.c 2009-09-24 11:45:25.000000000 -0400
25420 +++ linux-2.6.31.1/fs/nilfs2/btnode.c 2009-10-01 20:12:44.000000000 -0400
25421 @@ -46,7 +46,7 @@ void nilfs_btnode_cache_init_once(struct
25422 INIT_LIST_HEAD(&btnc->i_mmap_nonlinear);
25423 }
25424
25425 -static struct address_space_operations def_btnode_aops = {
25426 +static const struct address_space_operations def_btnode_aops = {
25427 .sync_page = block_sync_page,
25428 };
25429
25430 diff -urNp linux-2.6.31.1/fs/nilfs2/dir.c linux-2.6.31.1/fs/nilfs2/dir.c
25431 --- linux-2.6.31.1/fs/nilfs2/dir.c 2009-09-24 11:45:25.000000000 -0400
25432 +++ linux-2.6.31.1/fs/nilfs2/dir.c 2009-10-01 20:12:44.000000000 -0400
25433 @@ -697,7 +697,7 @@ not_empty:
25434 return 0;
25435 }
25436
25437 -struct file_operations nilfs_dir_operations = {
25438 +const struct file_operations nilfs_dir_operations = {
25439 .llseek = generic_file_llseek,
25440 .read = generic_read_dir,
25441 .readdir = nilfs_readdir,
25442 diff -urNp linux-2.6.31.1/fs/nilfs2/file.c linux-2.6.31.1/fs/nilfs2/file.c
25443 --- linux-2.6.31.1/fs/nilfs2/file.c 2009-09-24 11:45:25.000000000 -0400
25444 +++ linux-2.6.31.1/fs/nilfs2/file.c 2009-10-01 20:12:44.000000000 -0400
25445 @@ -117,7 +117,7 @@ static int nilfs_page_mkwrite(struct vm_
25446 return 0;
25447 }
25448
25449 -struct vm_operations_struct nilfs_file_vm_ops = {
25450 +const struct vm_operations_struct nilfs_file_vm_ops = {
25451 .fault = filemap_fault,
25452 .page_mkwrite = nilfs_page_mkwrite,
25453 };
25454 @@ -134,7 +134,7 @@ static int nilfs_file_mmap(struct file *
25455 * We have mostly NULL's here: the current defaults are ok for
25456 * the nilfs filesystem.
25457 */
25458 -struct file_operations nilfs_file_operations = {
25459 +const struct file_operations nilfs_file_operations = {
25460 .llseek = generic_file_llseek,
25461 .read = do_sync_read,
25462 .write = do_sync_write,
25463 @@ -151,7 +151,7 @@ struct file_operations nilfs_file_operat
25464 .splice_read = generic_file_splice_read,
25465 };
25466
25467 -struct inode_operations nilfs_file_inode_operations = {
25468 +const struct inode_operations nilfs_file_inode_operations = {
25469 .truncate = nilfs_truncate,
25470 .setattr = nilfs_setattr,
25471 .permission = nilfs_permission,
25472 diff -urNp linux-2.6.31.1/fs/nilfs2/gcinode.c linux-2.6.31.1/fs/nilfs2/gcinode.c
25473 --- linux-2.6.31.1/fs/nilfs2/gcinode.c 2009-09-24 11:45:25.000000000 -0400
25474 +++ linux-2.6.31.1/fs/nilfs2/gcinode.c 2009-10-01 20:12:44.000000000 -0400
25475 @@ -52,7 +52,7 @@
25476 #include "dat.h"
25477 #include "ifile.h"
25478
25479 -static struct address_space_operations def_gcinode_aops = {
25480 +static const struct address_space_operations def_gcinode_aops = {
25481 .sync_page = block_sync_page,
25482 };
25483
25484 diff -urNp linux-2.6.31.1/fs/nilfs2/inode.c linux-2.6.31.1/fs/nilfs2/inode.c
25485 --- linux-2.6.31.1/fs/nilfs2/inode.c 2009-09-24 11:45:25.000000000 -0400
25486 +++ linux-2.6.31.1/fs/nilfs2/inode.c 2009-10-01 20:12:44.000000000 -0400
25487 @@ -238,7 +238,7 @@ nilfs_direct_IO(int rw, struct kiocb *io
25488 return size;
25489 }
25490
25491 -struct address_space_operations nilfs_aops = {
25492 +const struct address_space_operations nilfs_aops = {
25493 .writepage = nilfs_writepage,
25494 .readpage = nilfs_readpage,
25495 .sync_page = block_sync_page,
25496 diff -urNp linux-2.6.31.1/fs/nilfs2/mdt.c linux-2.6.31.1/fs/nilfs2/mdt.c
25497 --- linux-2.6.31.1/fs/nilfs2/mdt.c 2009-09-24 11:45:25.000000000 -0400
25498 +++ linux-2.6.31.1/fs/nilfs2/mdt.c 2009-10-01 20:12:44.000000000 -0400
25499 @@ -430,7 +430,7 @@ nilfs_mdt_write_page(struct page *page,
25500 }
25501
25502
25503 -static struct address_space_operations def_mdt_aops = {
25504 +static const struct address_space_operations def_mdt_aops = {
25505 .writepage = nilfs_mdt_write_page,
25506 .sync_page = block_sync_page,
25507 };
25508 diff -urNp linux-2.6.31.1/fs/nilfs2/namei.c linux-2.6.31.1/fs/nilfs2/namei.c
25509 --- linux-2.6.31.1/fs/nilfs2/namei.c 2009-09-24 11:45:25.000000000 -0400
25510 +++ linux-2.6.31.1/fs/nilfs2/namei.c 2009-10-01 20:12:44.000000000 -0400
25511 @@ -448,7 +448,7 @@ out:
25512 return err;
25513 }
25514
25515 -struct inode_operations nilfs_dir_inode_operations = {
25516 +const struct inode_operations nilfs_dir_inode_operations = {
25517 .create = nilfs_create,
25518 .lookup = nilfs_lookup,
25519 .link = nilfs_link,
25520 @@ -462,12 +462,12 @@ struct inode_operations nilfs_dir_inode_
25521 .permission = nilfs_permission,
25522 };
25523
25524 -struct inode_operations nilfs_special_inode_operations = {
25525 +const struct inode_operations nilfs_special_inode_operations = {
25526 .setattr = nilfs_setattr,
25527 .permission = nilfs_permission,
25528 };
25529
25530 -struct inode_operations nilfs_symlink_inode_operations = {
25531 +const struct inode_operations nilfs_symlink_inode_operations = {
25532 .readlink = generic_readlink,
25533 .follow_link = page_follow_link_light,
25534 .put_link = page_put_link,
25535 diff -urNp linux-2.6.31.1/fs/nilfs2/nilfs.h linux-2.6.31.1/fs/nilfs2/nilfs.h
25536 --- linux-2.6.31.1/fs/nilfs2/nilfs.h 2009-09-24 11:45:25.000000000 -0400
25537 +++ linux-2.6.31.1/fs/nilfs2/nilfs.h 2009-10-01 20:12:44.000000000 -0400
25538 @@ -294,13 +294,13 @@ void nilfs_clear_gcdat_inode(struct the_
25539 /*
25540 * Inodes and files operations
25541 */
25542 -extern struct file_operations nilfs_dir_operations;
25543 -extern struct inode_operations nilfs_file_inode_operations;
25544 -extern struct file_operations nilfs_file_operations;
25545 -extern struct address_space_operations nilfs_aops;
25546 -extern struct inode_operations nilfs_dir_inode_operations;
25547 -extern struct inode_operations nilfs_special_inode_operations;
25548 -extern struct inode_operations nilfs_symlink_inode_operations;
25549 +extern const struct file_operations nilfs_dir_operations;
25550 +extern const struct inode_operations nilfs_file_inode_operations;
25551 +extern const struct file_operations nilfs_file_operations;
25552 +extern const struct address_space_operations nilfs_aops;
25553 +extern const struct inode_operations nilfs_dir_inode_operations;
25554 +extern const struct inode_operations nilfs_special_inode_operations;
25555 +extern const struct inode_operations nilfs_symlink_inode_operations;
25556
25557 /*
25558 * filesystem type
25559 diff -urNp linux-2.6.31.1/fs/nilfs2/super.c linux-2.6.31.1/fs/nilfs2/super.c
25560 --- linux-2.6.31.1/fs/nilfs2/super.c 2009-09-24 11:45:25.000000000 -0400
25561 +++ linux-2.6.31.1/fs/nilfs2/super.c 2009-10-01 20:12:44.000000000 -0400
25562 @@ -529,7 +529,7 @@ static int nilfs_statfs(struct dentry *d
25563 return 0;
25564 }
25565
25566 -static struct super_operations nilfs_sops = {
25567 +static const struct super_operations nilfs_sops = {
25568 .alloc_inode = nilfs_alloc_inode,
25569 .destroy_inode = nilfs_destroy_inode,
25570 .dirty_inode = nilfs_dirty_inode,
25571 diff -urNp linux-2.6.31.1/fs/nls/nls_base.c linux-2.6.31.1/fs/nls/nls_base.c
25572 --- linux-2.6.31.1/fs/nls/nls_base.c 2009-09-24 11:45:25.000000000 -0400
25573 +++ linux-2.6.31.1/fs/nls/nls_base.c 2009-10-01 20:12:44.000000000 -0400
25574 @@ -41,7 +41,7 @@ static const struct utf8_table utf8_tabl
25575 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
25576 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
25577 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
25578 - {0, /* end of table */}
25579 + {0, 0, 0, 0, 0, /* end of table */}
25580 };
25581
25582 #define UNICODE_MAX 0x0010ffff
25583 diff -urNp linux-2.6.31.1/fs/ntfs/file.c linux-2.6.31.1/fs/ntfs/file.c
25584 --- linux-2.6.31.1/fs/ntfs/file.c 2009-09-24 11:45:25.000000000 -0400
25585 +++ linux-2.6.31.1/fs/ntfs/file.c 2009-10-01 20:12:44.000000000 -0400
25586 @@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
25587 #endif /* NTFS_RW */
25588 };
25589
25590 -const struct file_operations ntfs_empty_file_ops = {};
25591 +const struct file_operations ntfs_empty_file_ops;
25592
25593 -const struct inode_operations ntfs_empty_inode_ops = {};
25594 +const struct inode_operations ntfs_empty_inode_ops;
25595 diff -urNp linux-2.6.31.1/fs/ocfs2/cluster/heartbeat.c linux-2.6.31.1/fs/ocfs2/cluster/heartbeat.c
25596 --- linux-2.6.31.1/fs/ocfs2/cluster/heartbeat.c 2009-09-24 11:45:25.000000000 -0400
25597 +++ linux-2.6.31.1/fs/ocfs2/cluster/heartbeat.c 2009-10-01 20:12:44.000000000 -0400
25598 @@ -966,7 +966,7 @@ static ssize_t o2hb_debug_read(struct fi
25599 }
25600 #endif /* CONFIG_DEBUG_FS */
25601
25602 -static struct file_operations o2hb_debug_fops = {
25603 +static const struct file_operations o2hb_debug_fops = {
25604 .open = o2hb_debug_open,
25605 .release = o2hb_debug_release,
25606 .read = o2hb_debug_read,
25607 diff -urNp linux-2.6.31.1/fs/ocfs2/cluster/netdebug.c linux-2.6.31.1/fs/ocfs2/cluster/netdebug.c
25608 --- linux-2.6.31.1/fs/ocfs2/cluster/netdebug.c 2009-09-24 11:45:25.000000000 -0400
25609 +++ linux-2.6.31.1/fs/ocfs2/cluster/netdebug.c 2009-10-01 20:12:44.000000000 -0400
25610 @@ -163,7 +163,7 @@ static void nst_seq_stop(struct seq_file
25611 {
25612 }
25613
25614 -static struct seq_operations nst_seq_ops = {
25615 +static const struct seq_operations nst_seq_ops = {
25616 .start = nst_seq_start,
25617 .next = nst_seq_next,
25618 .stop = nst_seq_stop,
25619 @@ -207,7 +207,7 @@ static int nst_fop_release(struct inode
25620 return seq_release_private(inode, file);
25621 }
25622
25623 -static struct file_operations nst_seq_fops = {
25624 +static const struct file_operations nst_seq_fops = {
25625 .open = nst_fop_open,
25626 .read = seq_read,
25627 .llseek = seq_lseek,
25628 @@ -344,7 +344,7 @@ static void sc_seq_stop(struct seq_file
25629 {
25630 }
25631
25632 -static struct seq_operations sc_seq_ops = {
25633 +static const struct seq_operations sc_seq_ops = {
25634 .start = sc_seq_start,
25635 .next = sc_seq_next,
25636 .stop = sc_seq_stop,
25637 @@ -388,7 +388,7 @@ static int sc_fop_release(struct inode *
25638 return seq_release_private(inode, file);
25639 }
25640
25641 -static struct file_operations sc_seq_fops = {
25642 +static const struct file_operations sc_seq_fops = {
25643 .open = sc_fop_open,
25644 .read = seq_read,
25645 .llseek = seq_lseek,
25646 diff -urNp linux-2.6.31.1/fs/ocfs2/dlm/dlmdebug.c linux-2.6.31.1/fs/ocfs2/dlm/dlmdebug.c
25647 --- linux-2.6.31.1/fs/ocfs2/dlm/dlmdebug.c 2009-09-24 11:45:25.000000000 -0400
25648 +++ linux-2.6.31.1/fs/ocfs2/dlm/dlmdebug.c 2009-10-01 20:12:44.000000000 -0400
25649 @@ -479,7 +479,7 @@ bail:
25650 return -ENOMEM;
25651 }
25652
25653 -static struct file_operations debug_purgelist_fops = {
25654 +static const struct file_operations debug_purgelist_fops = {
25655 .open = debug_purgelist_open,
25656 .release = debug_buffer_release,
25657 .read = debug_buffer_read,
25658 @@ -539,7 +539,7 @@ bail:
25659 return -ENOMEM;
25660 }
25661
25662 -static struct file_operations debug_mle_fops = {
25663 +static const struct file_operations debug_mle_fops = {
25664 .open = debug_mle_open,
25665 .release = debug_buffer_release,
25666 .read = debug_buffer_read,
25667 @@ -683,7 +683,7 @@ static int lockres_seq_show(struct seq_f
25668 return 0;
25669 }
25670
25671 -static struct seq_operations debug_lockres_ops = {
25672 +static const struct seq_operations debug_lockres_ops = {
25673 .start = lockres_seq_start,
25674 .stop = lockres_seq_stop,
25675 .next = lockres_seq_next,
25676 @@ -742,7 +742,7 @@ static int debug_lockres_release(struct
25677 return seq_release_private(inode, file);
25678 }
25679
25680 -static struct file_operations debug_lockres_fops = {
25681 +static const struct file_operations debug_lockres_fops = {
25682 .open = debug_lockres_open,
25683 .release = debug_lockres_release,
25684 .read = seq_read,
25685 @@ -926,7 +926,7 @@ bail:
25686 return -ENOMEM;
25687 }
25688
25689 -static struct file_operations debug_state_fops = {
25690 +static const struct file_operations debug_state_fops = {
25691 .open = debug_state_open,
25692 .release = debug_buffer_release,
25693 .read = debug_buffer_read,
25694 diff -urNp linux-2.6.31.1/fs/ocfs2/localalloc.c linux-2.6.31.1/fs/ocfs2/localalloc.c
25695 --- linux-2.6.31.1/fs/ocfs2/localalloc.c 2009-09-24 11:45:25.000000000 -0400
25696 +++ linux-2.6.31.1/fs/ocfs2/localalloc.c 2009-10-01 20:12:44.000000000 -0400
25697 @@ -1186,7 +1186,7 @@ static int ocfs2_local_alloc_slide_windo
25698 goto bail;
25699 }
25700
25701 - atomic_inc(&osb->alloc_stats.moves);
25702 + atomic_inc_unchecked(&osb->alloc_stats.moves);
25703
25704 status = 0;
25705 bail:
25706 diff -urNp linux-2.6.31.1/fs/ocfs2/mmap.c linux-2.6.31.1/fs/ocfs2/mmap.c
25707 --- linux-2.6.31.1/fs/ocfs2/mmap.c 2009-09-24 11:45:25.000000000 -0400
25708 +++ linux-2.6.31.1/fs/ocfs2/mmap.c 2009-10-01 20:12:44.000000000 -0400
25709 @@ -202,7 +202,7 @@ out:
25710 return ret;
25711 }
25712
25713 -static struct vm_operations_struct ocfs2_file_vm_ops = {
25714 +static const struct vm_operations_struct ocfs2_file_vm_ops = {
25715 .fault = ocfs2_fault,
25716 .page_mkwrite = ocfs2_page_mkwrite,
25717 };
25718 diff -urNp linux-2.6.31.1/fs/ocfs2/ocfs2.h linux-2.6.31.1/fs/ocfs2/ocfs2.h
25719 --- linux-2.6.31.1/fs/ocfs2/ocfs2.h 2009-09-24 11:45:25.000000000 -0400
25720 +++ linux-2.6.31.1/fs/ocfs2/ocfs2.h 2009-10-01 20:12:44.000000000 -0400
25721 @@ -191,11 +191,11 @@ enum ocfs2_vol_state
25722
25723 struct ocfs2_alloc_stats
25724 {
25725 - atomic_t moves;
25726 - atomic_t local_data;
25727 - atomic_t bitmap_data;
25728 - atomic_t bg_allocs;
25729 - atomic_t bg_extends;
25730 + atomic_unchecked_t moves;
25731 + atomic_unchecked_t local_data;
25732 + atomic_unchecked_t bitmap_data;
25733 + atomic_unchecked_t bg_allocs;
25734 + atomic_unchecked_t bg_extends;
25735 };
25736
25737 enum ocfs2_local_alloc_state
25738 diff -urNp linux-2.6.31.1/fs/ocfs2/suballoc.c linux-2.6.31.1/fs/ocfs2/suballoc.c
25739 --- linux-2.6.31.1/fs/ocfs2/suballoc.c 2009-09-24 11:45:25.000000000 -0400
25740 +++ linux-2.6.31.1/fs/ocfs2/suballoc.c 2009-10-01 20:12:44.000000000 -0400
25741 @@ -620,7 +620,7 @@ static int ocfs2_reserve_suballoc_bits(s
25742 mlog_errno(status);
25743 goto bail;
25744 }
25745 - atomic_inc(&osb->alloc_stats.bg_extends);
25746 + atomic_inc_unchecked(&osb->alloc_stats.bg_extends);
25747
25748 /* You should never ask for this much metadata */
25749 BUG_ON(bits_wanted >
25750 @@ -1650,7 +1650,7 @@ int ocfs2_claim_metadata(struct ocfs2_su
25751 mlog_errno(status);
25752 goto bail;
25753 }
25754 - atomic_inc(&osb->alloc_stats.bg_allocs);
25755 + atomic_inc_unchecked(&osb->alloc_stats.bg_allocs);
25756
25757 *blkno_start = bg_blkno + (u64) *suballoc_bit_start;
25758 ac->ac_bits_given += (*num_bits);
25759 @@ -1724,7 +1724,7 @@ int ocfs2_claim_new_inode(struct ocfs2_s
25760 mlog_errno(status);
25761 goto bail;
25762 }
25763 - atomic_inc(&osb->alloc_stats.bg_allocs);
25764 + atomic_inc_unchecked(&osb->alloc_stats.bg_allocs);
25765
25766 BUG_ON(num_bits != 1);
25767
25768 @@ -1826,7 +1826,7 @@ int __ocfs2_claim_clusters(struct ocfs2_
25769 cluster_start,
25770 num_clusters);
25771 if (!status)
25772 - atomic_inc(&osb->alloc_stats.local_data);
25773 + atomic_inc_unchecked(&osb->alloc_stats.local_data);
25774 } else {
25775 if (min_clusters > (osb->bitmap_cpg - 1)) {
25776 /* The only paths asking for contiguousness
25777 @@ -1854,7 +1854,7 @@ int __ocfs2_claim_clusters(struct ocfs2_
25778 ocfs2_desc_bitmap_to_cluster_off(ac->ac_inode,
25779 bg_blkno,
25780 bg_bit_off);
25781 - atomic_inc(&osb->alloc_stats.bitmap_data);
25782 + atomic_inc_unchecked(&osb->alloc_stats.bitmap_data);
25783 }
25784 }
25785 if (status < 0) {
25786 diff -urNp linux-2.6.31.1/fs/ocfs2/super.c linux-2.6.31.1/fs/ocfs2/super.c
25787 --- linux-2.6.31.1/fs/ocfs2/super.c 2009-09-24 11:45:25.000000000 -0400
25788 +++ linux-2.6.31.1/fs/ocfs2/super.c 2009-10-01 20:12:44.000000000 -0400
25789 @@ -284,11 +284,11 @@ static int ocfs2_osb_dump(struct ocfs2_s
25790 "%10s => GlobalAllocs: %d LocalAllocs: %d "
25791 "SubAllocs: %d LAWinMoves: %d SAExtends: %d\n",
25792 "Stats",
25793 - atomic_read(&osb->alloc_stats.bitmap_data),
25794 - atomic_read(&osb->alloc_stats.local_data),
25795 - atomic_read(&osb->alloc_stats.bg_allocs),
25796 - atomic_read(&osb->alloc_stats.moves),
25797 - atomic_read(&osb->alloc_stats.bg_extends));
25798 + atomic_read_unchecked(&osb->alloc_stats.bitmap_data),
25799 + atomic_read_unchecked(&osb->alloc_stats.local_data),
25800 + atomic_read_unchecked(&osb->alloc_stats.bg_allocs),
25801 + atomic_read_unchecked(&osb->alloc_stats.moves),
25802 + atomic_read_unchecked(&osb->alloc_stats.bg_extends));
25803
25804 out += snprintf(buf + out, len - out,
25805 "%10s => State: %u Descriptor: %llu Size: %u bits "
25806 @@ -373,7 +373,7 @@ static ssize_t ocfs2_debug_read(struct f
25807 }
25808 #endif /* CONFIG_DEBUG_FS */
25809
25810 -static struct file_operations ocfs2_osb_debug_fops = {
25811 +static const struct file_operations ocfs2_osb_debug_fops = {
25812 .open = ocfs2_osb_debug_open,
25813 .release = ocfs2_debug_release,
25814 .read = ocfs2_debug_read,
25815 @@ -1991,11 +1991,11 @@ static int ocfs2_initialize_super(struct
25816 spin_lock_init(&osb->osb_xattr_lock);
25817 ocfs2_init_inode_steal_slot(osb);
25818
25819 - atomic_set(&osb->alloc_stats.moves, 0);
25820 - atomic_set(&osb->alloc_stats.local_data, 0);
25821 - atomic_set(&osb->alloc_stats.bitmap_data, 0);
25822 - atomic_set(&osb->alloc_stats.bg_allocs, 0);
25823 - atomic_set(&osb->alloc_stats.bg_extends, 0);
25824 + atomic_set_unchecked(&osb->alloc_stats.moves, 0);
25825 + atomic_set_unchecked(&osb->alloc_stats.local_data, 0);
25826 + atomic_set_unchecked(&osb->alloc_stats.bitmap_data, 0);
25827 + atomic_set_unchecked(&osb->alloc_stats.bg_allocs, 0);
25828 + atomic_set_unchecked(&osb->alloc_stats.bg_extends, 0);
25829
25830 /* Copy the blockcheck stats from the superblock probe */
25831 osb->osb_ecc_stats = *stats;
25832 diff -urNp linux-2.6.31.1/fs/omfs/dir.c linux-2.6.31.1/fs/omfs/dir.c
25833 --- linux-2.6.31.1/fs/omfs/dir.c 2009-09-24 11:45:25.000000000 -0400
25834 +++ linux-2.6.31.1/fs/omfs/dir.c 2009-10-01 20:12:44.000000000 -0400
25835 @@ -489,7 +489,7 @@ out:
25836 return ret;
25837 }
25838
25839 -struct inode_operations omfs_dir_inops = {
25840 +const struct inode_operations omfs_dir_inops = {
25841 .lookup = omfs_lookup,
25842 .mkdir = omfs_mkdir,
25843 .rename = omfs_rename,
25844 @@ -498,7 +498,7 @@ struct inode_operations omfs_dir_inops =
25845 .rmdir = omfs_rmdir,
25846 };
25847
25848 -struct file_operations omfs_dir_operations = {
25849 +const struct file_operations omfs_dir_operations = {
25850 .read = generic_read_dir,
25851 .readdir = omfs_readdir,
25852 .llseek = generic_file_llseek,
25853 diff -urNp linux-2.6.31.1/fs/omfs/file.c linux-2.6.31.1/fs/omfs/file.c
25854 --- linux-2.6.31.1/fs/omfs/file.c 2009-09-24 11:45:25.000000000 -0400
25855 +++ linux-2.6.31.1/fs/omfs/file.c 2009-10-01 20:12:44.000000000 -0400
25856 @@ -322,7 +322,7 @@ static sector_t omfs_bmap(struct address
25857 return generic_block_bmap(mapping, block, omfs_get_block);
25858 }
25859
25860 -struct file_operations omfs_file_operations = {
25861 +const struct file_operations omfs_file_operations = {
25862 .llseek = generic_file_llseek,
25863 .read = do_sync_read,
25864 .write = do_sync_write,
25865 @@ -333,11 +333,11 @@ struct file_operations omfs_file_operati
25866 .splice_read = generic_file_splice_read,
25867 };
25868
25869 -struct inode_operations omfs_file_inops = {
25870 +const struct inode_operations omfs_file_inops = {
25871 .truncate = omfs_truncate
25872 };
25873
25874 -struct address_space_operations omfs_aops = {
25875 +const struct address_space_operations omfs_aops = {
25876 .readpage = omfs_readpage,
25877 .readpages = omfs_readpages,
25878 .writepage = omfs_writepage,
25879 diff -urNp linux-2.6.31.1/fs/omfs/inode.c linux-2.6.31.1/fs/omfs/inode.c
25880 --- linux-2.6.31.1/fs/omfs/inode.c 2009-09-24 11:45:25.000000000 -0400
25881 +++ linux-2.6.31.1/fs/omfs/inode.c 2009-10-01 20:12:44.000000000 -0400
25882 @@ -278,7 +278,7 @@ static int omfs_statfs(struct dentry *de
25883 return 0;
25884 }
25885
25886 -static struct super_operations omfs_sops = {
25887 +static const struct super_operations omfs_sops = {
25888 .write_inode = omfs_write_inode,
25889 .delete_inode = omfs_delete_inode,
25890 .put_super = omfs_put_super,
25891 diff -urNp linux-2.6.31.1/fs/omfs/omfs.h linux-2.6.31.1/fs/omfs/omfs.h
25892 --- linux-2.6.31.1/fs/omfs/omfs.h 2009-09-24 11:45:25.000000000 -0400
25893 +++ linux-2.6.31.1/fs/omfs/omfs.h 2009-10-01 20:12:44.000000000 -0400
25894 @@ -44,16 +44,16 @@ extern int omfs_allocate_range(struct su
25895 extern int omfs_clear_range(struct super_block *sb, u64 block, int count);
25896
25897 /* dir.c */
25898 -extern struct file_operations omfs_dir_operations;
25899 -extern struct inode_operations omfs_dir_inops;
25900 +extern const struct file_operations omfs_dir_operations;
25901 +extern const struct inode_operations omfs_dir_inops;
25902 extern int omfs_make_empty(struct inode *inode, struct super_block *sb);
25903 extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header,
25904 u64 fsblock);
25905
25906 /* file.c */
25907 -extern struct file_operations omfs_file_operations;
25908 -extern struct inode_operations omfs_file_inops;
25909 -extern struct address_space_operations omfs_aops;
25910 +extern const struct file_operations omfs_file_operations;
25911 +extern const struct inode_operations omfs_file_inops;
25912 +extern const struct address_space_operations omfs_aops;
25913 extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
25914 extern int omfs_shrink_inode(struct inode *inode);
25915
25916 diff -urNp linux-2.6.31.1/fs/open.c linux-2.6.31.1/fs/open.c
25917 --- linux-2.6.31.1/fs/open.c 2009-09-24 11:45:25.000000000 -0400
25918 +++ linux-2.6.31.1/fs/open.c 2009-10-01 20:12:44.000000000 -0400
25919 @@ -206,6 +206,9 @@ int do_truncate(struct dentry *dentry, l
25920 if (length < 0)
25921 return -EINVAL;
25922
25923 + if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
25924 + return -EACCES;
25925 +
25926 newattrs.ia_size = length;
25927 newattrs.ia_valid = ATTR_SIZE | time_attrs;
25928 if (filp) {
25929 @@ -510,6 +513,9 @@ SYSCALL_DEFINE3(faccessat, int, dfd, con
25930 if (__mnt_is_readonly(path.mnt))
25931 res = -EROFS;
25932
25933 + if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
25934 + res = -EACCES;
25935 +
25936 out_path_release:
25937 path_put(&path);
25938 out:
25939 @@ -536,6 +542,8 @@ SYSCALL_DEFINE1(chdir, const char __user
25940 if (error)
25941 goto dput_and_out;
25942
25943 + gr_log_chdir(path.dentry, path.mnt);
25944 +
25945 set_fs_pwd(current->fs, &path);
25946
25947 dput_and_out:
25948 @@ -562,6 +570,13 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd
25949 goto out_putf;
25950
25951 error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
25952 +
25953 + if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
25954 + error = -EPERM;
25955 +
25956 + if (!error)
25957 + gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
25958 +
25959 if (!error)
25960 set_fs_pwd(current->fs, &file->f_path);
25961 out_putf:
25962 @@ -587,7 +602,18 @@ SYSCALL_DEFINE1(chroot, const char __use
25963 if (!capable(CAP_SYS_CHROOT))
25964 goto dput_and_out;
25965
25966 + if (gr_handle_chroot_chroot(path.dentry, path.mnt))
25967 + goto dput_and_out;
25968 +
25969 + if (gr_handle_chroot_caps(&path)) {
25970 + error = -ENOMEM;
25971 + goto dput_and_out;
25972 + }
25973 +
25974 set_fs_root(current->fs, &path);
25975 +
25976 + gr_handle_chroot_chdir(&path);
25977 +
25978 error = 0;
25979 dput_and_out:
25980 path_put(&path);
25981 @@ -615,13 +641,28 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd
25982 err = mnt_want_write_file(file);
25983 if (err)
25984 goto out_putf;
25985 +
25986 + if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
25987 + err = -EACCES;
25988 + goto out_drop_write;
25989 + }
25990 +
25991 mutex_lock(&inode->i_mutex);
25992 if (mode == (mode_t) -1)
25993 mode = inode->i_mode;
25994 +
25995 + if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
25996 + err = -EPERM;
25997 + mutex_unlock(&inode->i_mutex);
25998 + goto out_drop_write;
25999 + }
26000 +
26001 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
26002 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
26003 err = notify_change(dentry, &newattrs);
26004 mutex_unlock(&inode->i_mutex);
26005 +
26006 +out_drop_write:
26007 mnt_drop_write(file->f_path.mnt);
26008 out_putf:
26009 fput(file);
26010 @@ -644,13 +685,28 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
26011 error = mnt_want_write(path.mnt);
26012 if (error)
26013 goto dput_and_out;
26014 +
26015 + if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
26016 + error = -EACCES;
26017 + goto out_drop_write;
26018 + }
26019 +
26020 mutex_lock(&inode->i_mutex);
26021 if (mode == (mode_t) -1)
26022 mode = inode->i_mode;
26023 +
26024 + if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
26025 + error = -EACCES;
26026 + mutex_unlock(&inode->i_mutex);
26027 + goto out_drop_write;
26028 + }
26029 +
26030 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
26031 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
26032 error = notify_change(path.dentry, &newattrs);
26033 mutex_unlock(&inode->i_mutex);
26034 +
26035 +out_drop_write:
26036 mnt_drop_write(path.mnt);
26037 dput_and_out:
26038 path_put(&path);
26039 @@ -663,12 +719,15 @@ SYSCALL_DEFINE2(chmod, const char __user
26040 return sys_fchmodat(AT_FDCWD, filename, mode);
26041 }
26042
26043 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
26044 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
26045 {
26046 struct inode *inode = dentry->d_inode;
26047 int error;
26048 struct iattr newattrs;
26049
26050 + if (!gr_acl_handle_chown(dentry, mnt))
26051 + return -EACCES;
26052 +
26053 newattrs.ia_valid = ATTR_CTIME;
26054 if (user != (uid_t) -1) {
26055 newattrs.ia_valid |= ATTR_UID;
26056 @@ -699,7 +758,7 @@ SYSCALL_DEFINE3(chown, const char __user
26057 error = mnt_want_write(path.mnt);
26058 if (error)
26059 goto out_release;
26060 - error = chown_common(path.dentry, user, group);
26061 + error = chown_common(path.dentry, user, group, path.mnt);
26062 mnt_drop_write(path.mnt);
26063 out_release:
26064 path_put(&path);
26065 @@ -724,7 +783,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, cons
26066 error = mnt_want_write(path.mnt);
26067 if (error)
26068 goto out_release;
26069 - error = chown_common(path.dentry, user, group);
26070 + error = chown_common(path.dentry, user, group, path.mnt);
26071 mnt_drop_write(path.mnt);
26072 out_release:
26073 path_put(&path);
26074 @@ -743,7 +802,7 @@ SYSCALL_DEFINE3(lchown, const char __use
26075 error = mnt_want_write(path.mnt);
26076 if (error)
26077 goto out_release;
26078 - error = chown_common(path.dentry, user, group);
26079 + error = chown_common(path.dentry, user, group, path.mnt);
26080 mnt_drop_write(path.mnt);
26081 out_release:
26082 path_put(&path);
26083 @@ -766,7 +825,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd
26084 goto out_fput;
26085 dentry = file->f_path.dentry;
26086 audit_inode(NULL, dentry);
26087 - error = chown_common(dentry, user, group);
26088 + error = chown_common(dentry, user, group, file->f_path.mnt);
26089 mnt_drop_write(file->f_path.mnt);
26090 out_fput:
26091 fput(file);
26092 diff -urNp linux-2.6.31.1/fs/pipe.c linux-2.6.31.1/fs/pipe.c
26093 --- linux-2.6.31.1/fs/pipe.c 2009-09-24 11:45:25.000000000 -0400
26094 +++ linux-2.6.31.1/fs/pipe.c 2009-10-01 20:12:44.000000000 -0400
26095 @@ -886,7 +886,7 @@ void free_pipe_info(struct inode *inode)
26096 inode->i_pipe = NULL;
26097 }
26098
26099 -static struct vfsmount *pipe_mnt __read_mostly;
26100 +struct vfsmount *pipe_mnt __read_mostly;
26101 static int pipefs_delete_dentry(struct dentry *dentry)
26102 {
26103 /*
26104 diff -urNp linux-2.6.31.1/fs/proc/array.c linux-2.6.31.1/fs/proc/array.c
26105 --- linux-2.6.31.1/fs/proc/array.c 2009-09-24 11:45:25.000000000 -0400
26106 +++ linux-2.6.31.1/fs/proc/array.c 2009-10-01 20:12:44.000000000 -0400
26107 @@ -321,6 +321,21 @@ static inline void task_context_switch_c
26108 p->nivcsw);
26109 }
26110
26111 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
26112 +static inline void task_pax(struct seq_file *m, struct task_struct *p)
26113 +{
26114 + if (p->mm)
26115 + seq_printf(m, "PaX:\t%c%c%c%c%c\n",
26116 + p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
26117 + p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
26118 + p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
26119 + p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
26120 + p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
26121 + else
26122 + seq_printf(m, "PaX:\t-----\n");
26123 +}
26124 +#endif
26125 +
26126 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
26127 struct pid *pid, struct task_struct *task)
26128 {
26129 @@ -340,9 +355,20 @@ int proc_pid_status(struct seq_file *m,
26130 task_show_regs(m, task);
26131 #endif
26132 task_context_switch_counts(m, task);
26133 +
26134 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
26135 + task_pax(m, task);
26136 +#endif
26137 +
26138 return 0;
26139 }
26140
26141 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26142 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
26143 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
26144 + _mm->pax_flags & MF_PAX_SEGMEXEC))
26145 +#endif
26146 +
26147 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
26148 struct pid *pid, struct task_struct *task, int whole)
26149 {
26150 @@ -439,6 +465,19 @@ static int do_task_stat(struct seq_file
26151 gtime = task_gtime(task);
26152 }
26153
26154 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26155 + if (PAX_RAND_FLAGS(mm)) {
26156 + eip = 0;
26157 + esp = 0;
26158 + wchan = 0;
26159 + }
26160 +#endif
26161 +#ifdef CONFIG_GRKERNSEC_HIDESYM
26162 + wchan = 0;
26163 + eip =0;
26164 + esp =0;
26165 +#endif
26166 +
26167 /* scale priority and nice values from timeslices to -20..20 */
26168 /* to make it look like a "normal" Unix priority/nice value */
26169 priority = task_prio(task);
26170 @@ -479,9 +518,15 @@ static int do_task_stat(struct seq_file
26171 vsize,
26172 mm ? get_mm_rss(mm) : 0,
26173 rsslim,
26174 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26175 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
26176 + PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
26177 + PAX_RAND_FLAGS(mm) ? 0 : ((permitted && mm) ? mm->start_stack : 0),
26178 +#else
26179 mm ? mm->start_code : 0,
26180 mm ? mm->end_code : 0,
26181 (permitted && mm) ? mm->start_stack : 0,
26182 +#endif
26183 esp,
26184 eip,
26185 /* The signal information here is obsolete.
26186 @@ -534,3 +579,10 @@ int proc_pid_statm(struct seq_file *m, s
26187
26188 return 0;
26189 }
26190 +
26191 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
26192 +int proc_pid_ipaddr(struct task_struct *task, char *buffer)
26193 +{
26194 + return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
26195 +}
26196 +#endif
26197 diff -urNp linux-2.6.31.1/fs/proc/base.c linux-2.6.31.1/fs/proc/base.c
26198 --- linux-2.6.31.1/fs/proc/base.c 2009-09-24 11:45:25.000000000 -0400
26199 +++ linux-2.6.31.1/fs/proc/base.c 2009-10-01 20:12:44.000000000 -0400
26200 @@ -213,6 +213,9 @@ static int check_mem_permission(struct t
26201 if (task == current)
26202 return 0;
26203
26204 + if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
26205 + return -EPERM;
26206 +
26207 /*
26208 * If current is actively ptrace'ing, and would also be
26209 * permitted to freshly attach with ptrace now, permit it.
26210 @@ -260,6 +263,9 @@ static int proc_pid_cmdline(struct task_
26211 if (!mm->arg_end)
26212 goto out_mm; /* Shh! No looking before we're done */
26213
26214 + if (gr_acl_handle_procpidmem(task))
26215 + goto out_mm;
26216 +
26217 len = mm->arg_end - mm->arg_start;
26218
26219 if (len > PAGE_SIZE)
26220 @@ -287,12 +293,26 @@ out:
26221 return res;
26222 }
26223
26224 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26225 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
26226 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
26227 + _mm->pax_flags & MF_PAX_SEGMEXEC))
26228 +#endif
26229 +
26230 static int proc_pid_auxv(struct task_struct *task, char *buffer)
26231 {
26232 int res = 0;
26233 struct mm_struct *mm = get_task_mm(task);
26234 if (mm) {
26235 unsigned int nwords = 0;
26236 +
26237 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26238 + if (PAX_RAND_FLAGS(mm)) {
26239 + mmput(mm);
26240 + return res;
26241 + }
26242 +#endif
26243 +
26244 do {
26245 nwords += 2;
26246 } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
26247 @@ -328,7 +348,7 @@ static int proc_pid_wchan(struct task_st
26248 }
26249 #endif /* CONFIG_KALLSYMS */
26250
26251 -#ifdef CONFIG_STACKTRACE
26252 +#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM)
26253
26254 #define MAX_STACK_TRACE_DEPTH 64
26255
26256 @@ -521,7 +541,7 @@ static int proc_pid_limits(struct task_s
26257 return count;
26258 }
26259
26260 -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
26261 +#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
26262 static int proc_pid_syscall(struct task_struct *task, char *buffer)
26263 {
26264 long nr;
26265 @@ -935,6 +955,9 @@ static ssize_t environ_read(struct file
26266 if (!task)
26267 goto out_no_task;
26268
26269 + if (gr_acl_handle_procpidmem(task))
26270 + goto out;
26271 +
26272 if (!ptrace_may_access(task, PTRACE_MODE_READ))
26273 goto out;
26274
26275 @@ -1438,7 +1461,11 @@ static struct inode *proc_pid_make_inode
26276 rcu_read_lock();
26277 cred = __task_cred(task);
26278 inode->i_uid = cred->euid;
26279 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
26280 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
26281 +#else
26282 inode->i_gid = cred->egid;
26283 +#endif
26284 rcu_read_unlock();
26285 }
26286 security_task_to_inode(task, inode);
26287 @@ -1456,6 +1483,9 @@ static int pid_getattr(struct vfsmount *
26288 struct inode *inode = dentry->d_inode;
26289 struct task_struct *task;
26290 const struct cred *cred;
26291 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26292 + const struct cred *tmpcred = current_cred();
26293 +#endif
26294
26295 generic_fillattr(inode, stat);
26296
26297 @@ -1463,12 +1493,34 @@ static int pid_getattr(struct vfsmount *
26298 stat->uid = 0;
26299 stat->gid = 0;
26300 task = pid_task(proc_pid(inode), PIDTYPE_PID);
26301 +
26302 + if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
26303 + rcu_read_unlock();
26304 + return -ENOENT;
26305 + }
26306 +
26307 if (task) {
26308 + cred = __task_cred(task);
26309 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26310 + if (!tmpcred->uid || (tmpcred->uid == cred->uid)
26311 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
26312 + || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
26313 +#endif
26314 + )
26315 +#endif
26316 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
26317 +#ifdef CONFIG_GRKERNSEC_PROC_USER
26318 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
26319 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26320 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
26321 +#endif
26322 task_dumpable(task)) {
26323 - cred = __task_cred(task);
26324 stat->uid = cred->euid;
26325 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
26326 + stat->gid = CONFIG_GRKERNSEC_PROC_GID;
26327 +#else
26328 stat->gid = cred->egid;
26329 +#endif
26330 }
26331 }
26332 rcu_read_unlock();
26333 @@ -1500,11 +1552,20 @@ static int pid_revalidate(struct dentry
26334
26335 if (task) {
26336 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
26337 +#ifdef CONFIG_GRKERNSEC_PROC_USER
26338 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
26339 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26340 + (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
26341 +#endif
26342 task_dumpable(task)) {
26343 rcu_read_lock();
26344 cred = __task_cred(task);
26345 inode->i_uid = cred->euid;
26346 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
26347 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
26348 +#else
26349 inode->i_gid = cred->egid;
26350 +#endif
26351 rcu_read_unlock();
26352 } else {
26353 inode->i_uid = 0;
26354 @@ -1625,7 +1686,8 @@ static int proc_fd_info(struct inode *in
26355 int fd = proc_fd(inode);
26356
26357 if (task) {
26358 - files = get_files_struct(task);
26359 + if (!gr_acl_handle_procpidmem(task))
26360 + files = get_files_struct(task);
26361 put_task_struct(task);
26362 }
26363 if (files) {
26364 @@ -1877,12 +1939,22 @@ static const struct file_operations proc
26365 static int proc_fd_permission(struct inode *inode, int mask)
26366 {
26367 int rv;
26368 + struct task_struct *task;
26369
26370 rv = generic_permission(inode, mask, NULL);
26371 - if (rv == 0)
26372 - return 0;
26373 +
26374 if (task_pid(current) == proc_pid(inode))
26375 rv = 0;
26376 +
26377 + task = get_proc_task(inode);
26378 + if (task == NULL)
26379 + return rv;
26380 +
26381 + if (gr_acl_handle_procpidmem(task))
26382 + rv = -EACCES;
26383 +
26384 + put_task_struct(task);
26385 +
26386 return rv;
26387 }
26388
26389 @@ -1991,6 +2063,9 @@ static struct dentry *proc_pident_lookup
26390 if (!task)
26391 goto out_no_task;
26392
26393 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
26394 + goto out;
26395 +
26396 /*
26397 * Yes, it does not scale. And it should not. Don't add
26398 * new entries into /proc/<tgid>/ without very good reasons.
26399 @@ -2035,6 +2110,9 @@ static int proc_pident_readdir(struct fi
26400 if (!task)
26401 goto out_no_task;
26402
26403 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
26404 + goto out;
26405 +
26406 ret = 0;
26407 i = filp->f_pos;
26408 switch (i) {
26409 @@ -2401,6 +2479,9 @@ static struct dentry *proc_base_lookup(s
26410 if (p > last)
26411 goto out;
26412
26413 + if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
26414 + goto out;
26415 +
26416 error = proc_base_instantiate(dir, dentry, task, p);
26417
26418 out:
26419 @@ -2487,7 +2568,7 @@ static const struct pid_entry tgid_base_
26420 #ifdef CONFIG_SCHED_DEBUG
26421 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
26422 #endif
26423 -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
26424 +#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
26425 INF("syscall", S_IRUSR, proc_pid_syscall),
26426 #endif
26427 INF("cmdline", S_IRUGO, proc_pid_cmdline),
26428 @@ -2515,7 +2596,7 @@ static const struct pid_entry tgid_base_
26429 #ifdef CONFIG_KALLSYMS
26430 INF("wchan", S_IRUGO, proc_pid_wchan),
26431 #endif
26432 -#ifdef CONFIG_STACKTRACE
26433 +#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM)
26434 ONE("stack", S_IRUSR, proc_pid_stack),
26435 #endif
26436 #ifdef CONFIG_SCHEDSTATS
26437 @@ -2545,6 +2626,9 @@ static const struct pid_entry tgid_base_
26438 #ifdef CONFIG_TASK_IO_ACCOUNTING
26439 INF("io", S_IRUGO, proc_tgid_io_accounting),
26440 #endif
26441 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
26442 + INF("ipaddr", S_IRUSR, proc_pid_ipaddr),
26443 +#endif
26444 };
26445
26446 static int proc_tgid_base_readdir(struct file * filp,
26447 @@ -2674,7 +2758,14 @@ static struct dentry *proc_pid_instantia
26448 if (!inode)
26449 goto out;
26450
26451 +#ifdef CONFIG_GRKERNSEC_PROC_USER
26452 + inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
26453 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26454 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
26455 + inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
26456 +#else
26457 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
26458 +#endif
26459 inode->i_op = &proc_tgid_base_inode_operations;
26460 inode->i_fop = &proc_tgid_base_operations;
26461 inode->i_flags|=S_IMMUTABLE;
26462 @@ -2716,7 +2807,11 @@ struct dentry *proc_pid_lookup(struct in
26463 if (!task)
26464 goto out;
26465
26466 + if (gr_check_hidden_task(task))
26467 + goto out_put_task;
26468 +
26469 result = proc_pid_instantiate(dir, dentry, task, NULL);
26470 +out_put_task:
26471 put_task_struct(task);
26472 out:
26473 return result;
26474 @@ -2781,6 +2876,10 @@ int proc_pid_readdir(struct file * filp,
26475 {
26476 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
26477 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
26478 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26479 + const struct cred *tmpcred = current_cred();
26480 + const struct cred *itercred;
26481 +#endif
26482 struct tgid_iter iter;
26483 struct pid_namespace *ns;
26484
26485 @@ -2799,6 +2898,20 @@ int proc_pid_readdir(struct file * filp,
26486 for (iter = next_tgid(ns, iter);
26487 iter.task;
26488 iter.tgid += 1, iter = next_tgid(ns, iter)) {
26489 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26490 + itercred = __task_cred(iter.task);
26491 +#endif
26492 + if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
26493 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26494 + || (tmpcred->uid && (itercred->uid != tmpcred->uid)
26495 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
26496 + && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
26497 +#endif
26498 + )
26499 +#endif
26500 + )
26501 + continue;
26502 +
26503 filp->f_pos = iter.tgid + TGID_OFFSET;
26504 if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
26505 put_task_struct(iter.task);
26506 @@ -2826,7 +2939,7 @@ static const struct pid_entry tid_base_s
26507 #ifdef CONFIG_SCHED_DEBUG
26508 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
26509 #endif
26510 -#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
26511 +#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
26512 INF("syscall", S_IRUSR, proc_pid_syscall),
26513 #endif
26514 INF("cmdline", S_IRUGO, proc_pid_cmdline),
26515 @@ -2853,7 +2966,7 @@ static const struct pid_entry tid_base_s
26516 #ifdef CONFIG_KALLSYMS
26517 INF("wchan", S_IRUGO, proc_pid_wchan),
26518 #endif
26519 -#ifdef CONFIG_STACKTRACE
26520 +#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM)
26521 ONE("stack", S_IRUSR, proc_pid_stack),
26522 #endif
26523 #ifdef CONFIG_SCHEDSTATS
26524 diff -urNp linux-2.6.31.1/fs/proc/cmdline.c linux-2.6.31.1/fs/proc/cmdline.c
26525 --- linux-2.6.31.1/fs/proc/cmdline.c 2009-09-24 11:45:25.000000000 -0400
26526 +++ linux-2.6.31.1/fs/proc/cmdline.c 2009-10-01 20:12:44.000000000 -0400
26527 @@ -23,7 +23,11 @@ static const struct file_operations cmdl
26528
26529 static int __init proc_cmdline_init(void)
26530 {
26531 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
26532 + proc_create_grsec("cmdline", 0, NULL, &cmdline_proc_fops);
26533 +#else
26534 proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
26535 +#endif
26536 return 0;
26537 }
26538 module_init(proc_cmdline_init);
26539 diff -urNp linux-2.6.31.1/fs/proc/devices.c linux-2.6.31.1/fs/proc/devices.c
26540 --- linux-2.6.31.1/fs/proc/devices.c 2009-09-24 11:45:25.000000000 -0400
26541 +++ linux-2.6.31.1/fs/proc/devices.c 2009-10-01 20:12:44.000000000 -0400
26542 @@ -64,7 +64,11 @@ static const struct file_operations proc
26543
26544 static int __init proc_devices_init(void)
26545 {
26546 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
26547 + proc_create_grsec("devices", 0, NULL, &proc_devinfo_operations);
26548 +#else
26549 proc_create("devices", 0, NULL, &proc_devinfo_operations);
26550 +#endif
26551 return 0;
26552 }
26553 module_init(proc_devices_init);
26554 diff -urNp linux-2.6.31.1/fs/proc/inode.c linux-2.6.31.1/fs/proc/inode.c
26555 --- linux-2.6.31.1/fs/proc/inode.c 2009-09-24 11:45:25.000000000 -0400
26556 +++ linux-2.6.31.1/fs/proc/inode.c 2009-10-01 20:12:44.000000000 -0400
26557 @@ -457,7 +457,11 @@ struct inode *proc_get_inode(struct supe
26558 if (de->mode) {
26559 inode->i_mode = de->mode;
26560 inode->i_uid = de->uid;
26561 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
26562 + inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
26563 +#else
26564 inode->i_gid = de->gid;
26565 +#endif
26566 }
26567 if (de->size)
26568 inode->i_size = de->size;
26569 diff -urNp linux-2.6.31.1/fs/proc/internal.h linux-2.6.31.1/fs/proc/internal.h
26570 --- linux-2.6.31.1/fs/proc/internal.h 2009-09-24 11:45:25.000000000 -0400
26571 +++ linux-2.6.31.1/fs/proc/internal.h 2009-10-01 20:12:44.000000000 -0400
26572 @@ -51,6 +51,9 @@ extern int proc_pid_status(struct seq_fi
26573 struct pid *pid, struct task_struct *task);
26574 extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
26575 struct pid *pid, struct task_struct *task);
26576 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
26577 +extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
26578 +#endif
26579 extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
26580
26581 extern const struct file_operations proc_maps_operations;
26582 diff -urNp linux-2.6.31.1/fs/proc/Kconfig linux-2.6.31.1/fs/proc/Kconfig
26583 --- linux-2.6.31.1/fs/proc/Kconfig 2009-09-24 11:45:25.000000000 -0400
26584 +++ linux-2.6.31.1/fs/proc/Kconfig 2009-10-01 20:12:44.000000000 -0400
26585 @@ -30,12 +30,12 @@ config PROC_FS
26586
26587 config PROC_KCORE
26588 bool "/proc/kcore support" if !ARM
26589 - depends on PROC_FS && MMU
26590 + depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
26591
26592 config PROC_VMCORE
26593 bool "/proc/vmcore support (EXPERIMENTAL)"
26594 - depends on PROC_FS && CRASH_DUMP
26595 - default y
26596 + depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
26597 + default n
26598 help
26599 Exports the dump image of crashed kernel in ELF format.
26600
26601 @@ -59,8 +59,8 @@ config PROC_SYSCTL
26602 limited in memory.
26603
26604 config PROC_PAGE_MONITOR
26605 - default y
26606 - depends on PROC_FS && MMU
26607 + default n
26608 + depends on PROC_FS && MMU && !GRKERNSEC
26609 bool "Enable /proc page monitoring" if EMBEDDED
26610 help
26611 Various /proc files exist to monitor process memory utilization:
26612 diff -urNp linux-2.6.31.1/fs/proc/kcore.c linux-2.6.31.1/fs/proc/kcore.c
26613 --- linux-2.6.31.1/fs/proc/kcore.c 2009-09-24 11:45:25.000000000 -0400
26614 +++ linux-2.6.31.1/fs/proc/kcore.c 2009-10-01 20:12:44.000000000 -0400
26615 @@ -404,10 +404,12 @@ read_kcore(struct file *file, char __use
26616
26617 static int __init proc_kcore_init(void)
26618 {
26619 +#if !defined(CONFIG_GRKERNSEC_PROC_ADD) && !defined(CONFIG_GRKERNSEC_HIDESYM)
26620 proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
26621 if (proc_root_kcore)
26622 proc_root_kcore->size =
26623 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
26624 +#endif
26625 return 0;
26626 }
26627 module_init(proc_kcore_init);
26628 diff -urNp linux-2.6.31.1/fs/proc/nommu.c linux-2.6.31.1/fs/proc/nommu.c
26629 --- linux-2.6.31.1/fs/proc/nommu.c 2009-09-24 11:45:25.000000000 -0400
26630 +++ linux-2.6.31.1/fs/proc/nommu.c 2009-10-01 20:12:44.000000000 -0400
26631 @@ -67,7 +67,7 @@ static int nommu_region_show(struct seq_
26632 if (len < 1)
26633 len = 1;
26634 seq_printf(m, "%*c", len, ' ');
26635 - seq_path(m, &file->f_path, "");
26636 + seq_path(m, &file->f_path, "\n\\");
26637 }
26638
26639 seq_putc(m, '\n');
26640 @@ -109,7 +109,7 @@ static void *nommu_region_list_next(stru
26641 return rb_next((struct rb_node *) v);
26642 }
26643
26644 -static struct seq_operations proc_nommu_region_list_seqop = {
26645 +static const struct seq_operations proc_nommu_region_list_seqop = {
26646 .start = nommu_region_list_start,
26647 .next = nommu_region_list_next,
26648 .stop = nommu_region_list_stop,
26649 diff -urNp linux-2.6.31.1/fs/proc/proc_net.c linux-2.6.31.1/fs/proc/proc_net.c
26650 --- linux-2.6.31.1/fs/proc/proc_net.c 2009-09-24 11:45:25.000000000 -0400
26651 +++ linux-2.6.31.1/fs/proc/proc_net.c 2009-10-01 20:12:44.000000000 -0400
26652 @@ -104,6 +104,17 @@ static struct net *get_proc_task_net(str
26653 struct task_struct *task;
26654 struct nsproxy *ns;
26655 struct net *net = NULL;
26656 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26657 + const struct cred *cred = current_cred();
26658 +#endif
26659 +
26660 +#ifdef CONFIG_GRKERNSEC_PROC_USER
26661 + if (cred->fsuid)
26662 + return net;
26663 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26664 + if (cred->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
26665 + return net;
26666 +#endif
26667
26668 rcu_read_lock();
26669 task = pid_task(proc_pid(dir), PIDTYPE_PID);
26670 diff -urNp linux-2.6.31.1/fs/proc/proc_sysctl.c linux-2.6.31.1/fs/proc/proc_sysctl.c
26671 --- linux-2.6.31.1/fs/proc/proc_sysctl.c 2009-09-24 11:45:25.000000000 -0400
26672 +++ linux-2.6.31.1/fs/proc/proc_sysctl.c 2009-10-01 20:12:44.000000000 -0400
26673 @@ -7,6 +7,8 @@
26674 #include <linux/security.h>
26675 #include "internal.h"
26676
26677 +extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
26678 +
26679 static const struct dentry_operations proc_sys_dentry_operations;
26680 static const struct file_operations proc_sys_file_operations;
26681 static const struct inode_operations proc_sys_inode_operations;
26682 @@ -109,6 +111,9 @@ static struct dentry *proc_sys_lookup(st
26683 if (!p)
26684 goto out;
26685
26686 + if (gr_handle_sysctl(p, MAY_EXEC))
26687 + goto out;
26688 +
26689 err = ERR_PTR(-ENOMEM);
26690 inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
26691 if (h)
26692 @@ -228,6 +233,9 @@ static int scan(struct ctl_table_header
26693 if (*pos < file->f_pos)
26694 continue;
26695
26696 + if (gr_handle_sysctl(table, 0))
26697 + continue;
26698 +
26699 res = proc_sys_fill_cache(file, dirent, filldir, head, table);
26700 if (res)
26701 return res;
26702 @@ -344,6 +352,9 @@ static int proc_sys_getattr(struct vfsmo
26703 if (IS_ERR(head))
26704 return PTR_ERR(head);
26705
26706 + if (table && gr_handle_sysctl(table, MAY_EXEC))
26707 + return -ENOENT;
26708 +
26709 generic_fillattr(inode, stat);
26710 if (table)
26711 stat->mode = (stat->mode & S_IFMT) | table->mode;
26712 diff -urNp linux-2.6.31.1/fs/proc/root.c linux-2.6.31.1/fs/proc/root.c
26713 --- linux-2.6.31.1/fs/proc/root.c 2009-09-24 11:45:25.000000000 -0400
26714 +++ linux-2.6.31.1/fs/proc/root.c 2009-10-01 20:12:44.000000000 -0400
26715 @@ -134,7 +134,15 @@ void __init proc_root_init(void)
26716 #ifdef CONFIG_PROC_DEVICETREE
26717 proc_device_tree_init();
26718 #endif
26719 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
26720 +#ifdef CONFIG_GRKERNSEC_PROC_USER
26721 + proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
26722 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
26723 + proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
26724 +#endif
26725 +#else
26726 proc_mkdir("bus", NULL);
26727 +#endif
26728 proc_sys_init();
26729 }
26730
26731 diff -urNp linux-2.6.31.1/fs/proc/task_mmu.c linux-2.6.31.1/fs/proc/task_mmu.c
26732 --- linux-2.6.31.1/fs/proc/task_mmu.c 2009-09-24 11:45:25.000000000 -0400
26733 +++ linux-2.6.31.1/fs/proc/task_mmu.c 2009-10-01 20:12:44.000000000 -0400
26734 @@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
26735 "VmStk:\t%8lu kB\n"
26736 "VmExe:\t%8lu kB\n"
26737 "VmLib:\t%8lu kB\n"
26738 - "VmPTE:\t%8lu kB\n",
26739 - hiwater_vm << (PAGE_SHIFT-10),
26740 + "VmPTE:\t%8lu kB\n"
26741 +
26742 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
26743 + "CsBase:\t%8lx\nCsLim:\t%8lx\n"
26744 +#endif
26745 +
26746 + ,hiwater_vm << (PAGE_SHIFT-10),
26747 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
26748 mm->locked_vm << (PAGE_SHIFT-10),
26749 hiwater_rss << (PAGE_SHIFT-10),
26750 total_rss << (PAGE_SHIFT-10),
26751 data << (PAGE_SHIFT-10),
26752 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
26753 - (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
26754 + (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
26755 +
26756 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
26757 + , mm->context.user_cs_base, mm->context.user_cs_limit
26758 +#endif
26759 +
26760 + );
26761 }
26762
26763 unsigned long task_vsize(struct mm_struct *mm)
26764 @@ -199,6 +210,12 @@ static int do_maps_open(struct inode *in
26765 return ret;
26766 }
26767
26768 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26769 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
26770 + (_mm->pax_flags & MF_PAX_RANDMMAP || \
26771 + _mm->pax_flags & MF_PAX_SEGMEXEC))
26772 +#endif
26773 +
26774 static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
26775 {
26776 struct mm_struct *mm = vma->vm_mm;
26777 @@ -217,13 +234,22 @@ static void show_map_vma(struct seq_file
26778 }
26779
26780 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
26781 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26782 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
26783 + PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
26784 +#else
26785 vma->vm_start,
26786 vma->vm_end,
26787 +#endif
26788 flags & VM_READ ? 'r' : '-',
26789 flags & VM_WRITE ? 'w' : '-',
26790 flags & VM_EXEC ? 'x' : '-',
26791 flags & VM_MAYSHARE ? 's' : 'p',
26792 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26793 + PAX_RAND_FLAGS(mm) ? 0UL : pgoff,
26794 +#else
26795 pgoff,
26796 +#endif
26797 MAJOR(dev), MINOR(dev), ino, &len);
26798
26799 /*
26800 @@ -232,16 +258,16 @@ static void show_map_vma(struct seq_file
26801 */
26802 if (file) {
26803 pad_len_spaces(m, len);
26804 - seq_path(m, &file->f_path, "\n");
26805 + seq_path(m, &file->f_path, "\n\\");
26806 } else {
26807 const char *name = arch_vma_name(vma);
26808 if (!name) {
26809 if (mm) {
26810 - if (vma->vm_start <= mm->start_brk &&
26811 - vma->vm_end >= mm->brk) {
26812 + if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
26813 name = "[heap]";
26814 - } else if (vma->vm_start <= mm->start_stack &&
26815 - vma->vm_end >= mm->start_stack) {
26816 + } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
26817 + (vma->vm_start <= mm->start_stack &&
26818 + vma->vm_end >= mm->start_stack)) {
26819 name = "[stack]";
26820 }
26821 } else {
26822 @@ -384,9 +410,16 @@ static int show_smap(struct seq_file *m,
26823 };
26824
26825 memset(&mss, 0, sizeof mss);
26826 - mss.vma = vma;
26827 - if (vma->vm_mm && !is_vm_hugetlb_page(vma))
26828 - walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
26829 +
26830 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26831 + if (!PAX_RAND_FLAGS(vma->vm_mm)) {
26832 +#endif
26833 + mss.vma = vma;
26834 + if (vma->vm_mm && !is_vm_hugetlb_page(vma))
26835 + walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
26836 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26837 + }
26838 +#endif
26839
26840 show_map_vma(m, vma);
26841
26842 @@ -402,7 +435,11 @@ static int show_smap(struct seq_file *m,
26843 "Swap: %8lu kB\n"
26844 "KernelPageSize: %8lu kB\n"
26845 "MMUPageSize: %8lu kB\n",
26846 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
26847 + PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
26848 +#else
26849 (vma->vm_end - vma->vm_start) >> 10,
26850 +#endif
26851 mss.resident >> 10,
26852 (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
26853 mss.shared_clean >> 10,
26854 diff -urNp linux-2.6.31.1/fs/proc/task_nommu.c linux-2.6.31.1/fs/proc/task_nommu.c
26855 --- linux-2.6.31.1/fs/proc/task_nommu.c 2009-09-24 11:45:25.000000000 -0400
26856 +++ linux-2.6.31.1/fs/proc/task_nommu.c 2009-10-01 20:12:44.000000000 -0400
26857 @@ -50,7 +50,7 @@ void task_mem(struct seq_file *m, struct
26858 else
26859 bytes += kobjsize(mm);
26860
26861 - if (current->fs && current->fs->users > 1)
26862 + if (current->fs && atomic_read(&current->fs->users) > 1)
26863 sbytes += kobjsize(current->fs);
26864 else
26865 bytes += kobjsize(current->fs);
26866 @@ -154,7 +154,7 @@ static int nommu_vma_show(struct seq_fil
26867 if (len < 1)
26868 len = 1;
26869 seq_printf(m, "%*c", len, ' ');
26870 - seq_path(m, &file->f_path, "");
26871 + seq_path(m, &file->f_path, "\n\\");
26872 }
26873
26874 seq_putc(m, '\n');
26875 diff -urNp linux-2.6.31.1/fs/readdir.c linux-2.6.31.1/fs/readdir.c
26876 --- linux-2.6.31.1/fs/readdir.c 2009-09-24 11:45:25.000000000 -0400
26877 +++ linux-2.6.31.1/fs/readdir.c 2009-10-01 20:12:44.000000000 -0400
26878 @@ -16,6 +16,7 @@
26879 #include <linux/security.h>
26880 #include <linux/syscalls.h>
26881 #include <linux/unistd.h>
26882 +#include <linux/namei.h>
26883
26884 #include <asm/uaccess.h>
26885
26886 @@ -67,6 +68,7 @@ struct old_linux_dirent {
26887
26888 struct readdir_callback {
26889 struct old_linux_dirent __user * dirent;
26890 + struct file * file;
26891 int result;
26892 };
26893
26894 @@ -84,6 +86,10 @@ static int fillonedir(void * __buf, cons
26895 buf->result = -EOVERFLOW;
26896 return -EOVERFLOW;
26897 }
26898 +
26899 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
26900 + return 0;
26901 +
26902 buf->result++;
26903 dirent = buf->dirent;
26904 if (!access_ok(VERIFY_WRITE, dirent,
26905 @@ -116,6 +122,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned in
26906
26907 buf.result = 0;
26908 buf.dirent = dirent;
26909 + buf.file = file;
26910
26911 error = vfs_readdir(file, fillonedir, &buf);
26912 if (buf.result)
26913 @@ -142,6 +149,7 @@ struct linux_dirent {
26914 struct getdents_callback {
26915 struct linux_dirent __user * current_dir;
26916 struct linux_dirent __user * previous;
26917 + struct file * file;
26918 int count;
26919 int error;
26920 };
26921 @@ -162,6 +170,10 @@ static int filldir(void * __buf, const c
26922 buf->error = -EOVERFLOW;
26923 return -EOVERFLOW;
26924 }
26925 +
26926 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
26927 + return 0;
26928 +
26929 dirent = buf->previous;
26930 if (dirent) {
26931 if (__put_user(offset, &dirent->d_off))
26932 @@ -209,6 +221,7 @@ SYSCALL_DEFINE3(getdents, unsigned int,
26933 buf.previous = NULL;
26934 buf.count = count;
26935 buf.error = 0;
26936 + buf.file = file;
26937
26938 error = vfs_readdir(file, filldir, &buf);
26939 if (error >= 0)
26940 @@ -228,6 +241,7 @@ out:
26941 struct getdents_callback64 {
26942 struct linux_dirent64 __user * current_dir;
26943 struct linux_dirent64 __user * previous;
26944 + struct file *file;
26945 int count;
26946 int error;
26947 };
26948 @@ -242,6 +256,10 @@ static int filldir64(void * __buf, const
26949 buf->error = -EINVAL; /* only used if we fail.. */
26950 if (reclen > buf->count)
26951 return -EINVAL;
26952 +
26953 + if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
26954 + return 0;
26955 +
26956 dirent = buf->previous;
26957 if (dirent) {
26958 if (__put_user(offset, &dirent->d_off))
26959 @@ -289,6 +307,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int
26960
26961 buf.current_dir = dirent;
26962 buf.previous = NULL;
26963 + buf.file = file;
26964 buf.count = count;
26965 buf.error = 0;
26966
26967 diff -urNp linux-2.6.31.1/fs/reiserfs/do_balan.c linux-2.6.31.1/fs/reiserfs/do_balan.c
26968 --- linux-2.6.31.1/fs/reiserfs/do_balan.c 2009-09-24 11:45:25.000000000 -0400
26969 +++ linux-2.6.31.1/fs/reiserfs/do_balan.c 2009-10-01 20:12:44.000000000 -0400
26970 @@ -2058,7 +2058,7 @@ void do_balance(struct tree_balance *tb,
26971 return;
26972 }
26973
26974 - atomic_inc(&(fs_generation(tb->tb_sb)));
26975 + atomic_inc_unchecked(&(fs_generation(tb->tb_sb)));
26976 do_balance_starts(tb);
26977
26978 /* balance leaf returns 0 except if combining L R and S into
26979 diff -urNp linux-2.6.31.1/fs/reiserfs/procfs.c linux-2.6.31.1/fs/reiserfs/procfs.c
26980 --- linux-2.6.31.1/fs/reiserfs/procfs.c 2009-09-24 11:45:25.000000000 -0400
26981 +++ linux-2.6.31.1/fs/reiserfs/procfs.c 2009-10-01 20:12:44.000000000 -0400
26982 @@ -123,7 +123,7 @@ static int show_super(struct seq_file *m
26983 "SMALL_TAILS " : "NO_TAILS ",
26984 replay_only(sb) ? "REPLAY_ONLY " : "",
26985 convert_reiserfs(sb) ? "CONV " : "",
26986 - atomic_read(&r->s_generation_counter),
26987 + atomic_read_unchecked(&r->s_generation_counter),
26988 SF(s_disk_reads), SF(s_disk_writes), SF(s_fix_nodes),
26989 SF(s_do_balance), SF(s_unneeded_left_neighbor),
26990 SF(s_good_search_by_key_reada), SF(s_bmaps),
26991 diff -urNp linux-2.6.31.1/fs/romfs/super.c linux-2.6.31.1/fs/romfs/super.c
26992 --- linux-2.6.31.1/fs/romfs/super.c 2009-09-24 11:45:25.000000000 -0400
26993 +++ linux-2.6.31.1/fs/romfs/super.c 2009-10-01 20:12:44.000000000 -0400
26994 @@ -284,7 +284,7 @@ static const struct file_operations romf
26995 .readdir = romfs_readdir,
26996 };
26997
26998 -static struct inode_operations romfs_dir_inode_operations = {
26999 +static const struct inode_operations romfs_dir_inode_operations = {
27000 .lookup = romfs_lookup,
27001 };
27002
27003 diff -urNp linux-2.6.31.1/fs/select.c linux-2.6.31.1/fs/select.c
27004 --- linux-2.6.31.1/fs/select.c 2009-09-24 11:45:25.000000000 -0400
27005 +++ linux-2.6.31.1/fs/select.c 2009-10-01 20:12:44.000000000 -0400
27006 @@ -19,6 +19,7 @@
27007 #include <linux/module.h>
27008 #include <linux/slab.h>
27009 #include <linux/poll.h>
27010 +#include <linux/security.h>
27011 #include <linux/personality.h> /* for STICKY_TIMEOUTS */
27012 #include <linux/file.h>
27013 #include <linux/fdtable.h>
27014 @@ -814,6 +815,7 @@ int do_sys_poll(struct pollfd __user *uf
27015 struct poll_list *walk = head;
27016 unsigned long todo = nfds;
27017
27018 + gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
27019 if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
27020 return -EINVAL;
27021
27022 diff -urNp linux-2.6.31.1/fs/seq_file.c linux-2.6.31.1/fs/seq_file.c
27023 --- linux-2.6.31.1/fs/seq_file.c 2009-09-24 11:45:25.000000000 -0400
27024 +++ linux-2.6.31.1/fs/seq_file.c 2009-10-01 20:12:44.000000000 -0400
27025 @@ -76,7 +76,8 @@ static int traverse(struct seq_file *m,
27026 return 0;
27027 }
27028 if (!m->buf) {
27029 - m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
27030 + m->size = PAGE_SIZE;
27031 + m->buf = kmalloc(m->size, GFP_KERNEL);
27032 if (!m->buf)
27033 return -ENOMEM;
27034 }
27035 @@ -116,7 +117,8 @@ static int traverse(struct seq_file *m,
27036 Eoverflow:
27037 m->op->stop(m, p);
27038 kfree(m->buf);
27039 - m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
27040 + m->size <<= 1;
27041 + m->buf = kmalloc(m->size, GFP_KERNEL);
27042 return !m->buf ? -ENOMEM : -EAGAIN;
27043 }
27044
27045 @@ -169,7 +171,8 @@ ssize_t seq_read(struct file *file, char
27046 m->version = file->f_version;
27047 /* grab buffer if we didn't have one */
27048 if (!m->buf) {
27049 - m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
27050 + m->size = PAGE_SIZE;
27051 + m->buf = kmalloc(m->size, GFP_KERNEL);
27052 if (!m->buf)
27053 goto Enomem;
27054 }
27055 @@ -210,7 +213,8 @@ ssize_t seq_read(struct file *file, char
27056 goto Fill;
27057 m->op->stop(m, p);
27058 kfree(m->buf);
27059 - m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
27060 + m->size <<= 1;
27061 + m->buf = kmalloc(m->size, GFP_KERNEL);
27062 if (!m->buf)
27063 goto Enomem;
27064 m->count = 0;
27065 diff -urNp linux-2.6.31.1/fs/smbfs/symlink.c linux-2.6.31.1/fs/smbfs/symlink.c
27066 --- linux-2.6.31.1/fs/smbfs/symlink.c 2009-09-24 11:45:25.000000000 -0400
27067 +++ linux-2.6.31.1/fs/smbfs/symlink.c 2009-10-01 20:12:44.000000000 -0400
27068 @@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
27069
27070 static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
27071 {
27072 - char *s = nd_get_link(nd);
27073 + const char *s = nd_get_link(nd);
27074 if (!IS_ERR(s))
27075 __putname(s);
27076 }
27077 diff -urNp linux-2.6.31.1/fs/squashfs/super.c linux-2.6.31.1/fs/squashfs/super.c
27078 --- linux-2.6.31.1/fs/squashfs/super.c 2009-09-24 11:45:25.000000000 -0400
27079 +++ linux-2.6.31.1/fs/squashfs/super.c 2009-10-01 20:12:44.000000000 -0400
27080 @@ -44,7 +44,7 @@
27081 #include "squashfs.h"
27082
27083 static struct file_system_type squashfs_fs_type;
27084 -static struct super_operations squashfs_super_ops;
27085 +static const struct super_operations squashfs_super_ops;
27086
27087 static int supported_squashfs_filesystem(short major, short minor, short comp)
27088 {
27089 @@ -444,7 +444,7 @@ static struct file_system_type squashfs_
27090 .fs_flags = FS_REQUIRES_DEV
27091 };
27092
27093 -static struct super_operations squashfs_super_ops = {
27094 +static const struct super_operations squashfs_super_ops = {
27095 .alloc_inode = squashfs_alloc_inode,
27096 .destroy_inode = squashfs_destroy_inode,
27097 .statfs = squashfs_statfs,
27098 diff -urNp linux-2.6.31.1/fs/sysfs/bin.c linux-2.6.31.1/fs/sysfs/bin.c
27099 --- linux-2.6.31.1/fs/sysfs/bin.c 2009-09-24 11:45:25.000000000 -0400
27100 +++ linux-2.6.31.1/fs/sysfs/bin.c 2009-10-01 20:12:44.000000000 -0400
27101 @@ -40,7 +40,7 @@ struct bin_buffer {
27102 struct mutex mutex;
27103 void *buffer;
27104 int mmapped;
27105 - struct vm_operations_struct *vm_ops;
27106 + const struct vm_operations_struct *vm_ops;
27107 struct file *file;
27108 struct hlist_node list;
27109 };
27110 @@ -331,7 +331,7 @@ static int bin_migrate(struct vm_area_st
27111 }
27112 #endif
27113
27114 -static struct vm_operations_struct bin_vm_ops = {
27115 +static const struct vm_operations_struct bin_vm_ops = {
27116 .open = bin_vma_open,
27117 .close = bin_vma_close,
27118 .fault = bin_fault,
27119 diff -urNp linux-2.6.31.1/fs/sysfs/symlink.c linux-2.6.31.1/fs/sysfs/symlink.c
27120 --- linux-2.6.31.1/fs/sysfs/symlink.c 2009-09-24 11:45:25.000000000 -0400
27121 +++ linux-2.6.31.1/fs/sysfs/symlink.c 2009-10-01 20:12:44.000000000 -0400
27122 @@ -203,7 +203,7 @@ static void *sysfs_follow_link(struct de
27123
27124 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
27125 {
27126 - char *page = nd_get_link(nd);
27127 + const char *page = nd_get_link(nd);
27128 if (!IS_ERR(page))
27129 free_page((unsigned long)page);
27130 }
27131 diff -urNp linux-2.6.31.1/fs/ubifs/file.c linux-2.6.31.1/fs/ubifs/file.c
27132 --- linux-2.6.31.1/fs/ubifs/file.c 2009-09-24 11:45:25.000000000 -0400
27133 +++ linux-2.6.31.1/fs/ubifs/file.c 2009-10-01 20:12:44.000000000 -0400
27134 @@ -1536,7 +1536,7 @@ out_unlock:
27135 return err;
27136 }
27137
27138 -static struct vm_operations_struct ubifs_file_vm_ops = {
27139 +static const struct vm_operations_struct ubifs_file_vm_ops = {
27140 .fault = filemap_fault,
27141 .page_mkwrite = ubifs_vm_page_mkwrite,
27142 };
27143 diff -urNp linux-2.6.31.1/fs/udf/balloc.c linux-2.6.31.1/fs/udf/balloc.c
27144 --- linux-2.6.31.1/fs/udf/balloc.c 2009-09-24 11:45:25.000000000 -0400
27145 +++ linux-2.6.31.1/fs/udf/balloc.c 2009-10-01 20:12:44.000000000 -0400
27146 @@ -172,9 +172,7 @@ static void udf_bitmap_free_blocks(struc
27147
27148 mutex_lock(&sbi->s_alloc_mutex);
27149 partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
27150 - if (bloc->logicalBlockNum < 0 ||
27151 - (bloc->logicalBlockNum + count) >
27152 - partmap->s_partition_len) {
27153 + if ((bloc->logicalBlockNum + count) > partmap->s_partition_len) {
27154 udf_debug("%d < %d || %d + %d > %d\n",
27155 bloc->logicalBlockNum, 0, bloc->logicalBlockNum,
27156 count, partmap->s_partition_len);
27157 @@ -436,9 +434,7 @@ static void udf_table_free_blocks(struct
27158
27159 mutex_lock(&sbi->s_alloc_mutex);
27160 partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
27161 - if (bloc->logicalBlockNum < 0 ||
27162 - (bloc->logicalBlockNum + count) >
27163 - partmap->s_partition_len) {
27164 + if ((bloc->logicalBlockNum + count) > partmap->s_partition_len) {
27165 udf_debug("%d < %d || %d + %d > %d\n",
27166 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
27167 partmap->s_partition_len);
27168 diff -urNp linux-2.6.31.1/fs/utimes.c linux-2.6.31.1/fs/utimes.c
27169 --- linux-2.6.31.1/fs/utimes.c 2009-09-24 11:45:25.000000000 -0400
27170 +++ linux-2.6.31.1/fs/utimes.c 2009-10-01 20:12:44.000000000 -0400
27171 @@ -1,6 +1,7 @@
27172 #include <linux/compiler.h>
27173 #include <linux/file.h>
27174 #include <linux/fs.h>
27175 +#include <linux/security.h>
27176 #include <linux/linkage.h>
27177 #include <linux/mount.h>
27178 #include <linux/namei.h>
27179 @@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
27180 goto mnt_drop_write_and_out;
27181 }
27182 }
27183 +
27184 + if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
27185 + error = -EACCES;
27186 + goto mnt_drop_write_and_out;
27187 + }
27188 +
27189 mutex_lock(&inode->i_mutex);
27190 error = notify_change(path->dentry, &newattrs);
27191 mutex_unlock(&inode->i_mutex);
27192 diff -urNp linux-2.6.31.1/fs/xfs/linux-2.6/xfs_file.c linux-2.6.31.1/fs/xfs/linux-2.6/xfs_file.c
27193 --- linux-2.6.31.1/fs/xfs/linux-2.6/xfs_file.c 2009-09-24 11:45:25.000000000 -0400
27194 +++ linux-2.6.31.1/fs/xfs/linux-2.6/xfs_file.c 2009-10-01 20:12:44.000000000 -0400
27195 @@ -42,7 +42,7 @@
27196
27197 #include <linux/dcache.h>
27198
27199 -static struct vm_operations_struct xfs_file_vm_ops;
27200 +static const struct vm_operations_struct xfs_file_vm_ops;
27201
27202 STATIC ssize_t
27203 xfs_file_aio_read(
27204 @@ -271,7 +271,7 @@ const struct file_operations xfs_dir_fil
27205 .fsync = xfs_file_fsync,
27206 };
27207
27208 -static struct vm_operations_struct xfs_file_vm_ops = {
27209 +static const struct vm_operations_struct xfs_file_vm_ops = {
27210 .fault = filemap_fault,
27211 .page_mkwrite = xfs_vm_page_mkwrite,
27212 };
27213 diff -urNp linux-2.6.31.1/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.31.1/fs/xfs/linux-2.6/xfs_iops.c
27214 --- linux-2.6.31.1/fs/xfs/linux-2.6/xfs_iops.c 2009-09-24 11:45:25.000000000 -0400
27215 +++ linux-2.6.31.1/fs/xfs/linux-2.6/xfs_iops.c 2009-10-01 20:12:44.000000000 -0400
27216 @@ -478,7 +478,7 @@ xfs_vn_put_link(
27217 struct nameidata *nd,
27218 void *p)
27219 {
27220 - char *s = nd_get_link(nd);
27221 + const char *s = nd_get_link(nd);
27222
27223 if (!IS_ERR(s))
27224 kfree(s);
27225 diff -urNp linux-2.6.31.1/fs/xfs/linux-2.6/xfs_super.c linux-2.6.31.1/fs/xfs/linux-2.6/xfs_super.c
27226 --- linux-2.6.31.1/fs/xfs/linux-2.6/xfs_super.c 2009-09-24 11:45:25.000000000 -0400
27227 +++ linux-2.6.31.1/fs/xfs/linux-2.6/xfs_super.c 2009-10-01 20:12:44.000000000 -0400
27228 @@ -67,7 +67,7 @@
27229 #include <linux/freezer.h>
27230 #include <linux/parser.h>
27231
27232 -static struct super_operations xfs_super_operations;
27233 +static const struct super_operations xfs_super_operations;
27234 static kmem_zone_t *xfs_ioend_zone;
27235 mempool_t *xfs_ioend_pool;
27236
27237 @@ -1532,7 +1532,7 @@ xfs_fs_get_sb(
27238 mnt);
27239 }
27240
27241 -static struct super_operations xfs_super_operations = {
27242 +static const struct super_operations xfs_super_operations = {
27243 .alloc_inode = xfs_fs_alloc_inode,
27244 .destroy_inode = xfs_fs_destroy_inode,
27245 .write_inode = xfs_fs_write_inode,
27246 diff -urNp linux-2.6.31.1/fs/xfs/xfs_bmap.c linux-2.6.31.1/fs/xfs/xfs_bmap.c
27247 --- linux-2.6.31.1/fs/xfs/xfs_bmap.c 2009-09-24 11:45:25.000000000 -0400
27248 +++ linux-2.6.31.1/fs/xfs/xfs_bmap.c 2009-10-01 20:12:44.000000000 -0400
27249 @@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
27250 int nmap,
27251 int ret_nmap);
27252 #else
27253 -#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
27254 +#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
27255 #endif /* DEBUG */
27256
27257 #if defined(XFS_RW_TRACE)
27258 diff -urNp linux-2.6.31.1/grsecurity/gracl_alloc.c linux-2.6.31.1/grsecurity/gracl_alloc.c
27259 --- linux-2.6.31.1/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
27260 +++ linux-2.6.31.1/grsecurity/gracl_alloc.c 2009-10-01 20:12:44.000000000 -0400
27261 @@ -0,0 +1,105 @@
27262 +#include <linux/kernel.h>
27263 +#include <linux/mm.h>
27264 +#include <linux/slab.h>
27265 +#include <linux/vmalloc.h>
27266 +#include <linux/gracl.h>
27267 +#include <linux/grsecurity.h>
27268 +
27269 +static unsigned long alloc_stack_next = 1;
27270 +static unsigned long alloc_stack_size = 1;
27271 +static void **alloc_stack;
27272 +
27273 +static __inline__ int
27274 +alloc_pop(void)
27275 +{
27276 + if (alloc_stack_next == 1)
27277 + return 0;
27278 +
27279 + kfree(alloc_stack[alloc_stack_next - 2]);
27280 +
27281 + alloc_stack_next--;
27282 +
27283 + return 1;
27284 +}
27285 +
27286 +static __inline__ int
27287 +alloc_push(void *buf)
27288 +{
27289 + if (alloc_stack_next >= alloc_stack_size)
27290 + return 1;
27291 +
27292 + alloc_stack[alloc_stack_next - 1] = buf;
27293 +
27294 + alloc_stack_next++;
27295 +
27296 + return 0;
27297 +}
27298 +
27299 +void *
27300 +acl_alloc(unsigned long len)
27301 +{
27302 + void *ret = NULL;
27303 +
27304 + if (!len || len > PAGE_SIZE)
27305 + goto out;
27306 +
27307 + ret = kmalloc(len, GFP_KERNEL);
27308 +
27309 + if (ret) {
27310 + if (alloc_push(ret)) {
27311 + kfree(ret);
27312 + ret = NULL;
27313 + }
27314 + }
27315 +
27316 +out:
27317 + return ret;
27318 +}
27319 +
27320 +void *
27321 +acl_alloc_num(unsigned long num, unsigned long len)
27322 +{
27323 + if (!len || (num > (PAGE_SIZE / len)))
27324 + return NULL;
27325 +
27326 + return acl_alloc(num * len);
27327 +}
27328 +
27329 +void
27330 +acl_free_all(void)
27331 +{
27332 + if (gr_acl_is_enabled() || !alloc_stack)
27333 + return;
27334 +
27335 + while (alloc_pop()) ;
27336 +
27337 + if (alloc_stack) {
27338 + if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
27339 + kfree(alloc_stack);
27340 + else
27341 + vfree(alloc_stack);
27342 + }
27343 +
27344 + alloc_stack = NULL;
27345 + alloc_stack_size = 1;
27346 + alloc_stack_next = 1;
27347 +
27348 + return;
27349 +}
27350 +
27351 +int
27352 +acl_alloc_stack_init(unsigned long size)
27353 +{
27354 + if ((size * sizeof (void *)) <= PAGE_SIZE)
27355 + alloc_stack =
27356 + (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
27357 + else
27358 + alloc_stack = (void **) vmalloc(size * sizeof (void *));
27359 +
27360 + alloc_stack_size = size;
27361 +
27362 + if (!alloc_stack)
27363 + return 0;
27364 + else
27365 + return 1;
27366 +}
27367 diff -urNp linux-2.6.31.1/grsecurity/gracl.c linux-2.6.31.1/grsecurity/gracl.c
27368 --- linux-2.6.31.1/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
27369 +++ linux-2.6.31.1/grsecurity/gracl.c 2009-10-01 20:12:44.000000000 -0400
27370 @@ -0,0 +1,3912 @@
27371 +#include <linux/kernel.h>
27372 +#include <linux/module.h>
27373 +#include <linux/sched.h>
27374 +#include <linux/mm.h>
27375 +#include <linux/file.h>
27376 +#include <linux/fs.h>
27377 +#include <linux/namei.h>
27378 +#include <linux/mount.h>
27379 +#include <linux/tty.h>
27380 +#include <linux/proc_fs.h>
27381 +#include <linux/smp_lock.h>
27382 +#include <linux/slab.h>
27383 +#include <linux/vmalloc.h>
27384 +#include <linux/types.h>
27385 +#include <linux/sysctl.h>
27386 +#include <linux/netdevice.h>
27387 +#include <linux/ptrace.h>
27388 +#include <linux/gracl.h>
27389 +#include <linux/gralloc.h>
27390 +#include <linux/grsecurity.h>
27391 +#include <linux/grinternal.h>
27392 +#include <linux/pid_namespace.h>
27393 +#include <linux/fdtable.h>
27394 +#include <linux/percpu.h>
27395 +
27396 +#include <asm/uaccess.h>
27397 +#include <asm/errno.h>
27398 +#include <asm/mman.h>
27399 +
27400 +static struct acl_role_db acl_role_set;
27401 +static struct name_db name_set;
27402 +static struct inodev_db inodev_set;
27403 +
27404 +/* for keeping track of userspace pointers used for subjects, so we
27405 + can share references in the kernel as well
27406 +*/
27407 +
27408 +static struct dentry *real_root;
27409 +static struct vfsmount *real_root_mnt;
27410 +
27411 +static struct acl_subj_map_db subj_map_set;
27412 +
27413 +static struct acl_role_label *default_role;
27414 +
27415 +static u16 acl_sp_role_value;
27416 +
27417 +extern char *gr_shared_page[4];
27418 +static DECLARE_MUTEX(gr_dev_sem);
27419 +DEFINE_RWLOCK(gr_inode_lock);
27420 +
27421 +struct gr_arg *gr_usermode;
27422 +
27423 +#ifdef CONFIG_PAX_KERNEXEC
27424 +static unsigned int gr_status __read_only = GR_STATUS_INIT;
27425 +#else
27426 +static unsigned int gr_status = GR_STATUS_INIT;
27427 +#endif
27428 +
27429 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
27430 +extern void gr_clear_learn_entries(void);
27431 +
27432 +#ifdef CONFIG_GRKERNSEC_RESLOG
27433 +extern void gr_log_resource(const struct task_struct *task,
27434 + const int res, const unsigned long wanted, const int gt);
27435 +#endif
27436 +
27437 +unsigned char *gr_system_salt;
27438 +unsigned char *gr_system_sum;
27439 +
27440 +static struct sprole_pw **acl_special_roles = NULL;
27441 +static __u16 num_sprole_pws = 0;
27442 +
27443 +static struct acl_role_label *kernel_role = NULL;
27444 +
27445 +static unsigned int gr_auth_attempts = 0;
27446 +static unsigned long gr_auth_expires = 0UL;
27447 +
27448 +extern struct vfsmount *sock_mnt;
27449 +extern struct vfsmount *pipe_mnt;
27450 +extern struct vfsmount *shm_mnt;
27451 +static struct acl_object_label *fakefs_obj;
27452 +
27453 +extern int gr_init_uidset(void);
27454 +extern void gr_free_uidset(void);
27455 +extern void gr_remove_uid(uid_t uid);
27456 +extern int gr_find_uid(uid_t uid);
27457 +
27458 +__inline__ int
27459 +gr_acl_is_enabled(void)
27460 +{
27461 + return (gr_status & GR_READY);
27462 +}
27463 +
27464 +char gr_roletype_to_char(void)
27465 +{
27466 + switch (current->role->roletype &
27467 + (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
27468 + GR_ROLE_SPECIAL)) {
27469 + case GR_ROLE_DEFAULT:
27470 + return 'D';
27471 + case GR_ROLE_USER:
27472 + return 'U';
27473 + case GR_ROLE_GROUP:
27474 + return 'G';
27475 + case GR_ROLE_SPECIAL:
27476 + return 'S';
27477 + }
27478 +
27479 + return 'X';
27480 +}
27481 +
27482 +__inline__ int
27483 +gr_acl_tpe_check(void)
27484 +{
27485 + if (unlikely(!(gr_status & GR_READY)))
27486 + return 0;
27487 + if (current->role->roletype & GR_ROLE_TPE)
27488 + return 1;
27489 + else
27490 + return 0;
27491 +}
27492 +
27493 +int
27494 +gr_handle_rawio(const struct inode *inode)
27495 +{
27496 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
27497 + if (inode && S_ISBLK(inode->i_mode) &&
27498 + grsec_enable_chroot_caps && proc_is_chrooted(current) &&
27499 + !capable(CAP_SYS_RAWIO))
27500 + return 1;
27501 +#endif
27502 + return 0;
27503 +}
27504 +
27505 +static int
27506 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
27507 +{
27508 + int i;
27509 + unsigned long *l1;
27510 + unsigned long *l2;
27511 + unsigned char *c1;
27512 + unsigned char *c2;
27513 + int num_longs;
27514 +
27515 + if (likely(lena != lenb))
27516 + return 0;
27517 +
27518 + l1 = (unsigned long *)a;
27519 + l2 = (unsigned long *)b;
27520 +
27521 + num_longs = lena / sizeof(unsigned long);
27522 +
27523 + for (i = num_longs; i--; l1++, l2++) {
27524 + if (unlikely(*l1 != *l2))
27525 + return 0;
27526 + }
27527 +
27528 + c1 = (unsigned char *) l1;
27529 + c2 = (unsigned char *) l2;
27530 +
27531 + i = lena - (num_longs * sizeof(unsigned long));
27532 +
27533 + for (; i--; c1++, c2++) {
27534 + if (unlikely(*c1 != *c2))
27535 + return 0;
27536 + }
27537 +
27538 + return 1;
27539 +}
27540 +
27541 +static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
27542 + struct dentry *root, struct vfsmount *rootmnt,
27543 + char *buffer, int buflen)
27544 +{
27545 + char * end = buffer+buflen;
27546 + char * retval;
27547 + int namelen;
27548 +
27549 + *--end = '\0';
27550 + buflen--;
27551 +
27552 + if (buflen < 1)
27553 + goto Elong;
27554 + /* Get '/' right */
27555 + retval = end-1;
27556 + *retval = '/';
27557 +
27558 + for (;;) {
27559 + struct dentry * parent;
27560 +
27561 + if (dentry == root && vfsmnt == rootmnt)
27562 + break;
27563 + if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
27564 + /* Global root? */
27565 + spin_lock(&vfsmount_lock);
27566 + if (vfsmnt->mnt_parent == vfsmnt) {
27567 + spin_unlock(&vfsmount_lock);
27568 + goto global_root;
27569 + }
27570 + dentry = vfsmnt->mnt_mountpoint;
27571 + vfsmnt = vfsmnt->mnt_parent;
27572 + spin_unlock(&vfsmount_lock);
27573 + continue;
27574 + }
27575 + parent = dentry->d_parent;
27576 + prefetch(parent);
27577 + namelen = dentry->d_name.len;
27578 + buflen -= namelen + 1;
27579 + if (buflen < 0)
27580 + goto Elong;
27581 + end -= namelen;
27582 + memcpy(end, dentry->d_name.name, namelen);
27583 + *--end = '/';
27584 + retval = end;
27585 + dentry = parent;
27586 + }
27587 +
27588 + return retval;
27589 +
27590 +global_root:
27591 + namelen = dentry->d_name.len;
27592 + buflen -= namelen;
27593 + if (buflen < 0)
27594 + goto Elong;
27595 + retval -= namelen-1; /* hit the slash */
27596 + memcpy(retval, dentry->d_name.name, namelen);
27597 + return retval;
27598 +Elong:
27599 + return ERR_PTR(-ENAMETOOLONG);
27600 +}
27601 +
27602 +static char *
27603 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
27604 + struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
27605 +{
27606 + char *retval;
27607 +
27608 + retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
27609 + if (unlikely(IS_ERR(retval)))
27610 + retval = strcpy(buf, "<path too long>");
27611 + else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
27612 + retval[1] = '\0';
27613 +
27614 + return retval;
27615 +}
27616 +
27617 +static char *
27618 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
27619 + char *buf, int buflen)
27620 +{
27621 + char *res;
27622 +
27623 + /* we can use real_root, real_root_mnt, because this is only called
27624 + by the RBAC system */
27625 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
27626 +
27627 + return res;
27628 +}
27629 +
27630 +static char *
27631 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
27632 + char *buf, int buflen)
27633 +{
27634 + char *res;
27635 + struct dentry *root;
27636 + struct vfsmount *rootmnt;
27637 + struct task_struct *reaper = &init_task;
27638 +
27639 + /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
27640 + read_lock(&reaper->fs->lock);
27641 + root = dget(reaper->fs->root.dentry);
27642 + rootmnt = mntget(reaper->fs->root.mnt);
27643 + read_unlock(&reaper->fs->lock);
27644 +
27645 + spin_lock(&dcache_lock);
27646 + res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
27647 + spin_unlock(&dcache_lock);
27648 +
27649 + dput(root);
27650 + mntput(rootmnt);
27651 + return res;
27652 +}
27653 +
27654 +static char *
27655 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
27656 +{
27657 + char *ret;
27658 + spin_lock(&dcache_lock);
27659 + ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
27660 + PAGE_SIZE);
27661 + spin_unlock(&dcache_lock);
27662 + return ret;
27663 +}
27664 +
27665 +char *
27666 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
27667 +{
27668 + return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
27669 + PAGE_SIZE);
27670 +}
27671 +
27672 +char *
27673 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
27674 +{
27675 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
27676 + PAGE_SIZE);
27677 +}
27678 +
27679 +char *
27680 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
27681 +{
27682 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
27683 + PAGE_SIZE);
27684 +}
27685 +
27686 +char *
27687 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
27688 +{
27689 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
27690 + PAGE_SIZE);
27691 +}
27692 +
27693 +char *
27694 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
27695 +{
27696 + return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
27697 + PAGE_SIZE);
27698 +}
27699 +
27700 +__inline__ __u32
27701 +to_gr_audit(const __u32 reqmode)
27702 +{
27703 + /* masks off auditable permission flags, then shifts them to create
27704 + auditing flags, and adds the special case of append auditing if
27705 + we're requesting write */
27706 + return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
27707 +}
27708 +
27709 +struct acl_subject_label *
27710 +lookup_subject_map(const struct acl_subject_label *userp)
27711 +{
27712 + unsigned int index = shash(userp, subj_map_set.s_size);
27713 + struct subject_map *match;
27714 +
27715 + match = subj_map_set.s_hash[index];
27716 +
27717 + while (match && match->user != userp)
27718 + match = match->next;
27719 +
27720 + if (match != NULL)
27721 + return match->kernel;
27722 + else
27723 + return NULL;
27724 +}
27725 +
27726 +static void
27727 +insert_subj_map_entry(struct subject_map *subjmap)
27728 +{
27729 + unsigned int index = shash(subjmap->user, subj_map_set.s_size);
27730 + struct subject_map **curr;
27731 +
27732 + subjmap->prev = NULL;
27733 +
27734 + curr = &subj_map_set.s_hash[index];
27735 + if (*curr != NULL)
27736 + (*curr)->prev = subjmap;
27737 +
27738 + subjmap->next = *curr;
27739 + *curr = subjmap;
27740 +
27741 + return;
27742 +}
27743 +
27744 +static struct acl_role_label *
27745 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
27746 + const gid_t gid)
27747 +{
27748 + unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
27749 + struct acl_role_label *match;
27750 + struct role_allowed_ip *ipp;
27751 + unsigned int x;
27752 +
27753 + match = acl_role_set.r_hash[index];
27754 +
27755 + while (match) {
27756 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
27757 + for (x = 0; x < match->domain_child_num; x++) {
27758 + if (match->domain_children[x] == uid)
27759 + goto found;
27760 + }
27761 + } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
27762 + break;
27763 + match = match->next;
27764 + }
27765 +found:
27766 + if (match == NULL) {
27767 + try_group:
27768 + index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
27769 + match = acl_role_set.r_hash[index];
27770 +
27771 + while (match) {
27772 + if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
27773 + for (x = 0; x < match->domain_child_num; x++) {
27774 + if (match->domain_children[x] == gid)
27775 + goto found2;
27776 + }
27777 + } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
27778 + break;
27779 + match = match->next;
27780 + }
27781 +found2:
27782 + if (match == NULL)
27783 + match = default_role;
27784 + if (match->allowed_ips == NULL)
27785 + return match;
27786 + else {
27787 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
27788 + if (likely
27789 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
27790 + (ntohl(ipp->addr) & ipp->netmask)))
27791 + return match;
27792 + }
27793 + match = default_role;
27794 + }
27795 + } else if (match->allowed_ips == NULL) {
27796 + return match;
27797 + } else {
27798 + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
27799 + if (likely
27800 + ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
27801 + (ntohl(ipp->addr) & ipp->netmask)))
27802 + return match;
27803 + }
27804 + goto try_group;
27805 + }
27806 +
27807 + return match;
27808 +}
27809 +
27810 +struct acl_subject_label *
27811 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
27812 + const struct acl_role_label *role)
27813 +{
27814 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
27815 + struct acl_subject_label *match;
27816 +
27817 + match = role->subj_hash[index];
27818 +
27819 + while (match && (match->inode != ino || match->device != dev ||
27820 + (match->mode & GR_DELETED))) {
27821 + match = match->next;
27822 + }
27823 +
27824 + if (match && !(match->mode & GR_DELETED))
27825 + return match;
27826 + else
27827 + return NULL;
27828 +}
27829 +
27830 +struct acl_subject_label *
27831 +lookup_acl_subj_label_deleted(const ino_t ino, const dev_t dev,
27832 + const struct acl_role_label *role)
27833 +{
27834 + unsigned int index = fhash(ino, dev, role->subj_hash_size);
27835 + struct acl_subject_label *match;
27836 +
27837 + match = role->subj_hash[index];
27838 +
27839 + while (match && (match->inode != ino || match->device != dev ||
27840 + !(match->mode & GR_DELETED))) {
27841 + match = match->next;
27842 + }
27843 +
27844 + if (match && (match->mode & GR_DELETED))
27845 + return match;
27846 + else
27847 + return NULL;
27848 +}
27849 +
27850 +static struct acl_object_label *
27851 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
27852 + const struct acl_subject_label *subj)
27853 +{
27854 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
27855 + struct acl_object_label *match;
27856 +
27857 + match = subj->obj_hash[index];
27858 +
27859 + while (match && (match->inode != ino || match->device != dev ||
27860 + (match->mode & GR_DELETED))) {
27861 + match = match->next;
27862 + }
27863 +
27864 + if (match && !(match->mode & GR_DELETED))
27865 + return match;
27866 + else
27867 + return NULL;
27868 +}
27869 +
27870 +static struct acl_object_label *
27871 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
27872 + const struct acl_subject_label *subj)
27873 +{
27874 + unsigned int index = fhash(ino, dev, subj->obj_hash_size);
27875 + struct acl_object_label *match;
27876 +
27877 + match = subj->obj_hash[index];
27878 +
27879 + while (match && (match->inode != ino || match->device != dev ||
27880 + !(match->mode & GR_DELETED))) {
27881 + match = match->next;
27882 + }
27883 +
27884 + if (match && (match->mode & GR_DELETED))
27885 + return match;
27886 +
27887 + match = subj->obj_hash[index];
27888 +
27889 + while (match && (match->inode != ino || match->device != dev ||
27890 + (match->mode & GR_DELETED))) {
27891 + match = match->next;
27892 + }
27893 +
27894 + if (match && !(match->mode & GR_DELETED))
27895 + return match;
27896 + else
27897 + return NULL;
27898 +}
27899 +
27900 +static struct name_entry *
27901 +lookup_name_entry(const char *name)
27902 +{
27903 + unsigned int len = strlen(name);
27904 + unsigned int key = full_name_hash(name, len);
27905 + unsigned int index = key % name_set.n_size;
27906 + struct name_entry *match;
27907 +
27908 + match = name_set.n_hash[index];
27909 +
27910 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
27911 + match = match->next;
27912 +
27913 + return match;
27914 +}
27915 +
27916 +static struct name_entry *
27917 +lookup_name_entry_create(const char *name)
27918 +{
27919 + unsigned int len = strlen(name);
27920 + unsigned int key = full_name_hash(name, len);
27921 + unsigned int index = key % name_set.n_size;
27922 + struct name_entry *match;
27923 +
27924 + match = name_set.n_hash[index];
27925 +
27926 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
27927 + !match->deleted))
27928 + match = match->next;
27929 +
27930 + if (match && match->deleted)
27931 + return match;
27932 +
27933 + match = name_set.n_hash[index];
27934 +
27935 + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
27936 + match->deleted))
27937 + match = match->next;
27938 +
27939 + if (match && !match->deleted)
27940 + return match;
27941 + else
27942 + return NULL;
27943 +}
27944 +
27945 +static struct inodev_entry *
27946 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
27947 +{
27948 + unsigned int index = fhash(ino, dev, inodev_set.i_size);
27949 + struct inodev_entry *match;
27950 +
27951 + match = inodev_set.i_hash[index];
27952 +
27953 + while (match && (match->nentry->inode != ino || match->nentry->device != dev))
27954 + match = match->next;
27955 +
27956 + return match;
27957 +}
27958 +
27959 +static void
27960 +insert_inodev_entry(struct inodev_entry *entry)
27961 +{
27962 + unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
27963 + inodev_set.i_size);
27964 + struct inodev_entry **curr;
27965 +
27966 + entry->prev = NULL;
27967 +
27968 + curr = &inodev_set.i_hash[index];
27969 + if (*curr != NULL)
27970 + (*curr)->prev = entry;
27971 +
27972 + entry->next = *curr;
27973 + *curr = entry;
27974 +
27975 + return;
27976 +}
27977 +
27978 +static void
27979 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
27980 +{
27981 + unsigned int index =
27982 + rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
27983 + struct acl_role_label **curr;
27984 +
27985 + role->prev = NULL;
27986 +
27987 + curr = &acl_role_set.r_hash[index];
27988 + if (*curr != NULL)
27989 + (*curr)->prev = role;
27990 +
27991 + role->next = *curr;
27992 + *curr = role;
27993 +
27994 + return;
27995 +}
27996 +
27997 +static void
27998 +insert_acl_role_label(struct acl_role_label *role)
27999 +{
28000 + int i;
28001 +
28002 + if (role->roletype & GR_ROLE_DOMAIN) {
28003 + for (i = 0; i < role->domain_child_num; i++)
28004 + __insert_acl_role_label(role, role->domain_children[i]);
28005 + } else
28006 + __insert_acl_role_label(role, role->uidgid);
28007 +}
28008 +
28009 +static int
28010 +insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
28011 +{
28012 + struct name_entry **curr, *nentry;
28013 + struct inodev_entry *ientry;
28014 + unsigned int len = strlen(name);
28015 + unsigned int key = full_name_hash(name, len);
28016 + unsigned int index = key % name_set.n_size;
28017 +
28018 + curr = &name_set.n_hash[index];
28019 +
28020 + while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
28021 + curr = &((*curr)->next);
28022 +
28023 + if (*curr != NULL)
28024 + return 1;
28025 +
28026 + nentry = acl_alloc(sizeof (struct name_entry));
28027 + if (nentry == NULL)
28028 + return 0;
28029 + ientry = acl_alloc(sizeof (struct inodev_entry));
28030 + if (ientry == NULL)
28031 + return 0;
28032 + ientry->nentry = nentry;
28033 +
28034 + nentry->key = key;
28035 + nentry->name = name;
28036 + nentry->inode = inode;
28037 + nentry->device = device;
28038 + nentry->len = len;
28039 + nentry->deleted = deleted;
28040 +
28041 + nentry->prev = NULL;
28042 + curr = &name_set.n_hash[index];
28043 + if (*curr != NULL)
28044 + (*curr)->prev = nentry;
28045 + nentry->next = *curr;
28046 + *curr = nentry;
28047 +
28048 + /* insert us into the table searchable by inode/dev */
28049 + insert_inodev_entry(ientry);
28050 +
28051 + return 1;
28052 +}
28053 +
28054 +static void
28055 +insert_acl_obj_label(struct acl_object_label *obj,
28056 + struct acl_subject_label *subj)
28057 +{
28058 + unsigned int index =
28059 + fhash(obj->inode, obj->device, subj->obj_hash_size);
28060 + struct acl_object_label **curr;
28061 +
28062 +
28063 + obj->prev = NULL;
28064 +
28065 + curr = &subj->obj_hash[index];
28066 + if (*curr != NULL)
28067 + (*curr)->prev = obj;
28068 +
28069 + obj->next = *curr;
28070 + *curr = obj;
28071 +
28072 + return;
28073 +}
28074 +
28075 +static void
28076 +insert_acl_subj_label(struct acl_subject_label *obj,
28077 + struct acl_role_label *role)
28078 +{
28079 + unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
28080 + struct acl_subject_label **curr;
28081 +
28082 + obj->prev = NULL;
28083 +
28084 + curr = &role->subj_hash[index];
28085 + if (*curr != NULL)
28086 + (*curr)->prev = obj;
28087 +
28088 + obj->next = *curr;
28089 + *curr = obj;
28090 +
28091 + return;
28092 +}
28093 +
28094 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
28095 +
28096 +static void *
28097 +create_table(__u32 * len, int elementsize)
28098 +{
28099 + unsigned int table_sizes[] = {
28100 + 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
28101 + 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
28102 + 4194301, 8388593, 16777213, 33554393, 67108859
28103 + };
28104 + void *newtable = NULL;
28105 + unsigned int pwr = 0;
28106 +
28107 + while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
28108 + table_sizes[pwr] <= *len)
28109 + pwr++;
28110 +
28111 + if (table_sizes[pwr] <= *len || (table_sizes[pwr] > ULONG_MAX / elementsize))
28112 + return newtable;
28113 +
28114 + if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
28115 + newtable =
28116 + kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
28117 + else
28118 + newtable = vmalloc(table_sizes[pwr] * elementsize);
28119 +
28120 + *len = table_sizes[pwr];
28121 +
28122 + return newtable;
28123 +}
28124 +
28125 +static int
28126 +init_variables(const struct gr_arg *arg)
28127 +{
28128 + struct task_struct *reaper = &init_task;
28129 + unsigned int stacksize;
28130 +
28131 + subj_map_set.s_size = arg->role_db.num_subjects;
28132 + acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
28133 + name_set.n_size = arg->role_db.num_objects;
28134 + inodev_set.i_size = arg->role_db.num_objects;
28135 +
28136 + if (!subj_map_set.s_size || !acl_role_set.r_size ||
28137 + !name_set.n_size || !inodev_set.i_size)
28138 + return 1;
28139 +
28140 + if (!gr_init_uidset())
28141 + return 1;
28142 +
28143 + /* set up the stack that holds allocation info */
28144 +
28145 + stacksize = arg->role_db.num_pointers + 5;
28146 +
28147 + if (!acl_alloc_stack_init(stacksize))
28148 + return 1;
28149 +
28150 + /* grab reference for the real root dentry and vfsmount */
28151 + read_lock(&reaper->fs->lock);
28152 + real_root_mnt = mntget(reaper->fs->root.mnt);
28153 + real_root = dget(reaper->fs->root.dentry);
28154 + read_unlock(&reaper->fs->lock);
28155 +
28156 + fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
28157 + if (fakefs_obj == NULL)
28158 + return 1;
28159 + fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
28160 +
28161 + subj_map_set.s_hash =
28162 + (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
28163 + acl_role_set.r_hash =
28164 + (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
28165 + name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
28166 + inodev_set.i_hash =
28167 + (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
28168 +
28169 + if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
28170 + !name_set.n_hash || !inodev_set.i_hash)
28171 + return 1;
28172 +
28173 + memset(subj_map_set.s_hash, 0,
28174 + sizeof(struct subject_map *) * subj_map_set.s_size);
28175 + memset(acl_role_set.r_hash, 0,
28176 + sizeof (struct acl_role_label *) * acl_role_set.r_size);
28177 + memset(name_set.n_hash, 0,
28178 + sizeof (struct name_entry *) * name_set.n_size);
28179 + memset(inodev_set.i_hash, 0,
28180 + sizeof (struct inodev_entry *) * inodev_set.i_size);
28181 +
28182 + return 0;
28183 +}
28184 +
28185 +/* free information not needed after startup
28186 + currently contains user->kernel pointer mappings for subjects
28187 +*/
28188 +
28189 +static void
28190 +free_init_variables(void)
28191 +{
28192 + __u32 i;
28193 +
28194 + if (subj_map_set.s_hash) {
28195 + for (i = 0; i < subj_map_set.s_size; i++) {
28196 + if (subj_map_set.s_hash[i]) {
28197 + kfree(subj_map_set.s_hash[i]);
28198 + subj_map_set.s_hash[i] = NULL;
28199 + }
28200 + }
28201 +
28202 + if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
28203 + PAGE_SIZE)
28204 + kfree(subj_map_set.s_hash);
28205 + else
28206 + vfree(subj_map_set.s_hash);
28207 + }
28208 +
28209 + return;
28210 +}
28211 +
28212 +static void
28213 +free_variables(void)
28214 +{
28215 + struct acl_subject_label *s;
28216 + struct acl_role_label *r;
28217 + struct task_struct *task, *task2;
28218 + unsigned int i, x;
28219 +
28220 + gr_clear_learn_entries();
28221 +
28222 + read_lock(&tasklist_lock);
28223 + do_each_thread(task2, task) {
28224 + task->acl_sp_role = 0;
28225 + task->acl_role_id = 0;
28226 + task->acl = NULL;
28227 + task->role = NULL;
28228 + } while_each_thread(task2, task);
28229 + read_unlock(&tasklist_lock);
28230 +
28231 + /* release the reference to the real root dentry and vfsmount */
28232 + if (real_root)
28233 + dput(real_root);
28234 + real_root = NULL;
28235 + if (real_root_mnt)
28236 + mntput(real_root_mnt);
28237 + real_root_mnt = NULL;
28238 +
28239 + /* free all object hash tables */
28240 +
28241 + FOR_EACH_ROLE_START(r, i)
28242 + if (r->subj_hash == NULL)
28243 + break;
28244 + FOR_EACH_SUBJECT_START(r, s, x)
28245 + if (s->obj_hash == NULL)
28246 + break;
28247 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
28248 + kfree(s->obj_hash);
28249 + else
28250 + vfree(s->obj_hash);
28251 + FOR_EACH_SUBJECT_END(s, x)
28252 + FOR_EACH_NESTED_SUBJECT_START(r, s)
28253 + if (s->obj_hash == NULL)
28254 + break;
28255 + if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
28256 + kfree(s->obj_hash);
28257 + else
28258 + vfree(s->obj_hash);
28259 + FOR_EACH_NESTED_SUBJECT_END(s)
28260 + if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
28261 + kfree(r->subj_hash);
28262 + else
28263 + vfree(r->subj_hash);
28264 + r->subj_hash = NULL;
28265 + FOR_EACH_ROLE_END(r,i)
28266 +
28267 + acl_free_all();
28268 +
28269 + if (acl_role_set.r_hash) {
28270 + if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
28271 + PAGE_SIZE)
28272 + kfree(acl_role_set.r_hash);
28273 + else
28274 + vfree(acl_role_set.r_hash);
28275 + }
28276 + if (name_set.n_hash) {
28277 + if ((name_set.n_size * sizeof (struct name_entry *)) <=
28278 + PAGE_SIZE)
28279 + kfree(name_set.n_hash);
28280 + else
28281 + vfree(name_set.n_hash);
28282 + }
28283 +
28284 + if (inodev_set.i_hash) {
28285 + if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
28286 + PAGE_SIZE)
28287 + kfree(inodev_set.i_hash);
28288 + else
28289 + vfree(inodev_set.i_hash);
28290 + }
28291 +
28292 + gr_free_uidset();
28293 +
28294 + memset(&name_set, 0, sizeof (struct name_db));
28295 + memset(&inodev_set, 0, sizeof (struct inodev_db));
28296 + memset(&acl_role_set, 0, sizeof (struct acl_role_db));
28297 + memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
28298 +
28299 + default_role = NULL;
28300 +
28301 + return;
28302 +}
28303 +
28304 +static __u32
28305 +count_user_objs(struct acl_object_label *userp)
28306 +{
28307 + struct acl_object_label o_tmp;
28308 + __u32 num = 0;
28309 +
28310 + while (userp) {
28311 + if (copy_from_user(&o_tmp, userp,
28312 + sizeof (struct acl_object_label)))
28313 + break;
28314 +
28315 + userp = o_tmp.prev;
28316 + num++;
28317 + }
28318 +
28319 + return num;
28320 +}
28321 +
28322 +static struct acl_subject_label *
28323 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
28324 +
28325 +static int
28326 +copy_user_glob(struct acl_object_label *obj)
28327 +{
28328 + struct acl_object_label *g_tmp, **guser;
28329 + unsigned int len;
28330 + char *tmp;
28331 +
28332 + if (obj->globbed == NULL)
28333 + return 0;
28334 +
28335 + guser = &obj->globbed;
28336 + while (*guser) {
28337 + g_tmp = (struct acl_object_label *)
28338 + acl_alloc(sizeof (struct acl_object_label));
28339 + if (g_tmp == NULL)
28340 + return -ENOMEM;
28341 +
28342 + if (copy_from_user(g_tmp, *guser,
28343 + sizeof (struct acl_object_label)))
28344 + return -EFAULT;
28345 +
28346 + len = strnlen_user(g_tmp->filename, PATH_MAX);
28347 +
28348 + if (!len || len >= PATH_MAX)
28349 + return -EINVAL;
28350 +
28351 + if ((tmp = (char *) acl_alloc(len)) == NULL)
28352 + return -ENOMEM;
28353 +
28354 + if (copy_from_user(tmp, g_tmp->filename, len))
28355 + return -EFAULT;
28356 + tmp[len-1] = '\0';
28357 + g_tmp->filename = tmp;
28358 +
28359 + *guser = g_tmp;
28360 + guser = &(g_tmp->next);
28361 + }
28362 +
28363 + return 0;
28364 +}
28365 +
28366 +static int
28367 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
28368 + struct acl_role_label *role)
28369 +{
28370 + struct acl_object_label *o_tmp;
28371 + unsigned int len;
28372 + int ret;
28373 + char *tmp;
28374 +
28375 + while (userp) {
28376 + if ((o_tmp = (struct acl_object_label *)
28377 + acl_alloc(sizeof (struct acl_object_label))) == NULL)
28378 + return -ENOMEM;
28379 +
28380 + if (copy_from_user(o_tmp, userp,
28381 + sizeof (struct acl_object_label)))
28382 + return -EFAULT;
28383 +
28384 + userp = o_tmp->prev;
28385 +
28386 + len = strnlen_user(o_tmp->filename, PATH_MAX);
28387 +
28388 + if (!len || len >= PATH_MAX)
28389 + return -EINVAL;
28390 +
28391 + if ((tmp = (char *) acl_alloc(len)) == NULL)
28392 + return -ENOMEM;
28393 +
28394 + if (copy_from_user(tmp, o_tmp->filename, len))
28395 + return -EFAULT;
28396 + tmp[len-1] = '\0';
28397 + o_tmp->filename = tmp;
28398 +
28399 + insert_acl_obj_label(o_tmp, subj);
28400 + if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
28401 + o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
28402 + return -ENOMEM;
28403 +
28404 + ret = copy_user_glob(o_tmp);
28405 + if (ret)
28406 + return ret;
28407 +
28408 + if (o_tmp->nested) {
28409 + o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
28410 + if (IS_ERR(o_tmp->nested))
28411 + return PTR_ERR(o_tmp->nested);
28412 +
28413 + /* insert into nested subject list */
28414 + o_tmp->nested->next = role->hash->first;
28415 + role->hash->first = o_tmp->nested;
28416 + }
28417 + }
28418 +
28419 + return 0;
28420 +}
28421 +
28422 +static __u32
28423 +count_user_subjs(struct acl_subject_label *userp)
28424 +{
28425 + struct acl_subject_label s_tmp;
28426 + __u32 num = 0;
28427 +
28428 + while (userp) {
28429 + if (copy_from_user(&s_tmp, userp,
28430 + sizeof (struct acl_subject_label)))
28431 + break;
28432 +
28433 + userp = s_tmp.prev;
28434 + /* do not count nested subjects against this count, since
28435 + they are not included in the hash table, but are
28436 + attached to objects. We have already counted
28437 + the subjects in userspace for the allocation
28438 + stack
28439 + */
28440 + if (!(s_tmp.mode & GR_NESTED))
28441 + num++;
28442 + }
28443 +
28444 + return num;
28445 +}
28446 +
28447 +static int
28448 +copy_user_allowedips(struct acl_role_label *rolep)
28449 +{
28450 + struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
28451 +
28452 + ruserip = rolep->allowed_ips;
28453 +
28454 + while (ruserip) {
28455 + rlast = rtmp;
28456 +
28457 + if ((rtmp = (struct role_allowed_ip *)
28458 + acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
28459 + return -ENOMEM;
28460 +
28461 + if (copy_from_user(rtmp, ruserip,
28462 + sizeof (struct role_allowed_ip)))
28463 + return -EFAULT;
28464 +
28465 + ruserip = rtmp->prev;
28466 +
28467 + if (!rlast) {
28468 + rtmp->prev = NULL;
28469 + rolep->allowed_ips = rtmp;
28470 + } else {
28471 + rlast->next = rtmp;
28472 + rtmp->prev = rlast;
28473 + }
28474 +
28475 + if (!ruserip)
28476 + rtmp->next = NULL;
28477 + }
28478 +
28479 + return 0;
28480 +}
28481 +
28482 +static int
28483 +copy_user_transitions(struct acl_role_label *rolep)
28484 +{
28485 + struct role_transition *rusertp, *rtmp = NULL, *rlast;
28486 +
28487 + unsigned int len;
28488 + char *tmp;
28489 +
28490 + rusertp = rolep->transitions;
28491 +
28492 + while (rusertp) {
28493 + rlast = rtmp;
28494 +
28495 + if ((rtmp = (struct role_transition *)
28496 + acl_alloc(sizeof (struct role_transition))) == NULL)
28497 + return -ENOMEM;
28498 +
28499 + if (copy_from_user(rtmp, rusertp,
28500 + sizeof (struct role_transition)))
28501 + return -EFAULT;
28502 +
28503 + rusertp = rtmp->prev;
28504 +
28505 + len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
28506 +
28507 + if (!len || len >= GR_SPROLE_LEN)
28508 + return -EINVAL;
28509 +
28510 + if ((tmp = (char *) acl_alloc(len)) == NULL)
28511 + return -ENOMEM;
28512 +
28513 + if (copy_from_user(tmp, rtmp->rolename, len))
28514 + return -EFAULT;
28515 + tmp[len-1] = '\0';
28516 + rtmp->rolename = tmp;
28517 +
28518 + if (!rlast) {
28519 + rtmp->prev = NULL;
28520 + rolep->transitions = rtmp;
28521 + } else {
28522 + rlast->next = rtmp;
28523 + rtmp->prev = rlast;
28524 + }
28525 +
28526 + if (!rusertp)
28527 + rtmp->next = NULL;
28528 + }
28529 +
28530 + return 0;
28531 +}
28532 +
28533 +static struct acl_subject_label *
28534 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
28535 +{
28536 + struct acl_subject_label *s_tmp = NULL, *s_tmp2;
28537 + unsigned int len;
28538 + char *tmp;
28539 + __u32 num_objs;
28540 + struct acl_ip_label **i_tmp, *i_utmp2;
28541 + struct gr_hash_struct ghash;
28542 + struct subject_map *subjmap;
28543 + unsigned int i_num;
28544 + int err;
28545 +
28546 + s_tmp = lookup_subject_map(userp);
28547 +
28548 + /* we've already copied this subject into the kernel, just return
28549 + the reference to it, and don't copy it over again
28550 + */
28551 + if (s_tmp)
28552 + return(s_tmp);
28553 +
28554 + if ((s_tmp = (struct acl_subject_label *)
28555 + acl_alloc(sizeof (struct acl_subject_label))) == NULL)
28556 + return ERR_PTR(-ENOMEM);
28557 +
28558 + subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
28559 + if (subjmap == NULL)
28560 + return ERR_PTR(-ENOMEM);
28561 +
28562 + subjmap->user = userp;
28563 + subjmap->kernel = s_tmp;
28564 + insert_subj_map_entry(subjmap);
28565 +
28566 + if (copy_from_user(s_tmp, userp,
28567 + sizeof (struct acl_subject_label)))
28568 + return ERR_PTR(-EFAULT);
28569 +
28570 + len = strnlen_user(s_tmp->filename, PATH_MAX);
28571 +
28572 + if (!len || len >= PATH_MAX)
28573 + return ERR_PTR(-EINVAL);
28574 +
28575 + if ((tmp = (char *) acl_alloc(len)) == NULL)
28576 + return ERR_PTR(-ENOMEM);
28577 +
28578 + if (copy_from_user(tmp, s_tmp->filename, len))
28579 + return ERR_PTR(-EFAULT);
28580 + tmp[len-1] = '\0';
28581 + s_tmp->filename = tmp;
28582 +
28583 + if (!strcmp(s_tmp->filename, "/"))
28584 + role->root_label = s_tmp;
28585 +
28586 + if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
28587 + return ERR_PTR(-EFAULT);
28588 +
28589 + /* copy user and group transition tables */
28590 +
28591 + if (s_tmp->user_trans_num) {
28592 + uid_t *uidlist;
28593 +
28594 + uidlist = (uid_t *)acl_alloc_num(s_tmp->user_trans_num, sizeof(uid_t));
28595 + if (uidlist == NULL)
28596 + return ERR_PTR(-ENOMEM);
28597 + if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
28598 + return ERR_PTR(-EFAULT);
28599 +
28600 + s_tmp->user_transitions = uidlist;
28601 + }
28602 +
28603 + if (s_tmp->group_trans_num) {
28604 + gid_t *gidlist;
28605 +
28606 + gidlist = (gid_t *)acl_alloc_num(s_tmp->group_trans_num, sizeof(gid_t));
28607 + if (gidlist == NULL)
28608 + return ERR_PTR(-ENOMEM);
28609 + if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
28610 + return ERR_PTR(-EFAULT);
28611 +
28612 + s_tmp->group_transitions = gidlist;
28613 + }
28614 +
28615 + /* set up object hash table */
28616 + num_objs = count_user_objs(ghash.first);
28617 +
28618 + s_tmp->obj_hash_size = num_objs;
28619 + s_tmp->obj_hash =
28620 + (struct acl_object_label **)
28621 + create_table(&(s_tmp->obj_hash_size), sizeof(void *));
28622 +
28623 + if (!s_tmp->obj_hash)
28624 + return ERR_PTR(-ENOMEM);
28625 +
28626 + memset(s_tmp->obj_hash, 0,
28627 + s_tmp->obj_hash_size *
28628 + sizeof (struct acl_object_label *));
28629 +
28630 + /* add in objects */
28631 + err = copy_user_objs(ghash.first, s_tmp, role);
28632 +
28633 + if (err)
28634 + return ERR_PTR(err);
28635 +
28636 + /* set pointer for parent subject */
28637 + if (s_tmp->parent_subject) {
28638 + s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
28639 +
28640 + if (IS_ERR(s_tmp2))
28641 + return s_tmp2;
28642 +
28643 + s_tmp->parent_subject = s_tmp2;
28644 + }
28645 +
28646 + /* add in ip acls */
28647 +
28648 + if (!s_tmp->ip_num) {
28649 + s_tmp->ips = NULL;
28650 + goto insert;
28651 + }
28652 +
28653 + i_tmp =
28654 + (struct acl_ip_label **) acl_alloc_num(s_tmp->ip_num,
28655 + sizeof (struct acl_ip_label *));
28656 +
28657 + if (!i_tmp)
28658 + return ERR_PTR(-ENOMEM);
28659 +
28660 + for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
28661 + *(i_tmp + i_num) =
28662 + (struct acl_ip_label *)
28663 + acl_alloc(sizeof (struct acl_ip_label));
28664 + if (!*(i_tmp + i_num))
28665 + return ERR_PTR(-ENOMEM);
28666 +
28667 + if (copy_from_user
28668 + (&i_utmp2, s_tmp->ips + i_num,
28669 + sizeof (struct acl_ip_label *)))
28670 + return ERR_PTR(-EFAULT);
28671 +
28672 + if (copy_from_user
28673 + (*(i_tmp + i_num), i_utmp2,
28674 + sizeof (struct acl_ip_label)))
28675 + return ERR_PTR(-EFAULT);
28676 +
28677 + if ((*(i_tmp + i_num))->iface == NULL)
28678 + continue;
28679 +
28680 + len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
28681 + if (!len || len >= IFNAMSIZ)
28682 + return ERR_PTR(-EINVAL);
28683 + tmp = acl_alloc(len);
28684 + if (tmp == NULL)
28685 + return ERR_PTR(-ENOMEM);
28686 + if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
28687 + return ERR_PTR(-EFAULT);
28688 + (*(i_tmp + i_num))->iface = tmp;
28689 + }
28690 +
28691 + s_tmp->ips = i_tmp;
28692 +
28693 +insert:
28694 + if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
28695 + s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
28696 + return ERR_PTR(-ENOMEM);
28697 +
28698 + return s_tmp;
28699 +}
28700 +
28701 +static int
28702 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
28703 +{
28704 + struct acl_subject_label s_pre;
28705 + struct acl_subject_label * ret;
28706 + int err;
28707 +
28708 + while (userp) {
28709 + if (copy_from_user(&s_pre, userp,
28710 + sizeof (struct acl_subject_label)))
28711 + return -EFAULT;
28712 +
28713 + /* do not add nested subjects here, add
28714 + while parsing objects
28715 + */
28716 +
28717 + if (s_pre.mode & GR_NESTED) {
28718 + userp = s_pre.prev;
28719 + continue;
28720 + }
28721 +
28722 + ret = do_copy_user_subj(userp, role);
28723 +
28724 + err = PTR_ERR(ret);
28725 + if (IS_ERR(ret))
28726 + return err;
28727 +
28728 + insert_acl_subj_label(ret, role);
28729 +
28730 + userp = s_pre.prev;
28731 + }
28732 +
28733 + return 0;
28734 +}
28735 +
28736 +static int
28737 +copy_user_acl(struct gr_arg *arg)
28738 +{
28739 + struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
28740 + struct sprole_pw *sptmp;
28741 + struct gr_hash_struct *ghash;
28742 + uid_t *domainlist;
28743 + unsigned int r_num;
28744 + unsigned int len;
28745 + char *tmp;
28746 + int err = 0;
28747 + __u16 i;
28748 + __u32 num_subjs;
28749 +
28750 + /* we need a default and kernel role */
28751 + if (arg->role_db.num_roles < 2)
28752 + return -EINVAL;
28753 +
28754 + /* copy special role authentication info from userspace */
28755 +
28756 + num_sprole_pws = arg->num_sprole_pws;
28757 + acl_special_roles = (struct sprole_pw **) acl_alloc_num(num_sprole_pws, sizeof(struct sprole_pw *));
28758 +
28759 + if (!acl_special_roles) {
28760 + err = -ENOMEM;
28761 + goto cleanup;
28762 + }
28763 +
28764 + for (i = 0; i < num_sprole_pws; i++) {
28765 + sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
28766 + if (!sptmp) {
28767 + err = -ENOMEM;
28768 + goto cleanup;
28769 + }
28770 + if (copy_from_user(sptmp, arg->sprole_pws + i,
28771 + sizeof (struct sprole_pw))) {
28772 + err = -EFAULT;
28773 + goto cleanup;
28774 + }
28775 +
28776 + len =
28777 + strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
28778 +
28779 + if (!len || len >= GR_SPROLE_LEN) {
28780 + err = -EINVAL;
28781 + goto cleanup;
28782 + }
28783 +
28784 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
28785 + err = -ENOMEM;
28786 + goto cleanup;
28787 + }
28788 +
28789 + if (copy_from_user(tmp, sptmp->rolename, len)) {
28790 + err = -EFAULT;
28791 + goto cleanup;
28792 + }
28793 + tmp[len-1] = '\0';
28794 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
28795 + printk(KERN_ALERT "Copying special role %s\n", tmp);
28796 +#endif
28797 + sptmp->rolename = tmp;
28798 + acl_special_roles[i] = sptmp;
28799 + }
28800 +
28801 + r_utmp = (struct acl_role_label **) arg->role_db.r_table;
28802 +
28803 + for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
28804 + r_tmp = acl_alloc(sizeof (struct acl_role_label));
28805 +
28806 + if (!r_tmp) {
28807 + err = -ENOMEM;
28808 + goto cleanup;
28809 + }
28810 +
28811 + if (copy_from_user(&r_utmp2, r_utmp + r_num,
28812 + sizeof (struct acl_role_label *))) {
28813 + err = -EFAULT;
28814 + goto cleanup;
28815 + }
28816 +
28817 + if (copy_from_user(r_tmp, r_utmp2,
28818 + sizeof (struct acl_role_label))) {
28819 + err = -EFAULT;
28820 + goto cleanup;
28821 + }
28822 +
28823 + len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
28824 +
28825 + if (!len || len >= PATH_MAX) {
28826 + err = -EINVAL;
28827 + goto cleanup;
28828 + }
28829 +
28830 + if ((tmp = (char *) acl_alloc(len)) == NULL) {
28831 + err = -ENOMEM;
28832 + goto cleanup;
28833 + }
28834 + if (copy_from_user(tmp, r_tmp->rolename, len)) {
28835 + err = -EFAULT;
28836 + goto cleanup;
28837 + }
28838 + tmp[len-1] = '\0';
28839 + r_tmp->rolename = tmp;
28840 +
28841 + if (!strcmp(r_tmp->rolename, "default")
28842 + && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
28843 + default_role = r_tmp;
28844 + } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
28845 + kernel_role = r_tmp;
28846 + }
28847 +
28848 + if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
28849 + err = -ENOMEM;
28850 + goto cleanup;
28851 + }
28852 + if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
28853 + err = -EFAULT;
28854 + goto cleanup;
28855 + }
28856 +
28857 + r_tmp->hash = ghash;
28858 +
28859 + num_subjs = count_user_subjs(r_tmp->hash->first);
28860 +
28861 + r_tmp->subj_hash_size = num_subjs;
28862 + r_tmp->subj_hash =
28863 + (struct acl_subject_label **)
28864 + create_table(&(r_tmp->subj_hash_size), sizeof(void *));
28865 +
28866 + if (!r_tmp->subj_hash) {
28867 + err = -ENOMEM;
28868 + goto cleanup;
28869 + }
28870 +
28871 + err = copy_user_allowedips(r_tmp);
28872 + if (err)
28873 + goto cleanup;
28874 +
28875 + /* copy domain info */
28876 + if (r_tmp->domain_children != NULL) {
28877 + domainlist = acl_alloc_num(r_tmp->domain_child_num, sizeof(uid_t));
28878 + if (domainlist == NULL) {
28879 + err = -ENOMEM;
28880 + goto cleanup;
28881 + }
28882 + if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
28883 + err = -EFAULT;
28884 + goto cleanup;
28885 + }
28886 + r_tmp->domain_children = domainlist;
28887 + }
28888 +
28889 + err = copy_user_transitions(r_tmp);
28890 + if (err)
28891 + goto cleanup;
28892 +
28893 + memset(r_tmp->subj_hash, 0,
28894 + r_tmp->subj_hash_size *
28895 + sizeof (struct acl_subject_label *));
28896 +
28897 + err = copy_user_subjs(r_tmp->hash->first, r_tmp);
28898 +
28899 + if (err)
28900 + goto cleanup;
28901 +
28902 + /* set nested subject list to null */
28903 + r_tmp->hash->first = NULL;
28904 +
28905 + insert_acl_role_label(r_tmp);
28906 + }
28907 +
28908 + goto return_err;
28909 + cleanup:
28910 + free_variables();
28911 + return_err:
28912 + return err;
28913 +
28914 +}
28915 +
28916 +static int
28917 +gracl_init(struct gr_arg *args)
28918 +{
28919 + int error = 0;
28920 +
28921 + memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
28922 + memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
28923 +
28924 + if (init_variables(args)) {
28925 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
28926 + error = -ENOMEM;
28927 + free_variables();
28928 + goto out;
28929 + }
28930 +
28931 + error = copy_user_acl(args);
28932 + free_init_variables();
28933 + if (error) {
28934 + free_variables();
28935 + goto out;
28936 + }
28937 +
28938 + if ((error = gr_set_acls(0))) {
28939 + free_variables();
28940 + goto out;
28941 + }
28942 +
28943 +#ifdef CONFIG_PAX_KERNEXEC
28944 + {
28945 + unsigned long cr0;
28946 +
28947 + pax_open_kernel(cr0);
28948 + gr_status |= GR_READY;
28949 + pax_close_kernel(cr0);
28950 + }
28951 +#else
28952 + gr_status |= GR_READY;
28953 +#endif
28954 +
28955 + out:
28956 + return error;
28957 +}
28958 +
28959 +/* derived from glibc fnmatch() 0: match, 1: no match*/
28960 +
28961 +static int
28962 +glob_match(const char *p, const char *n)
28963 +{
28964 + char c;
28965 +
28966 + while ((c = *p++) != '\0') {
28967 + switch (c) {
28968 + case '?':
28969 + if (*n == '\0')
28970 + return 1;
28971 + else if (*n == '/')
28972 + return 1;
28973 + break;
28974 + case '\\':
28975 + if (*n != c)
28976 + return 1;
28977 + break;
28978 + case '*':
28979 + for (c = *p++; c == '?' || c == '*'; c = *p++) {
28980 + if (*n == '/')
28981 + return 1;
28982 + else if (c == '?') {
28983 + if (*n == '\0')
28984 + return 1;
28985 + else
28986 + ++n;
28987 + }
28988 + }
28989 + if (c == '\0') {
28990 + return 0;
28991 + } else {
28992 + const char *endp;
28993 +
28994 + if ((endp = strchr(n, '/')) == NULL)
28995 + endp = n + strlen(n);
28996 +
28997 + if (c == '[') {
28998 + for (--p; n < endp; ++n)
28999 + if (!glob_match(p, n))
29000 + return 0;
29001 + } else if (c == '/') {
29002 + while (*n != '\0' && *n != '/')
29003 + ++n;
29004 + if (*n == '/' && !glob_match(p, n + 1))
29005 + return 0;
29006 + } else {
29007 + for (--p; n < endp; ++n)
29008 + if (*n == c && !glob_match(p, n))
29009 + return 0;
29010 + }
29011 +
29012 + return 1;
29013 + }
29014 + case '[':
29015 + {
29016 + int not;
29017 + char cold;
29018 +
29019 + if (*n == '\0' || *n == '/')
29020 + return 1;
29021 +
29022 + not = (*p == '!' || *p == '^');
29023 + if (not)
29024 + ++p;
29025 +
29026 + c = *p++;
29027 + for (;;) {
29028 + unsigned char fn = (unsigned char)*n;
29029 +
29030 + if (c == '\0')
29031 + return 1;
29032 + else {
29033 + if (c == fn)
29034 + goto matched;
29035 + cold = c;
29036 + c = *p++;
29037 +
29038 + if (c == '-' && *p != ']') {
29039 + unsigned char cend = *p++;
29040 +
29041 + if (cend == '\0')
29042 + return 1;
29043 +
29044 + if (cold <= fn && fn <= cend)
29045 + goto matched;
29046 +
29047 + c = *p++;
29048 + }
29049 + }
29050 +
29051 + if (c == ']')
29052 + break;
29053 + }
29054 + if (!not)
29055 + return 1;
29056 + break;
29057 + matched:
29058 + while (c != ']') {
29059 + if (c == '\0')
29060 + return 1;
29061 +
29062 + c = *p++;
29063 + }
29064 + if (not)
29065 + return 1;
29066 + }
29067 + break;
29068 + default:
29069 + if (c != *n)
29070 + return 1;
29071 + }
29072 +
29073 + ++n;
29074 + }
29075 +
29076 + if (*n == '\0')
29077 + return 0;
29078 +
29079 + if (*n == '/')
29080 + return 0;
29081 +
29082 + return 1;
29083 +}
29084 +
29085 +static struct acl_object_label *
29086 +chk_glob_label(struct acl_object_label *globbed,
29087 + struct dentry *dentry, struct vfsmount *mnt, char **path)
29088 +{
29089 + struct acl_object_label *tmp;
29090 +
29091 + if (*path == NULL)
29092 + *path = gr_to_filename_nolock(dentry, mnt);
29093 +
29094 + tmp = globbed;
29095 +
29096 + while (tmp) {
29097 + if (!glob_match(tmp->filename, *path))
29098 + return tmp;
29099 + tmp = tmp->next;
29100 + }
29101 +
29102 + return NULL;
29103 +}
29104 +
29105 +static struct acl_object_label *
29106 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
29107 + const ino_t curr_ino, const dev_t curr_dev,
29108 + const struct acl_subject_label *subj, char **path, const int checkglob)
29109 +{
29110 + struct acl_subject_label *tmpsubj;
29111 + struct acl_object_label *retval;
29112 + struct acl_object_label *retval2;
29113 +
29114 + tmpsubj = (struct acl_subject_label *) subj;
29115 + read_lock(&gr_inode_lock);
29116 + do {
29117 + retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
29118 + if (retval) {
29119 + if (checkglob && retval->globbed) {
29120 + retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
29121 + (struct vfsmount *)orig_mnt, path);
29122 + if (retval2)
29123 + retval = retval2;
29124 + }
29125 + break;
29126 + }
29127 + } while ((tmpsubj = tmpsubj->parent_subject));
29128 + read_unlock(&gr_inode_lock);
29129 +
29130 + return retval;
29131 +}
29132 +
29133 +static __inline__ struct acl_object_label *
29134 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
29135 + const struct dentry *curr_dentry,
29136 + const struct acl_subject_label *subj, char **path, const int checkglob)
29137 +{
29138 + return __full_lookup(orig_dentry, orig_mnt,
29139 + curr_dentry->d_inode->i_ino,
29140 + curr_dentry->d_inode->i_sb->s_dev, subj, path, checkglob);
29141 +}
29142 +
29143 +static struct acl_object_label *
29144 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
29145 + const struct acl_subject_label *subj, char *path, const int checkglob)
29146 +{
29147 + struct dentry *dentry = (struct dentry *) l_dentry;
29148 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
29149 + struct acl_object_label *retval;
29150 +
29151 + spin_lock(&dcache_lock);
29152 +
29153 + if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
29154 + /* ignore Eric Biederman */
29155 + IS_PRIVATE(l_dentry->d_inode))) {
29156 + retval = fakefs_obj;
29157 + goto out;
29158 + }
29159 +
29160 + for (;;) {
29161 + if (dentry == real_root && mnt == real_root_mnt)
29162 + break;
29163 +
29164 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
29165 + if (mnt->mnt_parent == mnt)
29166 + break;
29167 +
29168 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
29169 + if (retval != NULL)
29170 + goto out;
29171 +
29172 + dentry = mnt->mnt_mountpoint;
29173 + mnt = mnt->mnt_parent;
29174 + continue;
29175 + }
29176 +
29177 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
29178 + if (retval != NULL)
29179 + goto out;
29180 +
29181 + dentry = dentry->d_parent;
29182 + }
29183 +
29184 + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
29185 +
29186 + if (retval == NULL)
29187 + retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path, checkglob);
29188 +out:
29189 + spin_unlock(&dcache_lock);
29190 + return retval;
29191 +}
29192 +
29193 +static __inline__ struct acl_object_label *
29194 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
29195 + const struct acl_subject_label *subj)
29196 +{
29197 + char *path = NULL;
29198 + return __chk_obj_label(l_dentry, l_mnt, subj, path, 1);
29199 +}
29200 +
29201 +static __inline__ struct acl_object_label *
29202 +chk_obj_label_noglob(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
29203 + const struct acl_subject_label *subj)
29204 +{
29205 + char *path = NULL;
29206 + return __chk_obj_label(l_dentry, l_mnt, subj, path, 0);
29207 +}
29208 +
29209 +static __inline__ struct acl_object_label *
29210 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
29211 + const struct acl_subject_label *subj, char *path)
29212 +{
29213 + return __chk_obj_label(l_dentry, l_mnt, subj, path, 1);
29214 +}
29215 +
29216 +static struct acl_subject_label *
29217 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
29218 + const struct acl_role_label *role)
29219 +{
29220 + struct dentry *dentry = (struct dentry *) l_dentry;
29221 + struct vfsmount *mnt = (struct vfsmount *) l_mnt;
29222 + struct acl_subject_label *retval;
29223 +
29224 + spin_lock(&dcache_lock);
29225 +
29226 + for (;;) {
29227 + if (dentry == real_root && mnt == real_root_mnt)
29228 + break;
29229 + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
29230 + if (mnt->mnt_parent == mnt)
29231 + break;
29232 +
29233 + read_lock(&gr_inode_lock);
29234 + retval =
29235 + lookup_acl_subj_label(dentry->d_inode->i_ino,
29236 + dentry->d_inode->i_sb->s_dev, role);
29237 + read_unlock(&gr_inode_lock);
29238 + if (retval != NULL)
29239 + goto out;
29240 +
29241 + dentry = mnt->mnt_mountpoint;
29242 + mnt = mnt->mnt_parent;
29243 + continue;
29244 + }
29245 +
29246 + read_lock(&gr_inode_lock);
29247 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
29248 + dentry->d_inode->i_sb->s_dev, role);
29249 + read_unlock(&gr_inode_lock);
29250 + if (retval != NULL)
29251 + goto out;
29252 +
29253 + dentry = dentry->d_parent;
29254 + }
29255 +
29256 + read_lock(&gr_inode_lock);
29257 + retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
29258 + dentry->d_inode->i_sb->s_dev, role);
29259 + read_unlock(&gr_inode_lock);
29260 +
29261 + if (unlikely(retval == NULL)) {
29262 + read_lock(&gr_inode_lock);
29263 + retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
29264 + real_root->d_inode->i_sb->s_dev, role);
29265 + read_unlock(&gr_inode_lock);
29266 + }
29267 +out:
29268 + spin_unlock(&dcache_lock);
29269 +
29270 + return retval;
29271 +}
29272 +
29273 +static void
29274 +gr_log_learn(const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
29275 +{
29276 + struct task_struct *task = current;
29277 + const struct cred *cred = current_cred();
29278 +
29279 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
29280 + cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
29281 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
29282 + 1UL, 1UL, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
29283 +
29284 + return;
29285 +}
29286 +
29287 +static void
29288 +gr_log_learn_sysctl(const char *path, const __u32 mode)
29289 +{
29290 + struct task_struct *task = current;
29291 + const struct cred *cred = current_cred();
29292 +
29293 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
29294 + cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
29295 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
29296 + 1UL, 1UL, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
29297 +
29298 + return;
29299 +}
29300 +
29301 +static void
29302 +gr_log_learn_id_change(const char type, const unsigned int real,
29303 + const unsigned int effective, const unsigned int fs)
29304 +{
29305 + struct task_struct *task = current;
29306 + const struct cred *cred = current_cred();
29307 +
29308 + security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
29309 + cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
29310 + task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
29311 + type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
29312 +
29313 + return;
29314 +}
29315 +
29316 +__u32
29317 +gr_check_link(const struct dentry * new_dentry,
29318 + const struct dentry * parent_dentry,
29319 + const struct vfsmount * parent_mnt,
29320 + const struct dentry * old_dentry, const struct vfsmount * old_mnt)
29321 +{
29322 + struct acl_object_label *obj;
29323 + __u32 oldmode, newmode;
29324 + __u32 needmode;
29325 +
29326 + if (unlikely(!(gr_status & GR_READY)))
29327 + return (GR_CREATE | GR_LINK);
29328 +
29329 + obj = chk_obj_label(old_dentry, old_mnt, current->acl);
29330 + oldmode = obj->mode;
29331 +
29332 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
29333 + oldmode |= (GR_CREATE | GR_LINK);
29334 +
29335 + needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
29336 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
29337 + needmode |= GR_SETID | GR_AUDIT_SETID;
29338 +
29339 + newmode =
29340 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
29341 + oldmode | needmode);
29342 +
29343 + needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
29344 + GR_SETID | GR_READ | GR_FIND | GR_DELETE |
29345 + GR_INHERIT | GR_AUDIT_INHERIT);
29346 +
29347 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
29348 + goto bad;
29349 +
29350 + if ((oldmode & needmode) != needmode)
29351 + goto bad;
29352 +
29353 + needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
29354 + if ((newmode & needmode) != needmode)
29355 + goto bad;
29356 +
29357 + if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
29358 + return newmode;
29359 +bad:
29360 + needmode = oldmode;
29361 + if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
29362 + needmode |= GR_SETID;
29363 +
29364 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
29365 + gr_log_learn(old_dentry, old_mnt, needmode);
29366 + return (GR_CREATE | GR_LINK);
29367 + } else if (newmode & GR_SUPPRESS)
29368 + return GR_SUPPRESS;
29369 + else
29370 + return 0;
29371 +}
29372 +
29373 +__u32
29374 +gr_search_file(const struct dentry * dentry, const __u32 mode,
29375 + const struct vfsmount * mnt)
29376 +{
29377 + __u32 retval = mode;
29378 + struct acl_subject_label *curracl;
29379 + struct acl_object_label *currobj;
29380 +
29381 + if (unlikely(!(gr_status & GR_READY)))
29382 + return (mode & ~GR_AUDITS);
29383 +
29384 + curracl = current->acl;
29385 +
29386 + currobj = chk_obj_label(dentry, mnt, curracl);
29387 + retval = currobj->mode & mode;
29388 +
29389 + if (unlikely
29390 + ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
29391 + && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
29392 + __u32 new_mode = mode;
29393 +
29394 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
29395 +
29396 + retval = new_mode;
29397 +
29398 + if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
29399 + new_mode |= GR_INHERIT;
29400 +
29401 + if (!(mode & GR_NOLEARN))
29402 + gr_log_learn(dentry, mnt, new_mode);
29403 + }
29404 +
29405 + return retval;
29406 +}
29407 +
29408 +__u32
29409 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
29410 + const struct vfsmount * mnt, const __u32 mode)
29411 +{
29412 + struct name_entry *match;
29413 + struct acl_object_label *matchpo;
29414 + struct acl_subject_label *curracl;
29415 + char *path;
29416 + __u32 retval;
29417 +
29418 + if (unlikely(!(gr_status & GR_READY)))
29419 + return (mode & ~GR_AUDITS);
29420 +
29421 + preempt_disable();
29422 + path = gr_to_filename_rbac(new_dentry, mnt);
29423 + match = lookup_name_entry_create(path);
29424 +
29425 + if (!match)
29426 + goto check_parent;
29427 +
29428 + curracl = current->acl;
29429 +
29430 + read_lock(&gr_inode_lock);
29431 + matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
29432 + read_unlock(&gr_inode_lock);
29433 +
29434 + if (matchpo) {
29435 + if ((matchpo->mode & mode) !=
29436 + (mode & ~(GR_AUDITS | GR_SUPPRESS))
29437 + && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
29438 + __u32 new_mode = mode;
29439 +
29440 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
29441 +
29442 + gr_log_learn(new_dentry, mnt, new_mode);
29443 +
29444 + preempt_enable();
29445 + return new_mode;
29446 + }
29447 + preempt_enable();
29448 + return (matchpo->mode & mode);
29449 + }
29450 +
29451 + check_parent:
29452 + curracl = current->acl;
29453 +
29454 + matchpo = chk_obj_create_label(parent, mnt, curracl, path);
29455 + retval = matchpo->mode & mode;
29456 +
29457 + if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
29458 + && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
29459 + __u32 new_mode = mode;
29460 +
29461 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
29462 +
29463 + gr_log_learn(new_dentry, mnt, new_mode);
29464 + preempt_enable();
29465 + return new_mode;
29466 + }
29467 +
29468 + preempt_enable();
29469 + return retval;
29470 +}
29471 +
29472 +int
29473 +gr_check_hidden_task(const struct task_struct *task)
29474 +{
29475 + if (unlikely(!(gr_status & GR_READY)))
29476 + return 0;
29477 +
29478 + if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
29479 + return 1;
29480 +
29481 + return 0;
29482 +}
29483 +
29484 +int
29485 +gr_check_protected_task(const struct task_struct *task)
29486 +{
29487 + if (unlikely(!(gr_status & GR_READY) || !task))
29488 + return 0;
29489 +
29490 + if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
29491 + task->acl != current->acl)
29492 + return 1;
29493 +
29494 + return 0;
29495 +}
29496 +
29497 +void
29498 +gr_copy_label(struct task_struct *tsk)
29499 +{
29500 + tsk->signal->used_accept = 0;
29501 + tsk->acl_sp_role = 0;
29502 + tsk->acl_role_id = current->acl_role_id;
29503 + tsk->acl = current->acl;
29504 + tsk->role = current->role;
29505 + tsk->signal->curr_ip = current->signal->curr_ip;
29506 + if (current->exec_file)
29507 + get_file(current->exec_file);
29508 + tsk->exec_file = current->exec_file;
29509 + tsk->is_writable = current->is_writable;
29510 + if (unlikely(current->signal->used_accept))
29511 + current->signal->curr_ip = 0;
29512 +
29513 + return;
29514 +}
29515 +
29516 +static void
29517 +gr_set_proc_res(struct task_struct *task)
29518 +{
29519 + struct acl_subject_label *proc;
29520 + unsigned short i;
29521 +
29522 + proc = task->acl;
29523 +
29524 + if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
29525 + return;
29526 +
29527 + for (i = 0; i < RLIM_NLIMITS; i++) {
29528 + if (!(proc->resmask & (1 << i)))
29529 + continue;
29530 +
29531 + task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
29532 + task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
29533 + }
29534 +
29535 + return;
29536 +}
29537 +
29538 +int
29539 +gr_check_user_change(int real, int effective, int fs)
29540 +{
29541 + unsigned int i;
29542 + __u16 num;
29543 + uid_t *uidlist;
29544 + int curuid;
29545 + int realok = 0;
29546 + int effectiveok = 0;
29547 + int fsok = 0;
29548 +
29549 + if (unlikely(!(gr_status & GR_READY)))
29550 + return 0;
29551 +
29552 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
29553 + gr_log_learn_id_change('u', real, effective, fs);
29554 +
29555 + num = current->acl->user_trans_num;
29556 + uidlist = current->acl->user_transitions;
29557 +
29558 + if (uidlist == NULL)
29559 + return 0;
29560 +
29561 + if (real == -1)
29562 + realok = 1;
29563 + if (effective == -1)
29564 + effectiveok = 1;
29565 + if (fs == -1)
29566 + fsok = 1;
29567 +
29568 + if (current->acl->user_trans_type & GR_ID_ALLOW) {
29569 + for (i = 0; i < num; i++) {
29570 + curuid = (int)uidlist[i];
29571 + if (real == curuid)
29572 + realok = 1;
29573 + if (effective == curuid)
29574 + effectiveok = 1;
29575 + if (fs == curuid)
29576 + fsok = 1;
29577 + }
29578 + } else if (current->acl->user_trans_type & GR_ID_DENY) {
29579 + for (i = 0; i < num; i++) {
29580 + curuid = (int)uidlist[i];
29581 + if (real == curuid)
29582 + break;
29583 + if (effective == curuid)
29584 + break;
29585 + if (fs == curuid)
29586 + break;
29587 + }
29588 + /* not in deny list */
29589 + if (i == num) {
29590 + realok = 1;
29591 + effectiveok = 1;
29592 + fsok = 1;
29593 + }
29594 + }
29595 +
29596 + if (realok && effectiveok && fsok)
29597 + return 0;
29598 + else {
29599 + gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
29600 + return 1;
29601 + }
29602 +}
29603 +
29604 +int
29605 +gr_check_group_change(int real, int effective, int fs)
29606 +{
29607 + unsigned int i;
29608 + __u16 num;
29609 + gid_t *gidlist;
29610 + int curgid;
29611 + int realok = 0;
29612 + int effectiveok = 0;
29613 + int fsok = 0;
29614 +
29615 + if (unlikely(!(gr_status & GR_READY)))
29616 + return 0;
29617 +
29618 + if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
29619 + gr_log_learn_id_change('g', real, effective, fs);
29620 +
29621 + num = current->acl->group_trans_num;
29622 + gidlist = current->acl->group_transitions;
29623 +
29624 + if (gidlist == NULL)
29625 + return 0;
29626 +
29627 + if (real == -1)
29628 + realok = 1;
29629 + if (effective == -1)
29630 + effectiveok = 1;
29631 + if (fs == -1)
29632 + fsok = 1;
29633 +
29634 + if (current->acl->group_trans_type & GR_ID_ALLOW) {
29635 + for (i = 0; i < num; i++) {
29636 + curgid = (int)gidlist[i];
29637 + if (real == curgid)
29638 + realok = 1;
29639 + if (effective == curgid)
29640 + effectiveok = 1;
29641 + if (fs == curgid)
29642 + fsok = 1;
29643 + }
29644 + } else if (current->acl->group_trans_type & GR_ID_DENY) {
29645 + for (i = 0; i < num; i++) {
29646 + curgid = (int)gidlist[i];
29647 + if (real == curgid)
29648 + break;
29649 + if (effective == curgid)
29650 + break;
29651 + if (fs == curgid)
29652 + break;
29653 + }
29654 + /* not in deny list */
29655 + if (i == num) {
29656 + realok = 1;
29657 + effectiveok = 1;
29658 + fsok = 1;
29659 + }
29660 + }
29661 +
29662 + if (realok && effectiveok && fsok)
29663 + return 0;
29664 + else {
29665 + gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
29666 + return 1;
29667 + }
29668 +}
29669 +
29670 +void
29671 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
29672 +{
29673 + struct acl_role_label *role = task->role;
29674 + struct acl_subject_label *subj = NULL;
29675 + struct acl_object_label *obj;
29676 + struct file *filp;
29677 +
29678 + if (unlikely(!(gr_status & GR_READY)))
29679 + return;
29680 +
29681 + filp = task->exec_file;
29682 +
29683 + /* kernel process, we'll give them the kernel role */
29684 + if (unlikely(!filp)) {
29685 + task->role = kernel_role;
29686 + task->acl = kernel_role->root_label;
29687 + return;
29688 + } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
29689 + role = lookup_acl_role_label(task, uid, gid);
29690 +
29691 + /* perform subject lookup in possibly new role
29692 + we can use this result below in the case where role == task->role
29693 + */
29694 + subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
29695 +
29696 + /* if we changed uid/gid, but result in the same role
29697 + and are using inheritance, don't lose the inherited subject
29698 + if current subject is other than what normal lookup
29699 + would result in, we arrived via inheritance, don't
29700 + lose subject
29701 + */
29702 + if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
29703 + (subj == task->acl)))
29704 + task->acl = subj;
29705 +
29706 + task->role = role;
29707 +
29708 + task->is_writable = 0;
29709 +
29710 + /* ignore additional mmap checks for processes that are writable
29711 + by the default ACL */
29712 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
29713 + if (unlikely(obj->mode & GR_WRITE))
29714 + task->is_writable = 1;
29715 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
29716 + if (unlikely(obj->mode & GR_WRITE))
29717 + task->is_writable = 1;
29718 +
29719 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
29720 + printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
29721 +#endif
29722 +
29723 + gr_set_proc_res(task);
29724 +
29725 + return;
29726 +}
29727 +
29728 +int
29729 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt,
29730 + const int unsafe_share)
29731 +{
29732 + struct task_struct *task = current;
29733 + struct acl_subject_label *newacl;
29734 + struct acl_object_label *obj;
29735 + __u32 retmode;
29736 +
29737 + if (unlikely(!(gr_status & GR_READY)))
29738 + return 0;
29739 +
29740 + newacl = chk_subj_label(dentry, mnt, task->role);
29741 +
29742 + task_lock(task);
29743 + if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
29744 + GR_POVERRIDE) && (task->acl != newacl) &&
29745 + !(task->role->roletype & GR_ROLE_GOD) &&
29746 + !gr_search_file(dentry, GR_PTRACERD, mnt) &&
29747 + !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN)))
29748 + || unsafe_share) {
29749 + task_unlock(task);
29750 + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
29751 + return -EACCES;
29752 + }
29753 + task_unlock(task);
29754 +
29755 + obj = chk_obj_label(dentry, mnt, task->acl);
29756 + retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
29757 +
29758 + if (!(task->acl->mode & GR_INHERITLEARN) &&
29759 + ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
29760 + if (obj->nested)
29761 + task->acl = obj->nested;
29762 + else
29763 + task->acl = newacl;
29764 + } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
29765 + gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
29766 +
29767 + task->is_writable = 0;
29768 +
29769 + /* ignore additional mmap checks for processes that are writable
29770 + by the default ACL */
29771 + obj = chk_obj_label(dentry, mnt, default_role->root_label);
29772 + if (unlikely(obj->mode & GR_WRITE))
29773 + task->is_writable = 1;
29774 + obj = chk_obj_label(dentry, mnt, task->role->root_label);
29775 + if (unlikely(obj->mode & GR_WRITE))
29776 + task->is_writable = 1;
29777 +
29778 + gr_set_proc_res(task);
29779 +
29780 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
29781 + printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
29782 +#endif
29783 + return 0;
29784 +}
29785 +
29786 +/* always called with valid inodev ptr */
29787 +static void
29788 +do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
29789 +{
29790 + struct acl_object_label *matchpo;
29791 + struct acl_subject_label *matchps;
29792 + struct acl_subject_label *subj;
29793 + struct acl_role_label *role;
29794 + unsigned int i, x;
29795 +
29796 + FOR_EACH_ROLE_START(role, i)
29797 + FOR_EACH_SUBJECT_START(role, subj, x)
29798 + if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
29799 + matchpo->mode |= GR_DELETED;
29800 + FOR_EACH_SUBJECT_END(subj,x)
29801 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
29802 + if (subj->inode == ino && subj->device == dev)
29803 + subj->mode |= GR_DELETED;
29804 + FOR_EACH_NESTED_SUBJECT_END(subj)
29805 + if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
29806 + matchps->mode |= GR_DELETED;
29807 + FOR_EACH_ROLE_END(role,i)
29808 +
29809 + inodev->nentry->deleted = 1;
29810 +
29811 + return;
29812 +}
29813 +
29814 +void
29815 +gr_handle_delete(const ino_t ino, const dev_t dev)
29816 +{
29817 + struct inodev_entry *inodev;
29818 +
29819 + if (unlikely(!(gr_status & GR_READY)))
29820 + return;
29821 +
29822 + write_lock(&gr_inode_lock);
29823 + inodev = lookup_inodev_entry(ino, dev);
29824 + if (inodev != NULL)
29825 + do_handle_delete(inodev, ino, dev);
29826 + write_unlock(&gr_inode_lock);
29827 +
29828 + return;
29829 +}
29830 +
29831 +static void
29832 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
29833 + const ino_t newinode, const dev_t newdevice,
29834 + struct acl_subject_label *subj)
29835 +{
29836 + unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
29837 + struct acl_object_label *match;
29838 +
29839 + match = subj->obj_hash[index];
29840 +
29841 + while (match && (match->inode != oldinode ||
29842 + match->device != olddevice ||
29843 + !(match->mode & GR_DELETED)))
29844 + match = match->next;
29845 +
29846 + if (match && (match->inode == oldinode)
29847 + && (match->device == olddevice)
29848 + && (match->mode & GR_DELETED)) {
29849 + if (match->prev == NULL) {
29850 + subj->obj_hash[index] = match->next;
29851 + if (match->next != NULL)
29852 + match->next->prev = NULL;
29853 + } else {
29854 + match->prev->next = match->next;
29855 + if (match->next != NULL)
29856 + match->next->prev = match->prev;
29857 + }
29858 + match->prev = NULL;
29859 + match->next = NULL;
29860 + match->inode = newinode;
29861 + match->device = newdevice;
29862 + match->mode &= ~GR_DELETED;
29863 +
29864 + insert_acl_obj_label(match, subj);
29865 + }
29866 +
29867 + return;
29868 +}
29869 +
29870 +static void
29871 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
29872 + const ino_t newinode, const dev_t newdevice,
29873 + struct acl_role_label *role)
29874 +{
29875 + unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
29876 + struct acl_subject_label *match;
29877 +
29878 + match = role->subj_hash[index];
29879 +
29880 + while (match && (match->inode != oldinode ||
29881 + match->device != olddevice ||
29882 + !(match->mode & GR_DELETED)))
29883 + match = match->next;
29884 +
29885 + if (match && (match->inode == oldinode)
29886 + && (match->device == olddevice)
29887 + && (match->mode & GR_DELETED)) {
29888 + if (match->prev == NULL) {
29889 + role->subj_hash[index] = match->next;
29890 + if (match->next != NULL)
29891 + match->next->prev = NULL;
29892 + } else {
29893 + match->prev->next = match->next;
29894 + if (match->next != NULL)
29895 + match->next->prev = match->prev;
29896 + }
29897 + match->prev = NULL;
29898 + match->next = NULL;
29899 + match->inode = newinode;
29900 + match->device = newdevice;
29901 + match->mode &= ~GR_DELETED;
29902 +
29903 + insert_acl_subj_label(match, role);
29904 + }
29905 +
29906 + return;
29907 +}
29908 +
29909 +static void
29910 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
29911 + const ino_t newinode, const dev_t newdevice)
29912 +{
29913 + unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
29914 + struct inodev_entry *match;
29915 +
29916 + match = inodev_set.i_hash[index];
29917 +
29918 + while (match && (match->nentry->inode != oldinode ||
29919 + match->nentry->device != olddevice || !match->nentry->deleted))
29920 + match = match->next;
29921 +
29922 + if (match && (match->nentry->inode == oldinode)
29923 + && (match->nentry->device == olddevice) &&
29924 + match->nentry->deleted) {
29925 + if (match->prev == NULL) {
29926 + inodev_set.i_hash[index] = match->next;
29927 + if (match->next != NULL)
29928 + match->next->prev = NULL;
29929 + } else {
29930 + match->prev->next = match->next;
29931 + if (match->next != NULL)
29932 + match->next->prev = match->prev;
29933 + }
29934 + match->prev = NULL;
29935 + match->next = NULL;
29936 + match->nentry->inode = newinode;
29937 + match->nentry->device = newdevice;
29938 + match->nentry->deleted = 0;
29939 +
29940 + insert_inodev_entry(match);
29941 + }
29942 +
29943 + return;
29944 +}
29945 +
29946 +static void
29947 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
29948 + const struct vfsmount *mnt)
29949 +{
29950 + struct acl_subject_label *subj;
29951 + struct acl_role_label *role;
29952 + unsigned int i, x;
29953 +
29954 + FOR_EACH_ROLE_START(role, i)
29955 + update_acl_subj_label(matchn->inode, matchn->device,
29956 + dentry->d_inode->i_ino,
29957 + dentry->d_inode->i_sb->s_dev, role);
29958 +
29959 + FOR_EACH_NESTED_SUBJECT_START(role, subj)
29960 + if ((subj->inode == dentry->d_inode->i_ino) &&
29961 + (subj->device == dentry->d_inode->i_sb->s_dev)) {
29962 + subj->inode = dentry->d_inode->i_ino;
29963 + subj->device = dentry->d_inode->i_sb->s_dev;
29964 + }
29965 + FOR_EACH_NESTED_SUBJECT_END(subj)
29966 + FOR_EACH_SUBJECT_START(role, subj, x)
29967 + update_acl_obj_label(matchn->inode, matchn->device,
29968 + dentry->d_inode->i_ino,
29969 + dentry->d_inode->i_sb->s_dev, subj);
29970 + FOR_EACH_SUBJECT_END(subj,x)
29971 + FOR_EACH_ROLE_END(role,i)
29972 +
29973 + update_inodev_entry(matchn->inode, matchn->device,
29974 + dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
29975 +
29976 + return;
29977 +}
29978 +
29979 +void
29980 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
29981 +{
29982 + struct name_entry *matchn;
29983 +
29984 + if (unlikely(!(gr_status & GR_READY)))
29985 + return;
29986 +
29987 + preempt_disable();
29988 + matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
29989 +
29990 + if (unlikely((unsigned long)matchn)) {
29991 + write_lock(&gr_inode_lock);
29992 + do_handle_create(matchn, dentry, mnt);
29993 + write_unlock(&gr_inode_lock);
29994 + }
29995 + preempt_enable();
29996 +
29997 + return;
29998 +}
29999 +
30000 +void
30001 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
30002 + struct dentry *old_dentry,
30003 + struct dentry *new_dentry,
30004 + struct vfsmount *mnt, const __u8 replace)
30005 +{
30006 + struct name_entry *matchn;
30007 + struct inodev_entry *inodev;
30008 +
30009 + /* vfs_rename swaps the name and parent link for old_dentry and
30010 + new_dentry
30011 + at this point, old_dentry has the new name, parent link, and inode
30012 + for the renamed file
30013 + if a file is being replaced by a rename, new_dentry has the inode
30014 + and name for the replaced file
30015 + */
30016 +
30017 + if (unlikely(!(gr_status & GR_READY)))
30018 + return;
30019 +
30020 + preempt_disable();
30021 + matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
30022 +
30023 + /* we wouldn't have to check d_inode if it weren't for
30024 + NFS silly-renaming
30025 + */
30026 +
30027 + write_lock(&gr_inode_lock);
30028 + if (unlikely(replace && new_dentry->d_inode)) {
30029 + inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
30030 + new_dentry->d_inode->i_sb->s_dev);
30031 + if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
30032 + do_handle_delete(inodev, new_dentry->d_inode->i_ino,
30033 + new_dentry->d_inode->i_sb->s_dev);
30034 + }
30035 +
30036 + inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
30037 + old_dentry->d_inode->i_sb->s_dev);
30038 + if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
30039 + do_handle_delete(inodev, old_dentry->d_inode->i_ino,
30040 + old_dentry->d_inode->i_sb->s_dev);
30041 +
30042 + if (unlikely((unsigned long)matchn))
30043 + do_handle_create(matchn, old_dentry, mnt);
30044 +
30045 + write_unlock(&gr_inode_lock);
30046 + preempt_enable();
30047 +
30048 + return;
30049 +}
30050 +
30051 +static int
30052 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
30053 + unsigned char **sum)
30054 +{
30055 + struct acl_role_label *r;
30056 + struct role_allowed_ip *ipp;
30057 + struct role_transition *trans;
30058 + unsigned int i;
30059 + int found = 0;
30060 +
30061 + /* check transition table */
30062 +
30063 + for (trans = current->role->transitions; trans; trans = trans->next) {
30064 + if (!strcmp(rolename, trans->rolename)) {
30065 + found = 1;
30066 + break;
30067 + }
30068 + }
30069 +
30070 + if (!found)
30071 + return 0;
30072 +
30073 + /* handle special roles that do not require authentication
30074 + and check ip */
30075 +
30076 + FOR_EACH_ROLE_START(r, i)
30077 + if (!strcmp(rolename, r->rolename) &&
30078 + (r->roletype & GR_ROLE_SPECIAL)) {
30079 + found = 0;
30080 + if (r->allowed_ips != NULL) {
30081 + for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
30082 + if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
30083 + (ntohl(ipp->addr) & ipp->netmask))
30084 + found = 1;
30085 + }
30086 + } else
30087 + found = 2;
30088 + if (!found)
30089 + return 0;
30090 +
30091 + if (((mode == GR_SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
30092 + ((mode == GR_SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
30093 + *salt = NULL;
30094 + *sum = NULL;
30095 + return 1;
30096 + }
30097 + }
30098 + FOR_EACH_ROLE_END(r,i)
30099 +
30100 + for (i = 0; i < num_sprole_pws; i++) {
30101 + if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
30102 + *salt = acl_special_roles[i]->salt;
30103 + *sum = acl_special_roles[i]->sum;
30104 + return 1;
30105 + }
30106 + }
30107 +
30108 + return 0;
30109 +}
30110 +
30111 +static void
30112 +assign_special_role(char *rolename)
30113 +{
30114 + struct acl_object_label *obj;
30115 + struct acl_role_label *r;
30116 + struct acl_role_label *assigned = NULL;
30117 + struct task_struct *tsk;
30118 + struct file *filp;
30119 + unsigned int i;
30120 +
30121 + FOR_EACH_ROLE_START(r, i)
30122 + if (!strcmp(rolename, r->rolename) &&
30123 + (r->roletype & GR_ROLE_SPECIAL))
30124 + assigned = r;
30125 + FOR_EACH_ROLE_END(r,i)
30126 +
30127 + if (!assigned)
30128 + return;
30129 +
30130 + read_lock(&tasklist_lock);
30131 + read_lock(&grsec_exec_file_lock);
30132 +
30133 + tsk = current->parent;
30134 + if (tsk == NULL)
30135 + goto out_unlock;
30136 +
30137 + filp = tsk->exec_file;
30138 + if (filp == NULL)
30139 + goto out_unlock;
30140 +
30141 + tsk->is_writable = 0;
30142 +
30143 + tsk->acl_sp_role = 1;
30144 + tsk->acl_role_id = ++acl_sp_role_value;
30145 + tsk->role = assigned;
30146 + tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
30147 +
30148 + /* ignore additional mmap checks for processes that are writable
30149 + by the default ACL */
30150 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
30151 + if (unlikely(obj->mode & GR_WRITE))
30152 + tsk->is_writable = 1;
30153 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
30154 + if (unlikely(obj->mode & GR_WRITE))
30155 + tsk->is_writable = 1;
30156 +
30157 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
30158 + printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
30159 +#endif
30160 +
30161 +out_unlock:
30162 + read_unlock(&grsec_exec_file_lock);
30163 + read_unlock(&tasklist_lock);
30164 + return;
30165 +}
30166 +
30167 +int gr_check_secure_terminal(struct task_struct *task)
30168 +{
30169 + struct task_struct *p, *p2, *p3;
30170 + struct files_struct *files;
30171 + struct fdtable *fdt;
30172 + struct file *our_file = NULL, *file;
30173 + int i;
30174 +
30175 + if (task->signal->tty == NULL)
30176 + return 1;
30177 +
30178 + files = get_files_struct(task);
30179 + if (files != NULL) {
30180 + rcu_read_lock();
30181 + fdt = files_fdtable(files);
30182 + for (i=0; i < fdt->max_fds; i++) {
30183 + file = fcheck_files(files, i);
30184 + if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
30185 + get_file(file);
30186 + our_file = file;
30187 + }
30188 + }
30189 + rcu_read_unlock();
30190 + put_files_struct(files);
30191 + }
30192 +
30193 + if (our_file == NULL)
30194 + return 1;
30195 +
30196 + read_lock(&tasklist_lock);
30197 + do_each_thread(p2, p) {
30198 + files = get_files_struct(p);
30199 + if (files == NULL ||
30200 + (p->signal && p->signal->tty == task->signal->tty)) {
30201 + if (files != NULL)
30202 + put_files_struct(files);
30203 + continue;
30204 + }
30205 + rcu_read_lock();
30206 + fdt = files_fdtable(files);
30207 + for (i=0; i < fdt->max_fds; i++) {
30208 + file = fcheck_files(files, i);
30209 + if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
30210 + file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
30211 + p3 = task;
30212 + while (p3->pid > 0) {
30213 + if (p3 == p)
30214 + break;
30215 + p3 = p3->parent;
30216 + }
30217 + if (p3 == p)
30218 + break;
30219 + gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
30220 + gr_handle_alertkill(p);
30221 + rcu_read_unlock();
30222 + put_files_struct(files);
30223 + read_unlock(&tasklist_lock);
30224 + fput(our_file);
30225 + return 0;
30226 + }
30227 + }
30228 + rcu_read_unlock();
30229 + put_files_struct(files);
30230 + } while_each_thread(p2, p);
30231 + read_unlock(&tasklist_lock);
30232 +
30233 + fput(our_file);
30234 + return 1;
30235 +}
30236 +
30237 +ssize_t
30238 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
30239 +{
30240 + struct gr_arg_wrapper uwrap;
30241 + unsigned char *sprole_salt;
30242 + unsigned char *sprole_sum;
30243 + int error = sizeof (struct gr_arg_wrapper);
30244 + int error2 = 0;
30245 +
30246 + down(&gr_dev_sem);
30247 +
30248 + if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
30249 + error = -EPERM;
30250 + goto out;
30251 + }
30252 +
30253 + if (count != sizeof (struct gr_arg_wrapper)) {
30254 + gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
30255 + error = -EINVAL;
30256 + goto out;
30257 + }
30258 +
30259 +
30260 + if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
30261 + gr_auth_expires = 0;
30262 + gr_auth_attempts = 0;
30263 + }
30264 +
30265 + if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
30266 + error = -EFAULT;
30267 + goto out;
30268 + }
30269 +
30270 + if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
30271 + error = -EINVAL;
30272 + goto out;
30273 + }
30274 +
30275 + if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
30276 + error = -EFAULT;
30277 + goto out;
30278 + }
30279 +
30280 + if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_SPROLEPAM &&
30281 + gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
30282 + time_after(gr_auth_expires, get_seconds())) {
30283 + error = -EBUSY;
30284 + goto out;
30285 + }
30286 +
30287 + /* if non-root trying to do anything other than use a special role,
30288 + do not attempt authentication, do not count towards authentication
30289 + locking
30290 + */
30291 +
30292 + if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_STATUS &&
30293 + gr_usermode->mode != GR_UNSPROLE && gr_usermode->mode != GR_SPROLEPAM &&
30294 + current_uid()) {
30295 + error = -EPERM;
30296 + goto out;
30297 + }
30298 +
30299 + /* ensure pw and special role name are null terminated */
30300 +
30301 + gr_usermode->pw[GR_PW_LEN - 1] = '\0';
30302 + gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
30303 +
30304 + /* Okay.
30305 + * We have our enough of the argument structure..(we have yet
30306 + * to copy_from_user the tables themselves) . Copy the tables
30307 + * only if we need them, i.e. for loading operations. */
30308 +
30309 + switch (gr_usermode->mode) {
30310 + case GR_STATUS:
30311 + if (gr_status & GR_READY) {
30312 + error = 1;
30313 + if (!gr_check_secure_terminal(current))
30314 + error = 3;
30315 + } else
30316 + error = 2;
30317 + goto out;
30318 + case GR_SHUTDOWN:
30319 + if ((gr_status & GR_READY)
30320 + && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
30321 +#ifdef CONFIG_PAX_KERNEXEC
30322 + {
30323 + unsigned long cr0;
30324 +
30325 + pax_open_kernel(cr0);
30326 + gr_status &= ~GR_READY;
30327 + pax_close_kernel(cr0);
30328 + }
30329 +#else
30330 + gr_status &= ~GR_READY;
30331 +#endif
30332 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
30333 + free_variables();
30334 + memset(gr_usermode, 0, sizeof (struct gr_arg));
30335 + memset(gr_system_salt, 0, GR_SALT_LEN);
30336 + memset(gr_system_sum, 0, GR_SHA_LEN);
30337 + } else if (gr_status & GR_READY) {
30338 + gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
30339 + error = -EPERM;
30340 + } else {
30341 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
30342 + error = -EAGAIN;
30343 + }
30344 + break;
30345 + case GR_ENABLE:
30346 + if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
30347 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
30348 + else {
30349 + if (gr_status & GR_READY)
30350 + error = -EAGAIN;
30351 + else
30352 + error = error2;
30353 + gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
30354 + }
30355 + break;
30356 + case GR_RELOAD:
30357 + if (!(gr_status & GR_READY)) {
30358 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
30359 + error = -EAGAIN;
30360 + } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
30361 + lock_kernel();
30362 +#ifdef CONFIG_PAX_KERNEXEC
30363 + {
30364 + unsigned long cr0;
30365 +
30366 + pax_open_kernel(cr0);
30367 + gr_status &= ~GR_READY;
30368 + pax_close_kernel(cr0);
30369 + }
30370 +#else
30371 + gr_status &= ~GR_READY;
30372 +#endif
30373 + free_variables();
30374 + if (!(error2 = gracl_init(gr_usermode))) {
30375 + unlock_kernel();
30376 + gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
30377 + } else {
30378 + unlock_kernel();
30379 + error = error2;
30380 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
30381 + }
30382 + } else {
30383 + gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
30384 + error = -EPERM;
30385 + }
30386 + break;
30387 + case GR_SEGVMOD:
30388 + if (unlikely(!(gr_status & GR_READY))) {
30389 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
30390 + error = -EAGAIN;
30391 + break;
30392 + }
30393 +
30394 + if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
30395 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
30396 + if (gr_usermode->segv_device && gr_usermode->segv_inode) {
30397 + struct acl_subject_label *segvacl;
30398 + segvacl =
30399 + lookup_acl_subj_label(gr_usermode->segv_inode,
30400 + gr_usermode->segv_device,
30401 + current->role);
30402 + if (segvacl) {
30403 + segvacl->crashes = 0;
30404 + segvacl->expires = 0;
30405 + }
30406 + } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
30407 + gr_remove_uid(gr_usermode->segv_uid);
30408 + }
30409 + } else {
30410 + gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
30411 + error = -EPERM;
30412 + }
30413 + break;
30414 + case GR_SPROLE:
30415 + case GR_SPROLEPAM:
30416 + if (unlikely(!(gr_status & GR_READY))) {
30417 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
30418 + error = -EAGAIN;
30419 + break;
30420 + }
30421 +
30422 + if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
30423 + current->role->expires = 0;
30424 + current->role->auth_attempts = 0;
30425 + }
30426 +
30427 + if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
30428 + time_after(current->role->expires, get_seconds())) {
30429 + error = -EBUSY;
30430 + goto out;
30431 + }
30432 +
30433 + if (lookup_special_role_auth
30434 + (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
30435 + && ((!sprole_salt && !sprole_sum)
30436 + || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
30437 + char *p = "";
30438 + assign_special_role(gr_usermode->sp_role);
30439 + read_lock(&tasklist_lock);
30440 + if (current->parent)
30441 + p = current->parent->role->rolename;
30442 + read_unlock(&tasklist_lock);
30443 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
30444 + p, acl_sp_role_value);
30445 + } else {
30446 + gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
30447 + error = -EPERM;
30448 + if(!(current->role->auth_attempts++))
30449 + current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
30450 +
30451 + goto out;
30452 + }
30453 + break;
30454 + case GR_UNSPROLE:
30455 + if (unlikely(!(gr_status & GR_READY))) {
30456 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
30457 + error = -EAGAIN;
30458 + break;
30459 + }
30460 +
30461 + if (current->role->roletype & GR_ROLE_SPECIAL) {
30462 + char *p = "";
30463 + int i = 0;
30464 +
30465 + read_lock(&tasklist_lock);
30466 + if (current->parent) {
30467 + p = current->parent->role->rolename;
30468 + i = current->parent->acl_role_id;
30469 + }
30470 + read_unlock(&tasklist_lock);
30471 +
30472 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
30473 + gr_set_acls(1);
30474 + } else {
30475 + gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
30476 + error = -EPERM;
30477 + goto out;
30478 + }
30479 + break;
30480 + default:
30481 + gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
30482 + error = -EINVAL;
30483 + break;
30484 + }
30485 +
30486 + if (error != -EPERM)
30487 + goto out;
30488 +
30489 + if(!(gr_auth_attempts++))
30490 + gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
30491 +
30492 + out:
30493 + up(&gr_dev_sem);
30494 + return error;
30495 +}
30496 +
30497 +int
30498 +gr_set_acls(const int type)
30499 +{
30500 + struct acl_object_label *obj;
30501 + struct task_struct *task, *task2;
30502 + struct file *filp;
30503 + struct acl_role_label *role = current->role;
30504 + __u16 acl_role_id = current->acl_role_id;
30505 + const struct cred *cred;
30506 + char *tmpname;
30507 + struct name_entry *nmatch;
30508 + struct acl_subject_label *tmpsubj;
30509 +
30510 + read_lock(&tasklist_lock);
30511 + read_lock(&grsec_exec_file_lock);
30512 + do_each_thread(task2, task) {
30513 + /* check to see if we're called from the exit handler,
30514 + if so, only replace ACLs that have inherited the admin
30515 + ACL */
30516 +
30517 + if (type && (task->role != role ||
30518 + task->acl_role_id != acl_role_id))
30519 + continue;
30520 +
30521 + task->acl_role_id = 0;
30522 + task->acl_sp_role = 0;
30523 +
30524 + if ((filp = task->exec_file)) {
30525 + cred = __task_cred(task);
30526 + task->role = lookup_acl_role_label(task, cred->uid, cred->gid);
30527 +
30528 + /* the following is to apply the correct subject
30529 + on binaries running when the RBAC system
30530 + is enabled, when the binaries have been
30531 + replaced or deleted since their execution
30532 + -----
30533 + when the RBAC system starts, the inode/dev
30534 + from exec_file will be one the RBAC system
30535 + is unaware of. It only knows the inode/dev
30536 + of the present file on disk, or the absence
30537 + of it.
30538 + */
30539 + preempt_disable();
30540 + tmpname = gr_to_filename_rbac(filp->f_path.dentry, filp->f_path.mnt);
30541 +
30542 + nmatch = lookup_name_entry(tmpname);
30543 + preempt_enable();
30544 + tmpsubj = NULL;
30545 + if (nmatch) {
30546 + if (nmatch->deleted)
30547 + tmpsubj = lookup_acl_subj_label_deleted(nmatch->inode, nmatch->device, task->role);
30548 + else
30549 + tmpsubj = lookup_acl_subj_label(nmatch->inode, nmatch->device, task->role);
30550 + if (tmpsubj != NULL)
30551 + task->acl = tmpsubj;
30552 + }
30553 + if (tmpsubj == NULL)
30554 + task->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
30555 + task->role);
30556 + if (task->acl) {
30557 + struct acl_subject_label *curr;
30558 + curr = task->acl;
30559 +
30560 + task->is_writable = 0;
30561 + /* ignore additional mmap checks for processes that are writable
30562 + by the default ACL */
30563 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
30564 + if (unlikely(obj->mode & GR_WRITE))
30565 + task->is_writable = 1;
30566 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
30567 + if (unlikely(obj->mode & GR_WRITE))
30568 + task->is_writable = 1;
30569 +
30570 + gr_set_proc_res(task);
30571 +
30572 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
30573 + printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
30574 +#endif
30575 + } else {
30576 + read_unlock(&grsec_exec_file_lock);
30577 + read_unlock(&tasklist_lock);
30578 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
30579 + return 1;
30580 + }
30581 + } else {
30582 + // it's a kernel process
30583 + task->role = kernel_role;
30584 + task->acl = kernel_role->root_label;
30585 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
30586 + task->acl->mode &= ~GR_PROCFIND;
30587 +#endif
30588 + }
30589 + } while_each_thread(task2, task);
30590 + read_unlock(&grsec_exec_file_lock);
30591 + read_unlock(&tasklist_lock);
30592 + return 0;
30593 +}
30594 +
30595 +void
30596 +gr_learn_resource(const struct task_struct *task,
30597 + const int res, const unsigned long wanted, const int gt)
30598 +{
30599 + struct acl_subject_label *acl;
30600 + const struct cred *cred;
30601 +
30602 + if (unlikely((gr_status & GR_READY) &&
30603 + task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
30604 + goto skip_reslog;
30605 +
30606 +#ifdef CONFIG_GRKERNSEC_RESLOG
30607 + gr_log_resource(task, res, wanted, gt);
30608 +#endif
30609 + skip_reslog:
30610 +
30611 + if (unlikely(!(gr_status & GR_READY) || !wanted || res >= GR_NLIMITS))
30612 + return;
30613 +
30614 + acl = task->acl;
30615 +
30616 + if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
30617 + !(acl->resmask & (1 << (unsigned short) res))))
30618 + return;
30619 +
30620 + if (wanted >= acl->res[res].rlim_cur) {
30621 + unsigned long res_add;
30622 +
30623 + res_add = wanted;
30624 + switch (res) {
30625 + case RLIMIT_CPU:
30626 + res_add += GR_RLIM_CPU_BUMP;
30627 + break;
30628 + case RLIMIT_FSIZE:
30629 + res_add += GR_RLIM_FSIZE_BUMP;
30630 + break;
30631 + case RLIMIT_DATA:
30632 + res_add += GR_RLIM_DATA_BUMP;
30633 + break;
30634 + case RLIMIT_STACK:
30635 + res_add += GR_RLIM_STACK_BUMP;
30636 + break;
30637 + case RLIMIT_CORE:
30638 + res_add += GR_RLIM_CORE_BUMP;
30639 + break;
30640 + case RLIMIT_RSS:
30641 + res_add += GR_RLIM_RSS_BUMP;
30642 + break;
30643 + case RLIMIT_NPROC:
30644 + res_add += GR_RLIM_NPROC_BUMP;
30645 + break;
30646 + case RLIMIT_NOFILE:
30647 + res_add += GR_RLIM_NOFILE_BUMP;
30648 + break;
30649 + case RLIMIT_MEMLOCK:
30650 + res_add += GR_RLIM_MEMLOCK_BUMP;
30651 + break;
30652 + case RLIMIT_AS:
30653 + res_add += GR_RLIM_AS_BUMP;
30654 + break;
30655 + case RLIMIT_LOCKS:
30656 + res_add += GR_RLIM_LOCKS_BUMP;
30657 + break;
30658 + case RLIMIT_SIGPENDING:
30659 + res_add += GR_RLIM_SIGPENDING_BUMP;
30660 + break;
30661 + case RLIMIT_MSGQUEUE:
30662 + res_add += GR_RLIM_MSGQUEUE_BUMP;
30663 + break;
30664 + case RLIMIT_NICE:
30665 + res_add += GR_RLIM_NICE_BUMP;
30666 + break;
30667 + case RLIMIT_RTPRIO:
30668 + res_add += GR_RLIM_RTPRIO_BUMP;
30669 + break;
30670 + case RLIMIT_RTTIME:
30671 + res_add += GR_RLIM_RTTIME_BUMP;
30672 + break;
30673 + }
30674 +
30675 + acl->res[res].rlim_cur = res_add;
30676 +
30677 + if (wanted > acl->res[res].rlim_max)
30678 + acl->res[res].rlim_max = res_add;
30679 +
30680 + /* only log the subject filename, since resource logging is supported for
30681 + single-subject learning only */
30682 + cred = __task_cred(task);
30683 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
30684 + task->role->roletype, cred->uid, cred->gid, acl->filename,
30685 + acl->filename, acl->res[res].rlim_cur, acl->res[res].rlim_max,
30686 + "", (unsigned long) res, NIPQUAD(task->signal->curr_ip));
30687 + }
30688 +
30689 + return;
30690 +}
30691 +
30692 +#if defined(CONFIG_PAX_HAVE_ACL_FLAGS) && (defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR))
30693 +void
30694 +pax_set_initial_flags(struct linux_binprm *bprm)
30695 +{
30696 + struct task_struct *task = current;
30697 + struct acl_subject_label *proc;
30698 + unsigned long flags;
30699 +
30700 + if (unlikely(!(gr_status & GR_READY)))
30701 + return;
30702 +
30703 + flags = pax_get_flags(task);
30704 +
30705 + proc = task->acl;
30706 +
30707 + if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
30708 + flags &= ~MF_PAX_PAGEEXEC;
30709 + if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
30710 + flags &= ~MF_PAX_SEGMEXEC;
30711 + if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
30712 + flags &= ~MF_PAX_RANDMMAP;
30713 + if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
30714 + flags &= ~MF_PAX_EMUTRAMP;
30715 + if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
30716 + flags &= ~MF_PAX_MPROTECT;
30717 +
30718 + if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
30719 + flags |= MF_PAX_PAGEEXEC;
30720 + if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
30721 + flags |= MF_PAX_SEGMEXEC;
30722 + if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
30723 + flags |= MF_PAX_RANDMMAP;
30724 + if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
30725 + flags |= MF_PAX_EMUTRAMP;
30726 + if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
30727 + flags |= MF_PAX_MPROTECT;
30728 +
30729 + pax_set_flags(task, flags);
30730 +
30731 + return;
30732 +}
30733 +#endif
30734 +
30735 +#ifdef CONFIG_SYSCTL
30736 +/* Eric Biederman likes breaking userland ABI and every inode-based security
30737 + system to save 35kb of memory */
30738 +
30739 +/* we modify the passed in filename, but adjust it back before returning */
30740 +static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
30741 +{
30742 + struct name_entry *nmatch;
30743 + char *p, *lastp = NULL;
30744 + struct acl_object_label *obj = NULL, *tmp;
30745 + struct acl_subject_label *tmpsubj;
30746 + char c = '\0';
30747 +
30748 + read_lock(&gr_inode_lock);
30749 +
30750 + p = name + len - 1;
30751 + do {
30752 + nmatch = lookup_name_entry(name);
30753 + if (lastp != NULL)
30754 + *lastp = c;
30755 +
30756 + if (nmatch == NULL)
30757 + goto next_component;
30758 + tmpsubj = current->acl;
30759 + do {
30760 + obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
30761 + if (obj != NULL) {
30762 + tmp = obj->globbed;
30763 + while (tmp) {
30764 + if (!glob_match(tmp->filename, name)) {
30765 + obj = tmp;
30766 + goto found_obj;
30767 + }
30768 + tmp = tmp->next;
30769 + }
30770 + goto found_obj;
30771 + }
30772 + } while ((tmpsubj = tmpsubj->parent_subject));
30773 +next_component:
30774 + /* end case */
30775 + if (p == name)
30776 + break;
30777 +
30778 + while (*p != '/')
30779 + p--;
30780 + if (p == name)
30781 + lastp = p + 1;
30782 + else {
30783 + lastp = p;
30784 + p--;
30785 + }
30786 + c = *lastp;
30787 + *lastp = '\0';
30788 + } while (1);
30789 +found_obj:
30790 + read_unlock(&gr_inode_lock);
30791 + /* obj returned will always be non-null */
30792 + return obj;
30793 +}
30794 +
30795 +/* returns 0 when allowing, non-zero on error
30796 + op of 0 is used for readdir, so we don't log the names of hidden files
30797 +*/
30798 +__u32
30799 +gr_handle_sysctl(const struct ctl_table *table, const int op)
30800 +{
30801 + ctl_table *tmp;
30802 + const char *proc_sys = "/proc/sys";
30803 + char *path;
30804 + struct acl_object_label *obj;
30805 + unsigned short len = 0, pos = 0, depth = 0, i;
30806 + __u32 err = 0;
30807 + __u32 mode = 0;
30808 +
30809 + if (unlikely(!(gr_status & GR_READY)))
30810 + return 0;
30811 +
30812 + /* for now, ignore operations on non-sysctl entries if it's not a
30813 + readdir*/
30814 + if (table->child != NULL && op != 0)
30815 + return 0;
30816 +
30817 + mode |= GR_FIND;
30818 + /* it's only a read if it's an entry, read on dirs is for readdir */
30819 + if (op & MAY_READ)
30820 + mode |= GR_READ;
30821 + if (op & MAY_WRITE)
30822 + mode |= GR_WRITE;
30823 +
30824 + preempt_disable();
30825 +
30826 + path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
30827 +
30828 + /* it's only a read/write if it's an actual entry, not a dir
30829 + (which are opened for readdir)
30830 + */
30831 +
30832 + /* convert the requested sysctl entry into a pathname */
30833 +
30834 + for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
30835 + len += strlen(tmp->procname);
30836 + len++;
30837 + depth++;
30838 + }
30839 +
30840 + if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
30841 + /* deny */
30842 + goto out;
30843 + }
30844 +
30845 + memset(path, 0, PAGE_SIZE);
30846 +
30847 + memcpy(path, proc_sys, strlen(proc_sys));
30848 +
30849 + pos += strlen(proc_sys);
30850 +
30851 + for (; depth > 0; depth--) {
30852 + path[pos] = '/';
30853 + pos++;
30854 + for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
30855 + if (depth == i) {
30856 + memcpy(path + pos, tmp->procname,
30857 + strlen(tmp->procname));
30858 + pos += strlen(tmp->procname);
30859 + }
30860 + i++;
30861 + }
30862 + }
30863 +
30864 + obj = gr_lookup_by_name(path, pos);
30865 + err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
30866 +
30867 + if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
30868 + ((err & mode) != mode))) {
30869 + __u32 new_mode = mode;
30870 +
30871 + new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
30872 +
30873 + err = 0;
30874 + gr_log_learn_sysctl(path, new_mode);
30875 + } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
30876 + gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
30877 + err = -ENOENT;
30878 + } else if (!(err & GR_FIND)) {
30879 + err = -ENOENT;
30880 + } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
30881 + gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
30882 + path, (mode & GR_READ) ? " reading" : "",
30883 + (mode & GR_WRITE) ? " writing" : "");
30884 + err = -EACCES;
30885 + } else if ((err & mode) != mode) {
30886 + err = -EACCES;
30887 + } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
30888 + gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
30889 + path, (mode & GR_READ) ? " reading" : "",
30890 + (mode & GR_WRITE) ? " writing" : "");
30891 + err = 0;
30892 + } else
30893 + err = 0;
30894 +
30895 + out:
30896 + preempt_enable();
30897 +
30898 + return err;
30899 +}
30900 +#endif
30901 +
30902 +int
30903 +gr_handle_proc_ptrace(struct task_struct *task)
30904 +{
30905 + struct file *filp;
30906 + struct task_struct *tmp = task;
30907 + struct task_struct *curtemp = current;
30908 + __u32 retmode;
30909 +
30910 +#ifndef CONFIG_GRKERNSEC_HARDEN_PTRACE
30911 + if (unlikely(!(gr_status & GR_READY)))
30912 + return 0;
30913 +#endif
30914 +
30915 + read_lock(&tasklist_lock);
30916 + read_lock(&grsec_exec_file_lock);
30917 + filp = task->exec_file;
30918 +
30919 + while (tmp->pid > 0) {
30920 + if (tmp == curtemp)
30921 + break;
30922 + tmp = tmp->parent;
30923 + }
30924 +
30925 + if (!filp || (tmp->pid == 0 && ((grsec_enable_harden_ptrace && current_uid() && !(gr_status & GR_READY)) ||
30926 + ((gr_status & GR_READY) && !(current->acl->mode & GR_RELAXPTRACE))))) {
30927 + read_unlock(&grsec_exec_file_lock);
30928 + read_unlock(&tasklist_lock);
30929 + return 1;
30930 + }
30931 +
30932 +#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
30933 + if (!(gr_status & GR_READY)) {
30934 + read_unlock(&grsec_exec_file_lock);
30935 + read_unlock(&tasklist_lock);
30936 + return 0;
30937 + }
30938 +#endif
30939 +
30940 + retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
30941 + read_unlock(&grsec_exec_file_lock);
30942 + read_unlock(&tasklist_lock);
30943 +
30944 + if (retmode & GR_NOPTRACE)
30945 + return 1;
30946 +
30947 + if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
30948 + && (current->acl != task->acl || (current->acl != current->role->root_label
30949 + && current->pid != task->pid)))
30950 + return 1;
30951 +
30952 + return 0;
30953 +}
30954 +
30955 +int
30956 +gr_handle_ptrace(struct task_struct *task, const long request)
30957 +{
30958 + struct task_struct *tmp = task;
30959 + struct task_struct *curtemp = current;
30960 + __u32 retmode;
30961 +
30962 +#ifndef CONFIG_GRKERNSEC_HARDEN_PTRACE
30963 + if (unlikely(!(gr_status & GR_READY)))
30964 + return 0;
30965 +#endif
30966 +
30967 + read_lock(&tasklist_lock);
30968 + while (tmp->pid > 0) {
30969 + if (tmp == curtemp)
30970 + break;
30971 + tmp = tmp->parent;
30972 + }
30973 +
30974 + if (tmp->pid == 0 && ((grsec_enable_harden_ptrace && current_uid() && !(gr_status & GR_READY)) ||
30975 + ((gr_status & GR_READY) && !(current->acl->mode & GR_RELAXPTRACE)))) {
30976 + read_unlock(&tasklist_lock);
30977 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
30978 + return 1;
30979 + }
30980 + read_unlock(&tasklist_lock);
30981 +
30982 +#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
30983 + if (!(gr_status & GR_READY))
30984 + return 0;
30985 +#endif
30986 +
30987 + read_lock(&grsec_exec_file_lock);
30988 + if (unlikely(!task->exec_file)) {
30989 + read_unlock(&grsec_exec_file_lock);
30990 + return 0;
30991 + }
30992 +
30993 + retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
30994 + read_unlock(&grsec_exec_file_lock);
30995 +
30996 + if (retmode & GR_NOPTRACE) {
30997 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
30998 + return 1;
30999 + }
31000 +
31001 + if (retmode & GR_PTRACERD) {
31002 + switch (request) {
31003 + case PTRACE_POKETEXT:
31004 + case PTRACE_POKEDATA:
31005 + case PTRACE_POKEUSR:
31006 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
31007 + case PTRACE_SETREGS:
31008 + case PTRACE_SETFPREGS:
31009 +#endif
31010 +#ifdef CONFIG_X86
31011 + case PTRACE_SETFPXREGS:
31012 +#endif
31013 +#ifdef CONFIG_ALTIVEC
31014 + case PTRACE_SETVRREGS:
31015 +#endif
31016 + return 1;
31017 + default:
31018 + return 0;
31019 + }
31020 + } else if (!(current->acl->mode & GR_POVERRIDE) &&
31021 + !(current->role->roletype & GR_ROLE_GOD) &&
31022 + (current->acl != task->acl)) {
31023 + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
31024 + return 1;
31025 + }
31026 +
31027 + return 0;
31028 +}
31029 +
31030 +static int is_writable_mmap(const struct file *filp)
31031 +{
31032 + struct task_struct *task = current;
31033 + struct acl_object_label *obj, *obj2;
31034 +
31035 + if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
31036 + !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
31037 + obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
31038 + obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
31039 + task->role->root_label);
31040 + if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
31041 + gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
31042 + return 1;
31043 + }
31044 + }
31045 + return 0;
31046 +}
31047 +
31048 +int
31049 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
31050 +{
31051 + __u32 mode;
31052 +
31053 + if (unlikely(!file || !(prot & PROT_EXEC)))
31054 + return 1;
31055 +
31056 + if (is_writable_mmap(file))
31057 + return 0;
31058 +
31059 + mode =
31060 + gr_search_file(file->f_path.dentry,
31061 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
31062 + file->f_path.mnt);
31063 +
31064 + if (!gr_tpe_allow(file))
31065 + return 0;
31066 +
31067 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
31068 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
31069 + return 0;
31070 + } else if (unlikely(!(mode & GR_EXEC))) {
31071 + return 0;
31072 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
31073 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
31074 + return 1;
31075 + }
31076 +
31077 + return 1;
31078 +}
31079 +
31080 +int
31081 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
31082 +{
31083 + __u32 mode;
31084 +
31085 + if (unlikely(!file || !(prot & PROT_EXEC)))
31086 + return 1;
31087 +
31088 + if (is_writable_mmap(file))
31089 + return 0;
31090 +
31091 + mode =
31092 + gr_search_file(file->f_path.dentry,
31093 + GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
31094 + file->f_path.mnt);
31095 +
31096 + if (!gr_tpe_allow(file))
31097 + return 0;
31098 +
31099 + if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
31100 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
31101 + return 0;
31102 + } else if (unlikely(!(mode & GR_EXEC))) {
31103 + return 0;
31104 + } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
31105 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
31106 + return 1;
31107 + }
31108 +
31109 + return 1;
31110 +}
31111 +
31112 +void
31113 +gr_acl_handle_psacct(struct task_struct *task, const long code)
31114 +{
31115 + unsigned long runtime;
31116 + unsigned long cputime;
31117 + unsigned int wday, cday;
31118 + __u8 whr, chr;
31119 + __u8 wmin, cmin;
31120 + __u8 wsec, csec;
31121 + struct timespec timeval;
31122 +
31123 + if (unlikely(!(gr_status & GR_READY) || !task->acl ||
31124 + !(task->acl->mode & GR_PROCACCT)))
31125 + return;
31126 +
31127 + do_posix_clock_monotonic_gettime(&timeval);
31128 + runtime = timeval.tv_sec - task->start_time.tv_sec;
31129 + wday = runtime / (3600 * 24);
31130 + runtime -= wday * (3600 * 24);
31131 + whr = runtime / 3600;
31132 + runtime -= whr * 3600;
31133 + wmin = runtime / 60;
31134 + runtime -= wmin * 60;
31135 + wsec = runtime;
31136 +
31137 + cputime = (task->utime + task->stime) / HZ;
31138 + cday = cputime / (3600 * 24);
31139 + cputime -= cday * (3600 * 24);
31140 + chr = cputime / 3600;
31141 + cputime -= chr * 3600;
31142 + cmin = cputime / 60;
31143 + cputime -= cmin * 60;
31144 + csec = cputime;
31145 +
31146 + gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
31147 +
31148 + return;
31149 +}
31150 +
31151 +void gr_set_kernel_label(struct task_struct *task)
31152 +{
31153 + if (gr_status & GR_READY) {
31154 + task->role = kernel_role;
31155 + task->acl = kernel_role->root_label;
31156 + }
31157 + return;
31158 +}
31159 +
31160 +#ifdef CONFIG_TASKSTATS
31161 +int gr_is_taskstats_denied(int pid)
31162 +{
31163 + struct task_struct *task;
31164 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31165 + const struct cred *cred;
31166 +#endif
31167 + int ret = 0;
31168 +
31169 + /* restrict taskstats viewing to un-chrooted root users
31170 + who have the 'view' subject flag if the RBAC system is enabled
31171 + */
31172 +
31173 + read_lock(&tasklist_lock);
31174 + task = find_task_by_vpid(pid);
31175 + if (task) {
31176 + task_lock(task);
31177 +#ifdef CONFIG_GRKERNSEC_CHROOT
31178 + if (proc_is_chrooted(task))
31179 + ret = -EACCES;
31180 +#endif
31181 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31182 + cred = __task_cred(task);
31183 +#ifdef CONFIG_GRKERNSEC_PROC_USER
31184 + if (cred->uid != 0)
31185 + ret = -EACCES;
31186 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31187 + if (cred->uid != 0 && !groups_search(cred->group_info, CONFIG_GRKERNSEC_PROC_GID))
31188 + ret = -EACCES;
31189 +#endif
31190 +#endif
31191 + if (gr_status & GR_READY) {
31192 + if (!(task->acl->mode & GR_VIEW))
31193 + ret = -EACCES;
31194 + }
31195 +
31196 + task_unlock(task);
31197 + } else
31198 + ret = -ENOENT;
31199 +
31200 + read_unlock(&tasklist_lock);
31201 +
31202 + return ret;
31203 +}
31204 +#endif
31205 +
31206 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
31207 +{
31208 + struct task_struct *task = current;
31209 + struct dentry *dentry = file->f_path.dentry;
31210 + struct vfsmount *mnt = file->f_path.mnt;
31211 + struct acl_object_label *obj, *tmp;
31212 + struct acl_subject_label *subj;
31213 + unsigned int bufsize;
31214 + int is_not_root;
31215 + char *path;
31216 +
31217 + if (unlikely(!(gr_status & GR_READY)))
31218 + return 1;
31219 +
31220 + if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
31221 + return 1;
31222 +
31223 + /* ignore Eric Biederman */
31224 + if (IS_PRIVATE(dentry->d_inode))
31225 + return 1;
31226 +
31227 + subj = task->acl;
31228 + do {
31229 + obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
31230 + if (obj != NULL)
31231 + return (obj->mode & GR_FIND) ? 1 : 0;
31232 + } while ((subj = subj->parent_subject));
31233 +
31234 + /* this is purely an optimization since we're looking for an object
31235 + for the directory we're doing a readdir on
31236 + if it's possible for any globbed object to match the entry we're
31237 + filling into the directory, then the object we find here will be
31238 + an anchor point with attached globbed objects
31239 + */
31240 + obj = chk_obj_label_noglob(dentry, mnt, task->acl);
31241 + if (obj->globbed == NULL)
31242 + return (obj->mode & GR_FIND) ? 1 : 0;
31243 +
31244 + is_not_root = ((obj->filename[0] == '/') &&
31245 + (obj->filename[1] == '\0')) ? 0 : 1;
31246 + bufsize = PAGE_SIZE - namelen - is_not_root;
31247 +
31248 + /* check bufsize > PAGE_SIZE || bufsize == 0 */
31249 + if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
31250 + return 1;
31251 +
31252 + preempt_disable();
31253 + path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
31254 + bufsize);
31255 +
31256 + bufsize = strlen(path);
31257 +
31258 + /* if base is "/", don't append an additional slash */
31259 + if (is_not_root)
31260 + *(path + bufsize) = '/';
31261 + memcpy(path + bufsize + is_not_root, name, namelen);
31262 + *(path + bufsize + namelen + is_not_root) = '\0';
31263 +
31264 + tmp = obj->globbed;
31265 + while (tmp) {
31266 + if (!glob_match(tmp->filename, path)) {
31267 + preempt_enable();
31268 + return (tmp->mode & GR_FIND) ? 1 : 0;
31269 + }
31270 + tmp = tmp->next;
31271 + }
31272 + preempt_enable();
31273 + return (obj->mode & GR_FIND) ? 1 : 0;
31274 +}
31275 +
31276 +EXPORT_SYMBOL(gr_learn_resource);
31277 +EXPORT_SYMBOL(gr_set_kernel_label);
31278 +#ifdef CONFIG_SECURITY
31279 +EXPORT_SYMBOL(gr_check_user_change);
31280 +EXPORT_SYMBOL(gr_check_group_change);
31281 +#endif
31282 +
31283 diff -urNp linux-2.6.31.1/grsecurity/gracl_cap.c linux-2.6.31.1/grsecurity/gracl_cap.c
31284 --- linux-2.6.31.1/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
31285 +++ linux-2.6.31.1/grsecurity/gracl_cap.c 2009-10-01 20:12:44.000000000 -0400
31286 @@ -0,0 +1,131 @@
31287 +#include <linux/kernel.h>
31288 +#include <linux/module.h>
31289 +#include <linux/sched.h>
31290 +#include <linux/gracl.h>
31291 +#include <linux/grsecurity.h>
31292 +#include <linux/grinternal.h>
31293 +
31294 +static const char *captab_log[] = {
31295 + "CAP_CHOWN",
31296 + "CAP_DAC_OVERRIDE",
31297 + "CAP_DAC_READ_SEARCH",
31298 + "CAP_FOWNER",
31299 + "CAP_FSETID",
31300 + "CAP_KILL",
31301 + "CAP_SETGID",
31302 + "CAP_SETUID",
31303 + "CAP_SETPCAP",
31304 + "CAP_LINUX_IMMUTABLE",
31305 + "CAP_NET_BIND_SERVICE",
31306 + "CAP_NET_BROADCAST",
31307 + "CAP_NET_ADMIN",
31308 + "CAP_NET_RAW",
31309 + "CAP_IPC_LOCK",
31310 + "CAP_IPC_OWNER",
31311 + "CAP_SYS_MODULE",
31312 + "CAP_SYS_RAWIO",
31313 + "CAP_SYS_CHROOT",
31314 + "CAP_SYS_PTRACE",
31315 + "CAP_SYS_PACCT",
31316 + "CAP_SYS_ADMIN",
31317 + "CAP_SYS_BOOT",
31318 + "CAP_SYS_NICE",
31319 + "CAP_SYS_RESOURCE",
31320 + "CAP_SYS_TIME",
31321 + "CAP_SYS_TTY_CONFIG",
31322 + "CAP_MKNOD",
31323 + "CAP_LEASE",
31324 + "CAP_AUDIT_WRITE",
31325 + "CAP_AUDIT_CONTROL",
31326 + "CAP_SETFCAP",
31327 + "CAP_MAC_OVERRIDE",
31328 + "CAP_MAC_ADMIN"
31329 +};
31330 +
31331 +EXPORT_SYMBOL(gr_is_capable);
31332 +EXPORT_SYMBOL(gr_is_capable_nolog);
31333 +
31334 +int
31335 +gr_is_capable(const int cap)
31336 +{
31337 + struct task_struct *task = current;
31338 + const struct cred *cred = current_cred();
31339 + struct acl_subject_label *curracl;
31340 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
31341 +
31342 + if (!gr_acl_is_enabled())
31343 + return 1;
31344 +
31345 + curracl = task->acl;
31346 +
31347 + cap_drop = curracl->cap_lower;
31348 + cap_mask = curracl->cap_mask;
31349 +
31350 + while ((curracl = curracl->parent_subject)) {
31351 + /* if the cap isn't specified in the current computed mask but is specified in the
31352 + current level subject, and is lowered in the current level subject, then add
31353 + it to the set of dropped capabilities
31354 + otherwise, add the current level subject's mask to the current computed mask
31355 + */
31356 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
31357 + cap_raise(cap_mask, cap);
31358 + if (cap_raised(curracl->cap_lower, cap))
31359 + cap_raise(cap_drop, cap);
31360 + }
31361 + }
31362 +
31363 + if (!cap_raised(cap_drop, cap))
31364 + return 1;
31365 +
31366 + curracl = task->acl;
31367 +
31368 + if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
31369 + && cap_raised(cred->cap_effective, cap)) {
31370 + security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
31371 + task->role->roletype, cred->uid,
31372 + cred->gid, task->exec_file ?
31373 + gr_to_filename(task->exec_file->f_path.dentry,
31374 + task->exec_file->f_path.mnt) : curracl->filename,
31375 + curracl->filename, 0UL,
31376 + 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
31377 + return 1;
31378 + }
31379 +
31380 + if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(cred->cap_effective, cap))
31381 + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
31382 + return 0;
31383 +}
31384 +
31385 +int
31386 +gr_is_capable_nolog(const int cap)
31387 +{
31388 + struct acl_subject_label *curracl;
31389 + kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
31390 +
31391 + if (!gr_acl_is_enabled())
31392 + return 1;
31393 +
31394 + curracl = current->acl;
31395 +
31396 + cap_drop = curracl->cap_lower;
31397 + cap_mask = curracl->cap_mask;
31398 +
31399 + while ((curracl = curracl->parent_subject)) {
31400 + /* if the cap isn't specified in the current computed mask but is specified in the
31401 + current level subject, and is lowered in the current level subject, then add
31402 + it to the set of dropped capabilities
31403 + otherwise, add the current level subject's mask to the current computed mask
31404 + */
31405 + if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
31406 + cap_raise(cap_mask, cap);
31407 + if (cap_raised(curracl->cap_lower, cap))
31408 + cap_raise(cap_drop, cap);
31409 + }
31410 + }
31411 +
31412 + if (!cap_raised(cap_drop, cap))
31413 + return 1;
31414 +
31415 + return 0;
31416 +}
31417 +
31418 diff -urNp linux-2.6.31.1/grsecurity/gracl_fs.c linux-2.6.31.1/grsecurity/gracl_fs.c
31419 --- linux-2.6.31.1/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
31420 +++ linux-2.6.31.1/grsecurity/gracl_fs.c 2009-10-01 20:12:44.000000000 -0400
31421 @@ -0,0 +1,424 @@
31422 +#include <linux/kernel.h>
31423 +#include <linux/sched.h>
31424 +#include <linux/types.h>
31425 +#include <linux/fs.h>
31426 +#include <linux/file.h>
31427 +#include <linux/stat.h>
31428 +#include <linux/grsecurity.h>
31429 +#include <linux/grinternal.h>
31430 +#include <linux/gracl.h>
31431 +
31432 +__u32
31433 +gr_acl_handle_hidden_file(const struct dentry * dentry,
31434 + const struct vfsmount * mnt)
31435 +{
31436 + __u32 mode;
31437 +
31438 + if (unlikely(!dentry->d_inode))
31439 + return GR_FIND;
31440 +
31441 + mode =
31442 + gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
31443 +
31444 + if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
31445 + gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
31446 + return mode;
31447 + } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
31448 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
31449 + return 0;
31450 + } else if (unlikely(!(mode & GR_FIND)))
31451 + return 0;
31452 +
31453 + return GR_FIND;
31454 +}
31455 +
31456 +__u32
31457 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
31458 + const int fmode)
31459 +{
31460 + __u32 reqmode = GR_FIND;
31461 + __u32 mode;
31462 +
31463 + if (unlikely(!dentry->d_inode))
31464 + return reqmode;
31465 +
31466 + if (unlikely(fmode & O_APPEND))
31467 + reqmode |= GR_APPEND;
31468 + else if (unlikely(fmode & FMODE_WRITE))
31469 + reqmode |= GR_WRITE;
31470 + if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
31471 + reqmode |= GR_READ;
31472 + if ((fmode & FMODE_GREXEC) && (fmode & FMODE_EXEC))
31473 + reqmode &= ~GR_READ;
31474 + mode =
31475 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
31476 + mnt);
31477 +
31478 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
31479 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
31480 + reqmode & GR_READ ? " reading" : "",
31481 + reqmode & GR_WRITE ? " writing" : reqmode &
31482 + GR_APPEND ? " appending" : "");
31483 + return reqmode;
31484 + } else
31485 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
31486 + {
31487 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
31488 + reqmode & GR_READ ? " reading" : "",
31489 + reqmode & GR_WRITE ? " writing" : reqmode &
31490 + GR_APPEND ? " appending" : "");
31491 + return 0;
31492 + } else if (unlikely((mode & reqmode) != reqmode))
31493 + return 0;
31494 +
31495 + return reqmode;
31496 +}
31497 +
31498 +__u32
31499 +gr_acl_handle_creat(const struct dentry * dentry,
31500 + const struct dentry * p_dentry,
31501 + const struct vfsmount * p_mnt, const int fmode,
31502 + const int imode)
31503 +{
31504 + __u32 reqmode = GR_WRITE | GR_CREATE;
31505 + __u32 mode;
31506 +
31507 + if (unlikely(fmode & O_APPEND))
31508 + reqmode |= GR_APPEND;
31509 + if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
31510 + reqmode |= GR_READ;
31511 + if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
31512 + reqmode |= GR_SETID;
31513 +
31514 + mode =
31515 + gr_check_create(dentry, p_dentry, p_mnt,
31516 + reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
31517 +
31518 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
31519 + gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
31520 + reqmode & GR_READ ? " reading" : "",
31521 + reqmode & GR_WRITE ? " writing" : reqmode &
31522 + GR_APPEND ? " appending" : "");
31523 + return reqmode;
31524 + } else
31525 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
31526 + {
31527 + gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
31528 + reqmode & GR_READ ? " reading" : "",
31529 + reqmode & GR_WRITE ? " writing" : reqmode &
31530 + GR_APPEND ? " appending" : "");
31531 + return 0;
31532 + } else if (unlikely((mode & reqmode) != reqmode))
31533 + return 0;
31534 +
31535 + return reqmode;
31536 +}
31537 +
31538 +__u32
31539 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
31540 + const int fmode)
31541 +{
31542 + __u32 mode, reqmode = GR_FIND;
31543 +
31544 + if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
31545 + reqmode |= GR_EXEC;
31546 + if (fmode & S_IWOTH)
31547 + reqmode |= GR_WRITE;
31548 + if (fmode & S_IROTH)
31549 + reqmode |= GR_READ;
31550 +
31551 + mode =
31552 + gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
31553 + mnt);
31554 +
31555 + if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
31556 + gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
31557 + reqmode & GR_READ ? " reading" : "",
31558 + reqmode & GR_WRITE ? " writing" : "",
31559 + reqmode & GR_EXEC ? " executing" : "");
31560 + return reqmode;
31561 + } else
31562 + if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
31563 + {
31564 + gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
31565 + reqmode & GR_READ ? " reading" : "",
31566 + reqmode & GR_WRITE ? " writing" : "",
31567 + reqmode & GR_EXEC ? " executing" : "");
31568 + return 0;
31569 + } else if (unlikely((mode & reqmode) != reqmode))
31570 + return 0;
31571 +
31572 + return reqmode;
31573 +}
31574 +
31575 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
31576 +{
31577 + __u32 mode;
31578 +
31579 + mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
31580 +
31581 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
31582 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
31583 + return mode;
31584 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
31585 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
31586 + return 0;
31587 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
31588 + return 0;
31589 +
31590 + return (reqmode);
31591 +}
31592 +
31593 +__u32
31594 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
31595 +{
31596 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
31597 +}
31598 +
31599 +__u32
31600 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
31601 +{
31602 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
31603 +}
31604 +
31605 +__u32
31606 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
31607 +{
31608 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
31609 +}
31610 +
31611 +__u32
31612 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
31613 +{
31614 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
31615 +}
31616 +
31617 +__u32
31618 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
31619 + mode_t mode)
31620 +{
31621 + if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
31622 + return 1;
31623 +
31624 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
31625 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
31626 + GR_FCHMOD_ACL_MSG);
31627 + } else {
31628 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
31629 + }
31630 +}
31631 +
31632 +__u32
31633 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
31634 + mode_t mode)
31635 +{
31636 + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
31637 + return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
31638 + GR_CHMOD_ACL_MSG);
31639 + } else {
31640 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
31641 + }
31642 +}
31643 +
31644 +__u32
31645 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
31646 +{
31647 + return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
31648 +}
31649 +
31650 +__u32
31651 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
31652 +{
31653 + return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
31654 +}
31655 +
31656 +__u32
31657 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
31658 +{
31659 + return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
31660 + GR_UNIXCONNECT_ACL_MSG);
31661 +}
31662 +
31663 +/* hardlinks require at minimum create permission,
31664 + any additional privilege required is based on the
31665 + privilege of the file being linked to
31666 +*/
31667 +__u32
31668 +gr_acl_handle_link(const struct dentry * new_dentry,
31669 + const struct dentry * parent_dentry,
31670 + const struct vfsmount * parent_mnt,
31671 + const struct dentry * old_dentry,
31672 + const struct vfsmount * old_mnt, const char *to)
31673 +{
31674 + __u32 mode;
31675 + __u32 needmode = GR_CREATE | GR_LINK;
31676 + __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
31677 +
31678 + mode =
31679 + gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
31680 + old_mnt);
31681 +
31682 + if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
31683 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
31684 + return mode;
31685 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
31686 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
31687 + return 0;
31688 + } else if (unlikely((mode & needmode) != needmode))
31689 + return 0;
31690 +
31691 + return 1;
31692 +}
31693 +
31694 +__u32
31695 +gr_acl_handle_symlink(const struct dentry * new_dentry,
31696 + const struct dentry * parent_dentry,
31697 + const struct vfsmount * parent_mnt, const char *from)
31698 +{
31699 + __u32 needmode = GR_WRITE | GR_CREATE;
31700 + __u32 mode;
31701 +
31702 + mode =
31703 + gr_check_create(new_dentry, parent_dentry, parent_mnt,
31704 + GR_CREATE | GR_AUDIT_CREATE |
31705 + GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
31706 +
31707 + if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
31708 + gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
31709 + return mode;
31710 + } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
31711 + gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
31712 + return 0;
31713 + } else if (unlikely((mode & needmode) != needmode))
31714 + return 0;
31715 +
31716 + return (GR_WRITE | GR_CREATE);
31717 +}
31718 +
31719 +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)
31720 +{
31721 + __u32 mode;
31722 +
31723 + mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
31724 +
31725 + if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
31726 + gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
31727 + return mode;
31728 + } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
31729 + gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
31730 + return 0;
31731 + } else if (unlikely((mode & (reqmode)) != (reqmode)))
31732 + return 0;
31733 +
31734 + return (reqmode);
31735 +}
31736 +
31737 +__u32
31738 +gr_acl_handle_mknod(const struct dentry * new_dentry,
31739 + const struct dentry * parent_dentry,
31740 + const struct vfsmount * parent_mnt,
31741 + const int mode)
31742 +{
31743 + __u32 reqmode = GR_WRITE | GR_CREATE;
31744 + if (unlikely(mode & (S_ISUID | S_ISGID)))
31745 + reqmode |= GR_SETID;
31746 +
31747 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
31748 + reqmode, GR_MKNOD_ACL_MSG);
31749 +}
31750 +
31751 +__u32
31752 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
31753 + const struct dentry *parent_dentry,
31754 + const struct vfsmount *parent_mnt)
31755 +{
31756 + return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
31757 + GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
31758 +}
31759 +
31760 +#define RENAME_CHECK_SUCCESS(old, new) \
31761 + (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
31762 + ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
31763 +
31764 +int
31765 +gr_acl_handle_rename(struct dentry *new_dentry,
31766 + struct dentry *parent_dentry,
31767 + const struct vfsmount *parent_mnt,
31768 + struct dentry *old_dentry,
31769 + struct inode *old_parent_inode,
31770 + struct vfsmount *old_mnt, const char *newname)
31771 +{
31772 + __u32 comp1, comp2;
31773 + int error = 0;
31774 +
31775 + if (unlikely(!gr_acl_is_enabled()))
31776 + return 0;
31777 +
31778 + if (!new_dentry->d_inode) {
31779 + comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
31780 + GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
31781 + GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
31782 + comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
31783 + GR_DELETE | GR_AUDIT_DELETE |
31784 + GR_AUDIT_READ | GR_AUDIT_WRITE |
31785 + GR_SUPPRESS, old_mnt);
31786 + } else {
31787 + comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
31788 + GR_CREATE | GR_DELETE |
31789 + GR_AUDIT_CREATE | GR_AUDIT_DELETE |
31790 + GR_AUDIT_READ | GR_AUDIT_WRITE |
31791 + GR_SUPPRESS, parent_mnt);
31792 + comp2 =
31793 + gr_search_file(old_dentry,
31794 + GR_READ | GR_WRITE | GR_AUDIT_READ |
31795 + GR_DELETE | GR_AUDIT_DELETE |
31796 + GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
31797 + }
31798 +
31799 + if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
31800 + ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
31801 + gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
31802 + else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
31803 + && !(comp2 & GR_SUPPRESS)) {
31804 + gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
31805 + error = -EACCES;
31806 + } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
31807 + error = -EACCES;
31808 +
31809 + return error;
31810 +}
31811 +
31812 +void
31813 +gr_acl_handle_exit(void)
31814 +{
31815 + u16 id;
31816 + char *rolename;
31817 + struct file *exec_file;
31818 +
31819 + if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
31820 + id = current->acl_role_id;
31821 + rolename = current->role->rolename;
31822 + gr_set_acls(1);
31823 + gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
31824 + }
31825 +
31826 + write_lock(&grsec_exec_file_lock);
31827 + exec_file = current->exec_file;
31828 + current->exec_file = NULL;
31829 + write_unlock(&grsec_exec_file_lock);
31830 +
31831 + if (exec_file)
31832 + fput(exec_file);
31833 +}
31834 +
31835 +int
31836 +gr_acl_handle_procpidmem(const struct task_struct *task)
31837 +{
31838 + if (unlikely(!gr_acl_is_enabled()))
31839 + return 0;
31840 +
31841 + if (task != current && task->acl->mode & GR_PROTPROCFD)
31842 + return -EACCES;
31843 +
31844 + return 0;
31845 +}
31846 diff -urNp linux-2.6.31.1/grsecurity/gracl_ip.c linux-2.6.31.1/grsecurity/gracl_ip.c
31847 --- linux-2.6.31.1/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
31848 +++ linux-2.6.31.1/grsecurity/gracl_ip.c 2009-10-01 20:12:44.000000000 -0400
31849 @@ -0,0 +1,340 @@
31850 +#include <linux/kernel.h>
31851 +#include <asm/uaccess.h>
31852 +#include <asm/errno.h>
31853 +#include <net/sock.h>
31854 +#include <linux/file.h>
31855 +#include <linux/fs.h>
31856 +#include <linux/net.h>
31857 +#include <linux/in.h>
31858 +#include <linux/skbuff.h>
31859 +#include <linux/ip.h>
31860 +#include <linux/udp.h>
31861 +#include <linux/smp_lock.h>
31862 +#include <linux/types.h>
31863 +#include <linux/sched.h>
31864 +#include <linux/netdevice.h>
31865 +#include <linux/inetdevice.h>
31866 +#include <linux/gracl.h>
31867 +#include <linux/grsecurity.h>
31868 +#include <linux/grinternal.h>
31869 +
31870 +#define GR_BIND 0x01
31871 +#define GR_CONNECT 0x02
31872 +#define GR_INVERT 0x04
31873 +#define GR_BINDOVERRIDE 0x08
31874 +#define GR_CONNECTOVERRIDE 0x10
31875 +
31876 +static const char * gr_protocols[256] = {
31877 + "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
31878 + "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
31879 + "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
31880 + "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
31881 + "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
31882 + "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
31883 + "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
31884 + "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
31885 + "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
31886 + "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
31887 + "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
31888 + "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
31889 + "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
31890 + "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
31891 + "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
31892 + "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
31893 + "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
31894 + "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
31895 + "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
31896 + "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
31897 + "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
31898 + "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
31899 + "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
31900 + "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
31901 + "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
31902 + "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
31903 + "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
31904 + "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
31905 + "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
31906 + "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
31907 + "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
31908 + "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
31909 + };
31910 +
31911 +static const char * gr_socktypes[11] = {
31912 + "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
31913 + "unknown:7", "unknown:8", "unknown:9", "packet"
31914 + };
31915 +
31916 +const char *
31917 +gr_proto_to_name(unsigned char proto)
31918 +{
31919 + return gr_protocols[proto];
31920 +}
31921 +
31922 +const char *
31923 +gr_socktype_to_name(unsigned char type)
31924 +{
31925 + return gr_socktypes[type];
31926 +}
31927 +
31928 +int
31929 +gr_search_socket(const int domain, const int type, const int protocol)
31930 +{
31931 + struct acl_subject_label *curr;
31932 + const struct cred *cred = current_cred();
31933 +
31934 + if (unlikely(!gr_acl_is_enabled()))
31935 + goto exit;
31936 +
31937 + if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
31938 + || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
31939 + goto exit; // let the kernel handle it
31940 +
31941 + curr = current->acl;
31942 +
31943 + if (!curr->ips)
31944 + goto exit;
31945 +
31946 + if ((curr->ip_type & (1 << type)) &&
31947 + (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
31948 + goto exit;
31949 +
31950 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
31951 + /* we don't place acls on raw sockets , and sometimes
31952 + dgram/ip sockets are opened for ioctl and not
31953 + bind/connect, so we'll fake a bind learn log */
31954 + if (type == SOCK_RAW || type == SOCK_PACKET) {
31955 + __u32 fakeip = 0;
31956 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
31957 + current->role->roletype, cred->uid,
31958 + cred->gid, current->exec_file ?
31959 + gr_to_filename(current->exec_file->f_path.dentry,
31960 + current->exec_file->f_path.mnt) :
31961 + curr->filename, curr->filename,
31962 + NIPQUAD(fakeip), 0, type,
31963 + protocol, GR_CONNECT,
31964 +NIPQUAD(current->signal->curr_ip));
31965 + } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
31966 + __u32 fakeip = 0;
31967 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
31968 + current->role->roletype, cred->uid,
31969 + cred->gid, current->exec_file ?
31970 + gr_to_filename(current->exec_file->f_path.dentry,
31971 + current->exec_file->f_path.mnt) :
31972 + curr->filename, curr->filename,
31973 + NIPQUAD(fakeip), 0, type,
31974 + protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
31975 + }
31976 + /* we'll log when they use connect or bind */
31977 + goto exit;
31978 + }
31979 +
31980 + gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
31981 + gr_socktype_to_name(type), gr_proto_to_name(protocol));
31982 +
31983 + return 0;
31984 + exit:
31985 + return 1;
31986 +}
31987 +
31988 +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)
31989 +{
31990 + if ((ip->mode & mode) &&
31991 + (ip_port >= ip->low) &&
31992 + (ip_port <= ip->high) &&
31993 + ((ntohl(ip_addr) & our_netmask) ==
31994 + (ntohl(our_addr) & our_netmask))
31995 + && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
31996 + && (ip->type & (1 << type))) {
31997 + if (ip->mode & GR_INVERT)
31998 + return 2; // specifically denied
31999 + else
32000 + return 1; // allowed
32001 + }
32002 +
32003 + return 0; // not specifically allowed, may continue parsing
32004 +}
32005 +
32006 +static int
32007 +gr_search_connectbind(const int full_mode, struct sock *sk,
32008 + struct sockaddr_in *addr, const int type)
32009 +{
32010 + char iface[IFNAMSIZ] = {0};
32011 + struct acl_subject_label *curr;
32012 + struct acl_ip_label *ip;
32013 + struct inet_sock *isk;
32014 + struct net_device *dev;
32015 + struct in_device *idev;
32016 + unsigned long i;
32017 + int ret;
32018 + int mode = full_mode & (GR_BIND | GR_CONNECT);
32019 + __u32 ip_addr = 0;
32020 + __u32 our_addr;
32021 + __u32 our_netmask;
32022 + char *p;
32023 + __u16 ip_port = 0;
32024 + const struct cred *cred = current_cred();
32025 +
32026 + if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
32027 + return 0;
32028 +
32029 + curr = current->acl;
32030 + isk = inet_sk(sk);
32031 +
32032 + /* INADDR_ANY overriding for binds, inaddr_any_override is already in network order */
32033 + if ((full_mode & GR_BINDOVERRIDE) && addr->sin_addr.s_addr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0)
32034 + addr->sin_addr.s_addr = curr->inaddr_any_override;
32035 + if ((full_mode & GR_CONNECT) && isk->saddr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0) {
32036 + struct sockaddr_in saddr;
32037 + int err;
32038 +
32039 + saddr.sin_family = AF_INET;
32040 + saddr.sin_addr.s_addr = curr->inaddr_any_override;
32041 + saddr.sin_port = isk->sport;
32042 +
32043 + err = security_socket_bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
32044 + if (err)
32045 + return err;
32046 +
32047 + err = sk->sk_socket->ops->bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
32048 + if (err)
32049 + return err;
32050 + }
32051 +
32052 + if (!curr->ips)
32053 + return 0;
32054 +
32055 + ip_addr = addr->sin_addr.s_addr;
32056 + ip_port = ntohs(addr->sin_port);
32057 +
32058 + if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
32059 + security_learn(GR_IP_LEARN_MSG, current->role->rolename,
32060 + current->role->roletype, cred->uid,
32061 + cred->gid, current->exec_file ?
32062 + gr_to_filename(current->exec_file->f_path.dentry,
32063 + current->exec_file->f_path.mnt) :
32064 + curr->filename, curr->filename,
32065 + NIPQUAD(ip_addr), ip_port, type,
32066 + sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
32067 + return 0;
32068 + }
32069 +
32070 + for (i = 0; i < curr->ip_num; i++) {
32071 + ip = *(curr->ips + i);
32072 + if (ip->iface != NULL) {
32073 + strncpy(iface, ip->iface, IFNAMSIZ - 1);
32074 + p = strchr(iface, ':');
32075 + if (p != NULL)
32076 + *p = '\0';
32077 + dev = dev_get_by_name(sock_net(sk), iface);
32078 + if (dev == NULL)
32079 + continue;
32080 + idev = in_dev_get(dev);
32081 + if (idev == NULL) {
32082 + dev_put(dev);
32083 + continue;
32084 + }
32085 + rcu_read_lock();
32086 + for_ifa(idev) {
32087 + if (!strcmp(ip->iface, ifa->ifa_label)) {
32088 + our_addr = ifa->ifa_address;
32089 + our_netmask = 0xffffffff;
32090 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
32091 + if (ret == 1) {
32092 + rcu_read_unlock();
32093 + in_dev_put(idev);
32094 + dev_put(dev);
32095 + return 0;
32096 + } else if (ret == 2) {
32097 + rcu_read_unlock();
32098 + in_dev_put(idev);
32099 + dev_put(dev);
32100 + goto denied;
32101 + }
32102 + }
32103 + } endfor_ifa(idev);
32104 + rcu_read_unlock();
32105 + in_dev_put(idev);
32106 + dev_put(dev);
32107 + } else {
32108 + our_addr = ip->addr;
32109 + our_netmask = ip->netmask;
32110 + ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
32111 + if (ret == 1)
32112 + return 0;
32113 + else if (ret == 2)
32114 + goto denied;
32115 + }
32116 + }
32117 +
32118 +denied:
32119 + if (mode == GR_BIND)
32120 + 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));
32121 + else if (mode == GR_CONNECT)
32122 + 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));
32123 +
32124 + return -EACCES;
32125 +}
32126 +
32127 +int
32128 +gr_search_connect(struct socket *sock, struct sockaddr_in *addr)
32129 +{
32130 + return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sock->sk, addr, sock->type);
32131 +}
32132 +
32133 +int
32134 +gr_search_bind(struct socket *sock, struct sockaddr_in *addr)
32135 +{
32136 + return gr_search_connectbind(GR_BIND | GR_BINDOVERRIDE, sock->sk, addr, sock->type);
32137 +}
32138 +
32139 +int gr_search_listen(struct socket *sock)
32140 +{
32141 + struct sock *sk = sock->sk;
32142 + struct sockaddr_in addr;
32143 +
32144 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
32145 + addr.sin_port = inet_sk(sk)->sport;
32146 +
32147 + return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
32148 +}
32149 +
32150 +int gr_search_accept(struct socket *sock)
32151 +{
32152 + struct sock *sk = sock->sk;
32153 + struct sockaddr_in addr;
32154 +
32155 + addr.sin_addr.s_addr = inet_sk(sk)->saddr;
32156 + addr.sin_port = inet_sk(sk)->sport;
32157 +
32158 + return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
32159 +}
32160 +
32161 +int
32162 +gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr)
32163 +{
32164 + if (addr)
32165 + return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
32166 + else {
32167 + struct sockaddr_in sin;
32168 + const struct inet_sock *inet = inet_sk(sk);
32169 +
32170 + sin.sin_addr.s_addr = inet->daddr;
32171 + sin.sin_port = inet->dport;
32172 +
32173 + return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
32174 + }
32175 +}
32176 +
32177 +int
32178 +gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb)
32179 +{
32180 + struct sockaddr_in sin;
32181 +
32182 + if (unlikely(skb->len < sizeof (struct udphdr)))
32183 + return 0; // skip this packet
32184 +
32185 + sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
32186 + sin.sin_port = udp_hdr(skb)->source;
32187 +
32188 + return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
32189 +}
32190 diff -urNp linux-2.6.31.1/grsecurity/gracl_learn.c linux-2.6.31.1/grsecurity/gracl_learn.c
32191 --- linux-2.6.31.1/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
32192 +++ linux-2.6.31.1/grsecurity/gracl_learn.c 2009-10-01 20:12:44.000000000 -0400
32193 @@ -0,0 +1,211 @@
32194 +#include <linux/kernel.h>
32195 +#include <linux/mm.h>
32196 +#include <linux/sched.h>
32197 +#include <linux/poll.h>
32198 +#include <linux/smp_lock.h>
32199 +#include <linux/string.h>
32200 +#include <linux/file.h>
32201 +#include <linux/types.h>
32202 +#include <linux/vmalloc.h>
32203 +#include <linux/grinternal.h>
32204 +
32205 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
32206 + size_t count, loff_t *ppos);
32207 +extern int gr_acl_is_enabled(void);
32208 +
32209 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
32210 +static int gr_learn_attached;
32211 +
32212 +/* use a 512k buffer */
32213 +#define LEARN_BUFFER_SIZE (512 * 1024)
32214 +
32215 +static DEFINE_SPINLOCK(gr_learn_lock);
32216 +static DECLARE_MUTEX(gr_learn_user_sem);
32217 +
32218 +/* we need to maintain two buffers, so that the kernel context of grlearn
32219 + uses a semaphore around the userspace copying, and the other kernel contexts
32220 + use a spinlock when copying into the buffer, since they cannot sleep
32221 +*/
32222 +static char *learn_buffer;
32223 +static char *learn_buffer_user;
32224 +static int learn_buffer_len;
32225 +static int learn_buffer_user_len;
32226 +
32227 +static ssize_t
32228 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
32229 +{
32230 + DECLARE_WAITQUEUE(wait, current);
32231 + ssize_t retval = 0;
32232 +
32233 + add_wait_queue(&learn_wait, &wait);
32234 + set_current_state(TASK_INTERRUPTIBLE);
32235 + do {
32236 + down(&gr_learn_user_sem);
32237 + spin_lock(&gr_learn_lock);
32238 + if (learn_buffer_len)
32239 + break;
32240 + spin_unlock(&gr_learn_lock);
32241 + up(&gr_learn_user_sem);
32242 + if (file->f_flags & O_NONBLOCK) {
32243 + retval = -EAGAIN;
32244 + goto out;
32245 + }
32246 + if (signal_pending(current)) {
32247 + retval = -ERESTARTSYS;
32248 + goto out;
32249 + }
32250 +
32251 + schedule();
32252 + } while (1);
32253 +
32254 + memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
32255 + learn_buffer_user_len = learn_buffer_len;
32256 + retval = learn_buffer_len;
32257 + learn_buffer_len = 0;
32258 +
32259 + spin_unlock(&gr_learn_lock);
32260 +
32261 + if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
32262 + retval = -EFAULT;
32263 +
32264 + up(&gr_learn_user_sem);
32265 +out:
32266 + set_current_state(TASK_RUNNING);
32267 + remove_wait_queue(&learn_wait, &wait);
32268 + return retval;
32269 +}
32270 +
32271 +static unsigned int
32272 +poll_learn(struct file * file, poll_table * wait)
32273 +{
32274 + poll_wait(file, &learn_wait, wait);
32275 +
32276 + if (learn_buffer_len)
32277 + return (POLLIN | POLLRDNORM);
32278 +
32279 + return 0;
32280 +}
32281 +
32282 +void
32283 +gr_clear_learn_entries(void)
32284 +{
32285 + char *tmp;
32286 +
32287 + down(&gr_learn_user_sem);
32288 + if (learn_buffer != NULL) {
32289 + spin_lock(&gr_learn_lock);
32290 + tmp = learn_buffer;
32291 + learn_buffer = NULL;
32292 + spin_unlock(&gr_learn_lock);
32293 + vfree(learn_buffer);
32294 + }
32295 + if (learn_buffer_user != NULL) {
32296 + vfree(learn_buffer_user);
32297 + learn_buffer_user = NULL;
32298 + }
32299 + learn_buffer_len = 0;
32300 + up(&gr_learn_user_sem);
32301 +
32302 + return;
32303 +}
32304 +
32305 +void
32306 +gr_add_learn_entry(const char *fmt, ...)
32307 +{
32308 + va_list args;
32309 + unsigned int len;
32310 +
32311 + if (!gr_learn_attached)
32312 + return;
32313 +
32314 + spin_lock(&gr_learn_lock);
32315 +
32316 + /* leave a gap at the end so we know when it's "full" but don't have to
32317 + compute the exact length of the string we're trying to append
32318 + */
32319 + if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
32320 + spin_unlock(&gr_learn_lock);
32321 + wake_up_interruptible(&learn_wait);
32322 + return;
32323 + }
32324 + if (learn_buffer == NULL) {
32325 + spin_unlock(&gr_learn_lock);
32326 + return;
32327 + }
32328 +
32329 + va_start(args, fmt);
32330 + len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
32331 + va_end(args);
32332 +
32333 + learn_buffer_len += len + 1;
32334 +
32335 + spin_unlock(&gr_learn_lock);
32336 + wake_up_interruptible(&learn_wait);
32337 +
32338 + return;
32339 +}
32340 +
32341 +static int
32342 +open_learn(struct inode *inode, struct file *file)
32343 +{
32344 + if (file->f_mode & FMODE_READ && gr_learn_attached)
32345 + return -EBUSY;
32346 + if (file->f_mode & FMODE_READ) {
32347 + int retval = 0;
32348 + down(&gr_learn_user_sem);
32349 + if (learn_buffer == NULL)
32350 + learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
32351 + if (learn_buffer_user == NULL)
32352 + learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
32353 + if (learn_buffer == NULL) {
32354 + retval = -ENOMEM;
32355 + goto out_error;
32356 + }
32357 + if (learn_buffer_user == NULL) {
32358 + retval = -ENOMEM;
32359 + goto out_error;
32360 + }
32361 + learn_buffer_len = 0;
32362 + learn_buffer_user_len = 0;
32363 + gr_learn_attached = 1;
32364 +out_error:
32365 + up(&gr_learn_user_sem);
32366 + return retval;
32367 + }
32368 + return 0;
32369 +}
32370 +
32371 +static int
32372 +close_learn(struct inode *inode, struct file *file)
32373 +{
32374 + char *tmp;
32375 +
32376 + if (file->f_mode & FMODE_READ) {
32377 + down(&gr_learn_user_sem);
32378 + if (learn_buffer != NULL) {
32379 + spin_lock(&gr_learn_lock);
32380 + tmp = learn_buffer;
32381 + learn_buffer = NULL;
32382 + spin_unlock(&gr_learn_lock);
32383 + vfree(tmp);
32384 + }
32385 + if (learn_buffer_user != NULL) {
32386 + vfree(learn_buffer_user);
32387 + learn_buffer_user = NULL;
32388 + }
32389 + learn_buffer_len = 0;
32390 + learn_buffer_user_len = 0;
32391 + gr_learn_attached = 0;
32392 + up(&gr_learn_user_sem);
32393 + }
32394 +
32395 + return 0;
32396 +}
32397 +
32398 +const struct file_operations grsec_fops = {
32399 + .read = read_learn,
32400 + .write = write_grsec_handler,
32401 + .open = open_learn,
32402 + .release = close_learn,
32403 + .poll = poll_learn,
32404 +};
32405 diff -urNp linux-2.6.31.1/grsecurity/gracl_res.c linux-2.6.31.1/grsecurity/gracl_res.c
32406 --- linux-2.6.31.1/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
32407 +++ linux-2.6.31.1/grsecurity/gracl_res.c 2009-10-01 20:12:44.000000000 -0400
32408 @@ -0,0 +1,58 @@
32409 +#include <linux/kernel.h>
32410 +#include <linux/sched.h>
32411 +#include <linux/gracl.h>
32412 +#include <linux/grinternal.h>
32413 +
32414 +static const char *restab_log[] = {
32415 + [RLIMIT_CPU] = "RLIMIT_CPU",
32416 + [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
32417 + [RLIMIT_DATA] = "RLIMIT_DATA",
32418 + [RLIMIT_STACK] = "RLIMIT_STACK",
32419 + [RLIMIT_CORE] = "RLIMIT_CORE",
32420 + [RLIMIT_RSS] = "RLIMIT_RSS",
32421 + [RLIMIT_NPROC] = "RLIMIT_NPROC",
32422 + [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
32423 + [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
32424 + [RLIMIT_AS] = "RLIMIT_AS",
32425 + [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
32426 + [RLIMIT_SIGPENDING] = "RLIMIT_SIGPENDING",
32427 + [RLIMIT_MSGQUEUE] = "RLIMIT_MSGQUEUE",
32428 + [RLIMIT_NICE] = "RLIMIT_NICE",
32429 + [RLIMIT_RTPRIO] = "RLIMIT_RTPRIO",
32430 + [RLIMIT_RTTIME] = "RLIMIT_RTTIME",
32431 + [GR_CRASH_RES] = "RLIMIT_CRASH"
32432 +};
32433 +
32434 +void
32435 +gr_log_resource(const struct task_struct *task,
32436 + const int res, const unsigned long wanted, const int gt)
32437 +{
32438 + const struct cred *cred = __task_cred(task);
32439 +
32440 + if (res == RLIMIT_NPROC &&
32441 + (cap_raised(cred->cap_effective, CAP_SYS_ADMIN) ||
32442 + cap_raised(cred->cap_effective, CAP_SYS_RESOURCE)))
32443 + return;
32444 + else if (res == RLIMIT_MEMLOCK &&
32445 + cap_raised(cred->cap_effective, CAP_IPC_LOCK))
32446 + return;
32447 + else if (res == RLIMIT_NICE && cap_raised(cred->cap_effective, CAP_SYS_NICE))
32448 + return;
32449 +
32450 + if (!gr_acl_is_enabled() && !grsec_resource_logging)
32451 + return;
32452 +
32453 + // not yet supported resource
32454 + if (!restab_log[res])
32455 + return;
32456 +
32457 + preempt_disable();
32458 +
32459 + if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
32460 + (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
32461 + task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
32462 + gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
32463 + preempt_enable_no_resched();
32464 +
32465 + return;
32466 +}
32467 diff -urNp linux-2.6.31.1/grsecurity/gracl_segv.c linux-2.6.31.1/grsecurity/gracl_segv.c
32468 --- linux-2.6.31.1/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
32469 +++ linux-2.6.31.1/grsecurity/gracl_segv.c 2009-10-01 20:12:44.000000000 -0400
32470 @@ -0,0 +1,307 @@
32471 +#include <linux/kernel.h>
32472 +#include <linux/mm.h>
32473 +#include <asm/uaccess.h>
32474 +#include <asm/errno.h>
32475 +#include <asm/mman.h>
32476 +#include <net/sock.h>
32477 +#include <linux/file.h>
32478 +#include <linux/fs.h>
32479 +#include <linux/net.h>
32480 +#include <linux/in.h>
32481 +#include <linux/smp_lock.h>
32482 +#include <linux/slab.h>
32483 +#include <linux/types.h>
32484 +#include <linux/sched.h>
32485 +#include <linux/timer.h>
32486 +#include <linux/gracl.h>
32487 +#include <linux/grsecurity.h>
32488 +#include <linux/grinternal.h>
32489 +
32490 +static struct crash_uid *uid_set;
32491 +static unsigned short uid_used;
32492 +static DEFINE_SPINLOCK(gr_uid_lock);
32493 +extern rwlock_t gr_inode_lock;
32494 +extern struct acl_subject_label *
32495 + lookup_acl_subj_label(const ino_t inode, const dev_t dev,
32496 + struct acl_role_label *role);
32497 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
32498 +
32499 +int
32500 +gr_init_uidset(void)
32501 +{
32502 + uid_set =
32503 + kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
32504 + uid_used = 0;
32505 +
32506 + return uid_set ? 1 : 0;
32507 +}
32508 +
32509 +void
32510 +gr_free_uidset(void)
32511 +{
32512 + if (uid_set)
32513 + kfree(uid_set);
32514 +
32515 + return;
32516 +}
32517 +
32518 +int
32519 +gr_find_uid(const uid_t uid)
32520 +{
32521 + struct crash_uid *tmp = uid_set;
32522 + uid_t buid;
32523 + int low = 0, high = uid_used - 1, mid;
32524 +
32525 + while (high >= low) {
32526 + mid = (low + high) >> 1;
32527 + buid = tmp[mid].uid;
32528 + if (buid == uid)
32529 + return mid;
32530 + if (buid > uid)
32531 + high = mid - 1;
32532 + if (buid < uid)
32533 + low = mid + 1;
32534 + }
32535 +
32536 + return -1;
32537 +}
32538 +
32539 +static __inline__ void
32540 +gr_insertsort(void)
32541 +{
32542 + unsigned short i, j;
32543 + struct crash_uid index;
32544 +
32545 + for (i = 1; i < uid_used; i++) {
32546 + index = uid_set[i];
32547 + j = i;
32548 + while ((j > 0) && uid_set[j - 1].uid > index.uid) {
32549 + uid_set[j] = uid_set[j - 1];
32550 + j--;
32551 + }
32552 + uid_set[j] = index;
32553 + }
32554 +
32555 + return;
32556 +}
32557 +
32558 +static __inline__ void
32559 +gr_insert_uid(const uid_t uid, const unsigned long expires)
32560 +{
32561 + int loc;
32562 +
32563 + if (uid_used == GR_UIDTABLE_MAX)
32564 + return;
32565 +
32566 + loc = gr_find_uid(uid);
32567 +
32568 + if (loc >= 0) {
32569 + uid_set[loc].expires = expires;
32570 + return;
32571 + }
32572 +
32573 + uid_set[uid_used].uid = uid;
32574 + uid_set[uid_used].expires = expires;
32575 + uid_used++;
32576 +
32577 + gr_insertsort();
32578 +
32579 + return;
32580 +}
32581 +
32582 +void
32583 +gr_remove_uid(const unsigned short loc)
32584 +{
32585 + unsigned short i;
32586 +
32587 + for (i = loc + 1; i < uid_used; i++)
32588 + uid_set[i - 1] = uid_set[i];
32589 +
32590 + uid_used--;
32591 +
32592 + return;
32593 +}
32594 +
32595 +int
32596 +gr_check_crash_uid(const uid_t uid)
32597 +{
32598 + int loc;
32599 + int ret = 0;
32600 +
32601 + if (unlikely(!gr_acl_is_enabled()))
32602 + return 0;
32603 +
32604 + spin_lock(&gr_uid_lock);
32605 + loc = gr_find_uid(uid);
32606 +
32607 + if (loc < 0)
32608 + goto out_unlock;
32609 +
32610 + if (time_before_eq(uid_set[loc].expires, get_seconds()))
32611 + gr_remove_uid(loc);
32612 + else
32613 + ret = 1;
32614 +
32615 +out_unlock:
32616 + spin_unlock(&gr_uid_lock);
32617 + return ret;
32618 +}
32619 +
32620 +static __inline__ int
32621 +proc_is_setxid(const struct cred *cred)
32622 +{
32623 + if (cred->uid != cred->euid || cred->uid != cred->suid ||
32624 + cred->uid != cred->fsuid)
32625 + return 1;
32626 + if (cred->gid != cred->egid || cred->gid != cred->sgid ||
32627 + cred->gid != cred->fsgid)
32628 + return 1;
32629 +
32630 + return 0;
32631 +}
32632 +static __inline__ int
32633 +gr_fake_force_sig(int sig, struct task_struct *t)
32634 +{
32635 + unsigned long int flags;
32636 + int ret, blocked, ignored;
32637 + struct k_sigaction *action;
32638 +
32639 + spin_lock_irqsave(&t->sighand->siglock, flags);
32640 + action = &t->sighand->action[sig-1];
32641 + ignored = action->sa.sa_handler == SIG_IGN;
32642 + blocked = sigismember(&t->blocked, sig);
32643 + if (blocked || ignored) {
32644 + action->sa.sa_handler = SIG_DFL;
32645 + if (blocked) {
32646 + sigdelset(&t->blocked, sig);
32647 + recalc_sigpending_and_wake(t);
32648 + }
32649 + }
32650 + if (action->sa.sa_handler == SIG_DFL)
32651 + t->signal->flags &= ~SIGNAL_UNKILLABLE;
32652 + ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
32653 +
32654 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
32655 +
32656 + return ret;
32657 +}
32658 +
32659 +void
32660 +gr_handle_crash(struct task_struct *task, const int sig)
32661 +{
32662 + struct acl_subject_label *curr;
32663 + struct acl_subject_label *curr2;
32664 + struct task_struct *tsk, *tsk2;
32665 + const struct cred *cred = __task_cred(task);
32666 + const struct cred *cred2;
32667 +
32668 + if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
32669 + return;
32670 +
32671 + if (unlikely(!gr_acl_is_enabled()))
32672 + return;
32673 +
32674 + curr = task->acl;
32675 +
32676 + if (!(curr->resmask & (1 << GR_CRASH_RES)))
32677 + return;
32678 +
32679 + if (time_before_eq(curr->expires, get_seconds())) {
32680 + curr->expires = 0;
32681 + curr->crashes = 0;
32682 + }
32683 +
32684 + curr->crashes++;
32685 +
32686 + if (!curr->expires)
32687 + curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
32688 +
32689 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
32690 + time_after(curr->expires, get_seconds())) {
32691 + if (cred->uid && proc_is_setxid(cred)) {
32692 + gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
32693 + spin_lock(&gr_uid_lock);
32694 + gr_insert_uid(cred->uid, curr->expires);
32695 + spin_unlock(&gr_uid_lock);
32696 + curr->expires = 0;
32697 + curr->crashes = 0;
32698 + read_lock(&tasklist_lock);
32699 + do_each_thread(tsk2, tsk) {
32700 + cred2 = __task_cred(tsk);
32701 + if (tsk != task && cred2->uid == cred->uid)
32702 + gr_fake_force_sig(SIGKILL, tsk);
32703 + } while_each_thread(tsk2, tsk);
32704 + read_unlock(&tasklist_lock);
32705 + } else {
32706 + gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
32707 + read_lock(&tasklist_lock);
32708 + do_each_thread(tsk2, tsk) {
32709 + if (likely(tsk != task)) {
32710 + curr2 = tsk->acl;
32711 +
32712 + if (curr2->device == curr->device &&
32713 + curr2->inode == curr->inode)
32714 + gr_fake_force_sig(SIGKILL, tsk);
32715 + }
32716 + } while_each_thread(tsk2, tsk);
32717 + read_unlock(&tasklist_lock);
32718 + }
32719 + }
32720 +
32721 + return;
32722 +}
32723 +
32724 +int
32725 +gr_check_crash_exec(const struct file *filp)
32726 +{
32727 + struct acl_subject_label *curr;
32728 +
32729 + if (unlikely(!gr_acl_is_enabled()))
32730 + return 0;
32731 +
32732 + read_lock(&gr_inode_lock);
32733 + curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
32734 + filp->f_path.dentry->d_inode->i_sb->s_dev,
32735 + current->role);
32736 + read_unlock(&gr_inode_lock);
32737 +
32738 + if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
32739 + (!curr->crashes && !curr->expires))
32740 + return 0;
32741 +
32742 + if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
32743 + time_after(curr->expires, get_seconds()))
32744 + return 1;
32745 + else if (time_before_eq(curr->expires, get_seconds())) {
32746 + curr->crashes = 0;
32747 + curr->expires = 0;
32748 + }
32749 +
32750 + return 0;
32751 +}
32752 +
32753 +void
32754 +gr_handle_alertkill(struct task_struct *task)
32755 +{
32756 + struct acl_subject_label *curracl;
32757 + __u32 curr_ip;
32758 + struct task_struct *p, *p2;
32759 +
32760 + if (unlikely(!gr_acl_is_enabled()))
32761 + return;
32762 +
32763 + curracl = task->acl;
32764 + curr_ip = task->signal->curr_ip;
32765 +
32766 + if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
32767 + read_lock(&tasklist_lock);
32768 + do_each_thread(p2, p) {
32769 + if (p->signal->curr_ip == curr_ip)
32770 + gr_fake_force_sig(SIGKILL, p);
32771 + } while_each_thread(p2, p);
32772 + read_unlock(&tasklist_lock);
32773 + } else if (curracl->mode & GR_KILLPROC)
32774 + gr_fake_force_sig(SIGKILL, task);
32775 +
32776 + return;
32777 +}
32778 diff -urNp linux-2.6.31.1/grsecurity/gracl_shm.c linux-2.6.31.1/grsecurity/gracl_shm.c
32779 --- linux-2.6.31.1/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
32780 +++ linux-2.6.31.1/grsecurity/gracl_shm.c 2009-10-01 20:12:44.000000000 -0400
32781 @@ -0,0 +1,37 @@
32782 +#include <linux/kernel.h>
32783 +#include <linux/mm.h>
32784 +#include <linux/sched.h>
32785 +#include <linux/file.h>
32786 +#include <linux/ipc.h>
32787 +#include <linux/gracl.h>
32788 +#include <linux/grsecurity.h>
32789 +#include <linux/grinternal.h>
32790 +
32791 +int
32792 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
32793 + const time_t shm_createtime, const uid_t cuid, const int shmid)
32794 +{
32795 + struct task_struct *task;
32796 +
32797 + if (!gr_acl_is_enabled())
32798 + return 1;
32799 +
32800 + read_lock(&tasklist_lock);
32801 +
32802 + task = find_task_by_vpid(shm_cprid);
32803 +
32804 + if (unlikely(!task))
32805 + task = find_task_by_vpid(shm_lapid);
32806 +
32807 + if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
32808 + (task->pid == shm_lapid)) &&
32809 + (task->acl->mode & GR_PROTSHM) &&
32810 + (task->acl != current->acl))) {
32811 + read_unlock(&tasklist_lock);
32812 + gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
32813 + return 0;
32814 + }
32815 + read_unlock(&tasklist_lock);
32816 +
32817 + return 1;
32818 +}
32819 diff -urNp linux-2.6.31.1/grsecurity/grsec_chdir.c linux-2.6.31.1/grsecurity/grsec_chdir.c
32820 --- linux-2.6.31.1/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
32821 +++ linux-2.6.31.1/grsecurity/grsec_chdir.c 2009-10-01 20:12:44.000000000 -0400
32822 @@ -0,0 +1,19 @@
32823 +#include <linux/kernel.h>
32824 +#include <linux/sched.h>
32825 +#include <linux/fs.h>
32826 +#include <linux/file.h>
32827 +#include <linux/grsecurity.h>
32828 +#include <linux/grinternal.h>
32829 +
32830 +void
32831 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
32832 +{
32833 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
32834 + if ((grsec_enable_chdir && grsec_enable_group &&
32835 + in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
32836 + !grsec_enable_group)) {
32837 + gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
32838 + }
32839 +#endif
32840 + return;
32841 +}
32842 diff -urNp linux-2.6.31.1/grsecurity/grsec_chroot.c linux-2.6.31.1/grsecurity/grsec_chroot.c
32843 --- linux-2.6.31.1/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
32844 +++ linux-2.6.31.1/grsecurity/grsec_chroot.c 2009-10-01 21:52:18.000000000 -0400
32845 @@ -0,0 +1,348 @@
32846 +#include <linux/kernel.h>
32847 +#include <linux/module.h>
32848 +#include <linux/sched.h>
32849 +#include <linux/file.h>
32850 +#include <linux/fs.h>
32851 +#include <linux/mount.h>
32852 +#include <linux/types.h>
32853 +#include <linux/pid_namespace.h>
32854 +#include <linux/grsecurity.h>
32855 +#include <linux/grinternal.h>
32856 +
32857 +int
32858 +gr_handle_chroot_unix(const pid_t pid)
32859 +{
32860 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
32861 + struct pid *spid = NULL;
32862 +
32863 + if (unlikely(!grsec_enable_chroot_unix))
32864 + return 1;
32865 +
32866 + if (likely(!proc_is_chrooted(current)))
32867 + return 1;
32868 +
32869 + read_lock(&tasklist_lock);
32870 +
32871 + spid = find_vpid(pid);
32872 + if (spid) {
32873 + struct task_struct *p;
32874 + p = pid_task(spid, PIDTYPE_PID);
32875 + task_lock(p);
32876 + if (unlikely(!have_same_root(current, p))) {
32877 + task_unlock(p);
32878 + read_unlock(&tasklist_lock);
32879 + gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
32880 + return 0;
32881 + }
32882 + task_unlock(p);
32883 + }
32884 + read_unlock(&tasklist_lock);
32885 +#endif
32886 + return 1;
32887 +}
32888 +
32889 +int
32890 +gr_handle_chroot_nice(void)
32891 +{
32892 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
32893 + if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
32894 + gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
32895 + return -EPERM;
32896 + }
32897 +#endif
32898 + return 0;
32899 +}
32900 +
32901 +int
32902 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
32903 +{
32904 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
32905 + if (grsec_enable_chroot_nice && (niceval < task_nice(p))
32906 + && proc_is_chrooted(current)) {
32907 + gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
32908 + return -EACCES;
32909 + }
32910 +#endif
32911 + return 0;
32912 +}
32913 +
32914 +int
32915 +gr_handle_chroot_rawio(const struct inode *inode)
32916 +{
32917 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
32918 + if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
32919 + inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
32920 + return 1;
32921 +#endif
32922 + return 0;
32923 +}
32924 +
32925 +int
32926 +gr_pid_is_chrooted(struct task_struct *p)
32927 +{
32928 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
32929 + if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
32930 + return 0;
32931 +
32932 + task_lock(p);
32933 + if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
32934 + !have_same_root(current, p)) {
32935 + task_unlock(p);
32936 + return 1;
32937 + }
32938 + task_unlock(p);
32939 +#endif
32940 + return 0;
32941 +}
32942 +
32943 +EXPORT_SYMBOL(gr_pid_is_chrooted);
32944 +
32945 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
32946 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
32947 +{
32948 + struct dentry *dentry = (struct dentry *)u_dentry;
32949 + struct vfsmount *mnt = (struct vfsmount *)u_mnt;
32950 + struct dentry *realroot;
32951 + struct vfsmount *realrootmnt;
32952 + struct dentry *currentroot;
32953 + struct vfsmount *currentmnt;
32954 + struct task_struct *reaper = &init_task;
32955 + int ret = 1;
32956 +
32957 + read_lock(&reaper->fs->lock);
32958 + realrootmnt = mntget(reaper->fs->root.mnt);
32959 + realroot = dget(reaper->fs->root.dentry);
32960 + read_unlock(&reaper->fs->lock);
32961 +
32962 + read_lock(&current->fs->lock);
32963 + currentmnt = mntget(current->fs->root.mnt);
32964 + currentroot = dget(current->fs->root.dentry);
32965 + read_unlock(&current->fs->lock);
32966 +
32967 + spin_lock(&dcache_lock);
32968 + for (;;) {
32969 + if (unlikely((dentry == realroot && mnt == realrootmnt)
32970 + || (dentry == currentroot && mnt == currentmnt)))
32971 + break;
32972 + if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
32973 + if (mnt->mnt_parent == mnt)
32974 + break;
32975 + dentry = mnt->mnt_mountpoint;
32976 + mnt = mnt->mnt_parent;
32977 + continue;
32978 + }
32979 + dentry = dentry->d_parent;
32980 + }
32981 + spin_unlock(&dcache_lock);
32982 +
32983 + dput(currentroot);
32984 + mntput(currentmnt);
32985 +
32986 + /* access is outside of chroot */
32987 + if (dentry == realroot && mnt == realrootmnt)
32988 + ret = 0;
32989 +
32990 + dput(realroot);
32991 + mntput(realrootmnt);
32992 + return ret;
32993 +}
32994 +#endif
32995 +
32996 +int
32997 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
32998 +{
32999 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
33000 + if (!grsec_enable_chroot_fchdir)
33001 + return 1;
33002 +
33003 + if (!proc_is_chrooted(current))
33004 + return 1;
33005 + else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
33006 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
33007 + return 0;
33008 + }
33009 +#endif
33010 + return 1;
33011 +}
33012 +
33013 +int
33014 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
33015 + const time_t shm_createtime)
33016 +{
33017 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
33018 + struct pid *pid = NULL;
33019 + time_t starttime;
33020 +
33021 + if (unlikely(!grsec_enable_chroot_shmat))
33022 + return 1;
33023 +
33024 + if (likely(!proc_is_chrooted(current)))
33025 + return 1;
33026 +
33027 + read_lock(&tasklist_lock);
33028 +
33029 + pid = find_vpid(shm_cprid);
33030 + if (pid) {
33031 + struct task_struct *p;
33032 + p = pid_task(pid, PIDTYPE_PID);
33033 + task_lock(p);
33034 + starttime = p->start_time.tv_sec;
33035 + if (unlikely(!have_same_root(current, p) &&
33036 + time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
33037 + task_unlock(p);
33038 + read_unlock(&tasklist_lock);
33039 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
33040 + return 0;
33041 + }
33042 + task_unlock(p);
33043 + } else {
33044 + pid = find_vpid(shm_lapid);
33045 + if (pid) {
33046 + struct task_struct *p;
33047 + p = pid_task(pid, PIDTYPE_PID);
33048 + task_lock(p);
33049 + if (unlikely(!have_same_root(current, p))) {
33050 + task_unlock(p);
33051 + read_unlock(&tasklist_lock);
33052 + gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
33053 + return 0;
33054 + }
33055 + task_unlock(p);
33056 + }
33057 + }
33058 +
33059 + read_unlock(&tasklist_lock);
33060 +#endif
33061 + return 1;
33062 +}
33063 +
33064 +void
33065 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
33066 +{
33067 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
33068 + if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
33069 + gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
33070 +#endif
33071 + return;
33072 +}
33073 +
33074 +int
33075 +gr_handle_chroot_mknod(const struct dentry *dentry,
33076 + const struct vfsmount *mnt, const int mode)
33077 +{
33078 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
33079 + if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
33080 + proc_is_chrooted(current)) {
33081 + gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
33082 + return -EPERM;
33083 + }
33084 +#endif
33085 + return 0;
33086 +}
33087 +
33088 +int
33089 +gr_handle_chroot_mount(const struct dentry *dentry,
33090 + const struct vfsmount *mnt, const char *dev_name)
33091 +{
33092 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
33093 + if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
33094 + gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
33095 + return -EPERM;
33096 + }
33097 +#endif
33098 + return 0;
33099 +}
33100 +
33101 +int
33102 +gr_handle_chroot_pivot(void)
33103 +{
33104 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
33105 + if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
33106 + gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
33107 + return -EPERM;
33108 + }
33109 +#endif
33110 + return 0;
33111 +}
33112 +
33113 +int
33114 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
33115 +{
33116 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
33117 + if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
33118 + !gr_is_outside_chroot(dentry, mnt)) {
33119 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
33120 + return -EPERM;
33121 + }
33122 +#endif
33123 + return 0;
33124 +}
33125 +
33126 +int
33127 +gr_handle_chroot_caps(struct path *path)
33128 +{
33129 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
33130 + if (grsec_enable_chroot_caps && current->pid > 1 && current->fs != NULL &&
33131 + (init_task.fs->root.dentry != path->dentry) &&
33132 + (current->nsproxy->mnt_ns->root->mnt_root != path->dentry)) {
33133 +
33134 + kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
33135 + const struct cred *old = current_cred();
33136 + struct cred *new = prepare_creds();
33137 + if (new == NULL)
33138 + return 1;
33139 +
33140 + new->cap_permitted = cap_drop(old->cap_permitted,
33141 + chroot_caps);
33142 + new->cap_inheritable = cap_drop(old->cap_inheritable,
33143 + chroot_caps);
33144 + new->cap_effective = cap_drop(old->cap_effective,
33145 + chroot_caps);
33146 +
33147 + commit_creds(new);
33148 +
33149 + return 0;
33150 + }
33151 +#endif
33152 + return 0;
33153 +}
33154 +
33155 +int
33156 +gr_handle_chroot_sysctl(const int op)
33157 +{
33158 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
33159 + if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
33160 + && (op & MAY_WRITE))
33161 + return -EACCES;
33162 +#endif
33163 + return 0;
33164 +}
33165 +
33166 +void
33167 +gr_handle_chroot_chdir(struct path *path)
33168 +{
33169 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
33170 + if (grsec_enable_chroot_chdir)
33171 + set_fs_pwd(current->fs, path);
33172 +#endif
33173 + return;
33174 +}
33175 +
33176 +int
33177 +gr_handle_chroot_chmod(const struct dentry *dentry,
33178 + const struct vfsmount *mnt, const int mode)
33179 +{
33180 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
33181 + if (grsec_enable_chroot_chmod &&
33182 + ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
33183 + proc_is_chrooted(current)) {
33184 + gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
33185 + return -EPERM;
33186 + }
33187 +#endif
33188 + return 0;
33189 +}
33190 +
33191 +#ifdef CONFIG_SECURITY
33192 +EXPORT_SYMBOL(gr_handle_chroot_caps);
33193 +#endif
33194 diff -urNp linux-2.6.31.1/grsecurity/grsec_disabled.c linux-2.6.31.1/grsecurity/grsec_disabled.c
33195 --- linux-2.6.31.1/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
33196 +++ linux-2.6.31.1/grsecurity/grsec_disabled.c 2009-10-01 20:12:44.000000000 -0400
33197 @@ -0,0 +1,426 @@
33198 +#include <linux/kernel.h>
33199 +#include <linux/module.h>
33200 +#include <linux/sched.h>
33201 +#include <linux/file.h>
33202 +#include <linux/fs.h>
33203 +#include <linux/kdev_t.h>
33204 +#include <linux/net.h>
33205 +#include <linux/in.h>
33206 +#include <linux/ip.h>
33207 +#include <linux/skbuff.h>
33208 +#include <linux/sysctl.h>
33209 +
33210 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
33211 +void
33212 +pax_set_initial_flags(struct linux_binprm *bprm)
33213 +{
33214 + return;
33215 +}
33216 +#endif
33217 +
33218 +#ifdef CONFIG_SYSCTL
33219 +__u32
33220 +gr_handle_sysctl(const struct ctl_table * table, const int op)
33221 +{
33222 + return 0;
33223 +}
33224 +#endif
33225 +
33226 +#ifdef CONFIG_TASKSTATS
33227 +int gr_is_taskstats_denied(int pid)
33228 +{
33229 + return 0;
33230 +}
33231 +#endif
33232 +
33233 +int
33234 +gr_acl_is_enabled(void)
33235 +{
33236 + return 0;
33237 +}
33238 +
33239 +int
33240 +gr_handle_rawio(const struct inode *inode)
33241 +{
33242 + return 0;
33243 +}
33244 +
33245 +void
33246 +gr_acl_handle_psacct(struct task_struct *task, const long code)
33247 +{
33248 + return;
33249 +}
33250 +
33251 +int
33252 +gr_handle_ptrace(struct task_struct *task, const long request)
33253 +{
33254 + return 0;
33255 +}
33256 +
33257 +int
33258 +gr_handle_proc_ptrace(struct task_struct *task)
33259 +{
33260 + return 0;
33261 +}
33262 +
33263 +void
33264 +gr_learn_resource(const struct task_struct *task,
33265 + const int res, const unsigned long wanted, const int gt)
33266 +{
33267 + return;
33268 +}
33269 +
33270 +int
33271 +gr_set_acls(const int type)
33272 +{
33273 + return 0;
33274 +}
33275 +
33276 +int
33277 +gr_check_hidden_task(const struct task_struct *tsk)
33278 +{
33279 + return 0;
33280 +}
33281 +
33282 +int
33283 +gr_check_protected_task(const struct task_struct *task)
33284 +{
33285 + return 0;
33286 +}
33287 +
33288 +void
33289 +gr_copy_label(struct task_struct *tsk)
33290 +{
33291 + return;
33292 +}
33293 +
33294 +void
33295 +gr_set_pax_flags(struct task_struct *task)
33296 +{
33297 + return;
33298 +}
33299 +
33300 +int
33301 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt,
33302 + const int unsafe_share)
33303 +{
33304 + return 0;
33305 +}
33306 +
33307 +void
33308 +gr_handle_delete(const ino_t ino, const dev_t dev)
33309 +{
33310 + return;
33311 +}
33312 +
33313 +void
33314 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
33315 +{
33316 + return;
33317 +}
33318 +
33319 +void
33320 +gr_handle_crash(struct task_struct *task, const int sig)
33321 +{
33322 + return;
33323 +}
33324 +
33325 +int
33326 +gr_check_crash_exec(const struct file *filp)
33327 +{
33328 + return 0;
33329 +}
33330 +
33331 +int
33332 +gr_check_crash_uid(const uid_t uid)
33333 +{
33334 + return 0;
33335 +}
33336 +
33337 +void
33338 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
33339 + struct dentry *old_dentry,
33340 + struct dentry *new_dentry,
33341 + struct vfsmount *mnt, const __u8 replace)
33342 +{
33343 + return;
33344 +}
33345 +
33346 +int
33347 +gr_search_socket(const int family, const int type, const int protocol)
33348 +{
33349 + return 1;
33350 +}
33351 +
33352 +int
33353 +gr_search_connectbind(const int mode, const struct socket *sock,
33354 + const struct sockaddr_in *addr)
33355 +{
33356 + return 0;
33357 +}
33358 +
33359 +int
33360 +gr_is_capable(const int cap)
33361 +{
33362 + return 1;
33363 +}
33364 +
33365 +int
33366 +gr_is_capable_nolog(const int cap)
33367 +{
33368 + return 1;
33369 +}
33370 +
33371 +void
33372 +gr_handle_alertkill(struct task_struct *task)
33373 +{
33374 + return;
33375 +}
33376 +
33377 +__u32
33378 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
33379 +{
33380 + return 1;
33381 +}
33382 +
33383 +__u32
33384 +gr_acl_handle_hidden_file(const struct dentry * dentry,
33385 + const struct vfsmount * mnt)
33386 +{
33387 + return 1;
33388 +}
33389 +
33390 +__u32
33391 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
33392 + const int fmode)
33393 +{
33394 + return 1;
33395 +}
33396 +
33397 +__u32
33398 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
33399 +{
33400 + return 1;
33401 +}
33402 +
33403 +__u32
33404 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
33405 +{
33406 + return 1;
33407 +}
33408 +
33409 +int
33410 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
33411 + unsigned int *vm_flags)
33412 +{
33413 + return 1;
33414 +}
33415 +
33416 +__u32
33417 +gr_acl_handle_truncate(const struct dentry * dentry,
33418 + const struct vfsmount * mnt)
33419 +{
33420 + return 1;
33421 +}
33422 +
33423 +__u32
33424 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
33425 +{
33426 + return 1;
33427 +}
33428 +
33429 +__u32
33430 +gr_acl_handle_access(const struct dentry * dentry,
33431 + const struct vfsmount * mnt, const int fmode)
33432 +{
33433 + return 1;
33434 +}
33435 +
33436 +__u32
33437 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
33438 + mode_t mode)
33439 +{
33440 + return 1;
33441 +}
33442 +
33443 +__u32
33444 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
33445 + mode_t mode)
33446 +{
33447 + return 1;
33448 +}
33449 +
33450 +__u32
33451 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
33452 +{
33453 + return 1;
33454 +}
33455 +
33456 +void
33457 +grsecurity_init(void)
33458 +{
33459 + return;
33460 +}
33461 +
33462 +__u32
33463 +gr_acl_handle_mknod(const struct dentry * new_dentry,
33464 + const struct dentry * parent_dentry,
33465 + const struct vfsmount * parent_mnt,
33466 + const int mode)
33467 +{
33468 + return 1;
33469 +}
33470 +
33471 +__u32
33472 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
33473 + const struct dentry * parent_dentry,
33474 + const struct vfsmount * parent_mnt)
33475 +{
33476 + return 1;
33477 +}
33478 +
33479 +__u32
33480 +gr_acl_handle_symlink(const struct dentry * new_dentry,
33481 + const struct dentry * parent_dentry,
33482 + const struct vfsmount * parent_mnt, const char *from)
33483 +{
33484 + return 1;
33485 +}
33486 +
33487 +__u32
33488 +gr_acl_handle_link(const struct dentry * new_dentry,
33489 + const struct dentry * parent_dentry,
33490 + const struct vfsmount * parent_mnt,
33491 + const struct dentry * old_dentry,
33492 + const struct vfsmount * old_mnt, const char *to)
33493 +{
33494 + return 1;
33495 +}
33496 +
33497 +int
33498 +gr_acl_handle_rename(const struct dentry *new_dentry,
33499 + const struct dentry *parent_dentry,
33500 + const struct vfsmount *parent_mnt,
33501 + const struct dentry *old_dentry,
33502 + const struct inode *old_parent_inode,
33503 + const struct vfsmount *old_mnt, const char *newname)
33504 +{
33505 + return 0;
33506 +}
33507 +
33508 +int
33509 +gr_acl_handle_filldir(const struct file *file, const char *name,
33510 + const int namelen, const ino_t ino)
33511 +{
33512 + return 1;
33513 +}
33514 +
33515 +int
33516 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
33517 + const time_t shm_createtime, const uid_t cuid, const int shmid)
33518 +{
33519 + return 1;
33520 +}
33521 +
33522 +int
33523 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
33524 +{
33525 + return 0;
33526 +}
33527 +
33528 +int
33529 +gr_search_accept(const struct socket *sock)
33530 +{
33531 + return 0;
33532 +}
33533 +
33534 +int
33535 +gr_search_listen(const struct socket *sock)
33536 +{
33537 + return 0;
33538 +}
33539 +
33540 +int
33541 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
33542 +{
33543 + return 0;
33544 +}
33545 +
33546 +__u32
33547 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
33548 +{
33549 + return 1;
33550 +}
33551 +
33552 +__u32
33553 +gr_acl_handle_creat(const struct dentry * dentry,
33554 + const struct dentry * p_dentry,
33555 + const struct vfsmount * p_mnt, const int fmode,
33556 + const int imode)
33557 +{
33558 + return 1;
33559 +}
33560 +
33561 +void
33562 +gr_acl_handle_exit(void)
33563 +{
33564 + return;
33565 +}
33566 +
33567 +int
33568 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
33569 +{
33570 + return 1;
33571 +}
33572 +
33573 +void
33574 +gr_set_role_label(const uid_t uid, const gid_t gid)
33575 +{
33576 + return;
33577 +}
33578 +
33579 +int
33580 +gr_acl_handle_procpidmem(const struct task_struct *task)
33581 +{
33582 + return 0;
33583 +}
33584 +
33585 +int
33586 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
33587 +{
33588 + return 0;
33589 +}
33590 +
33591 +int
33592 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
33593 +{
33594 + return 0;
33595 +}
33596 +
33597 +void
33598 +gr_set_kernel_label(struct task_struct *task)
33599 +{
33600 + return;
33601 +}
33602 +
33603 +int
33604 +gr_check_user_change(int real, int effective, int fs)
33605 +{
33606 + return 0;
33607 +}
33608 +
33609 +int
33610 +gr_check_group_change(int real, int effective, int fs)
33611 +{
33612 + return 0;
33613 +}
33614 +
33615 +
33616 +EXPORT_SYMBOL(gr_is_capable);
33617 +EXPORT_SYMBOL(gr_is_capable_nolog);
33618 +EXPORT_SYMBOL(gr_learn_resource);
33619 +EXPORT_SYMBOL(gr_set_kernel_label);
33620 +#ifdef CONFIG_SECURITY
33621 +EXPORT_SYMBOL(gr_check_user_change);
33622 +EXPORT_SYMBOL(gr_check_group_change);
33623 +#endif
33624 diff -urNp linux-2.6.31.1/grsecurity/grsec_exec.c linux-2.6.31.1/grsecurity/grsec_exec.c
33625 --- linux-2.6.31.1/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
33626 +++ linux-2.6.31.1/grsecurity/grsec_exec.c 2009-10-01 20:12:44.000000000 -0400
33627 @@ -0,0 +1,89 @@
33628 +#include <linux/kernel.h>
33629 +#include <linux/sched.h>
33630 +#include <linux/file.h>
33631 +#include <linux/binfmts.h>
33632 +#include <linux/smp_lock.h>
33633 +#include <linux/fs.h>
33634 +#include <linux/types.h>
33635 +#include <linux/grdefs.h>
33636 +#include <linux/grinternal.h>
33637 +#include <linux/capability.h>
33638 +
33639 +#include <asm/uaccess.h>
33640 +
33641 +#ifdef CONFIG_GRKERNSEC_EXECLOG
33642 +static char gr_exec_arg_buf[132];
33643 +static DECLARE_MUTEX(gr_exec_arg_sem);
33644 +#endif
33645 +
33646 +int
33647 +gr_handle_nproc(void)
33648 +{
33649 +#ifdef CONFIG_GRKERNSEC_EXECVE
33650 + const struct cred *cred = current_cred();
33651 + if (grsec_enable_execve && cred->user &&
33652 + (atomic_read(&cred->user->processes) >
33653 + current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
33654 + !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
33655 + gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
33656 + return -EAGAIN;
33657 + }
33658 +#endif
33659 + return 0;
33660 +}
33661 +
33662 +void
33663 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
33664 +{
33665 +#ifdef CONFIG_GRKERNSEC_EXECLOG
33666 + char *grarg = gr_exec_arg_buf;
33667 + unsigned int i, x, execlen = 0;
33668 + char c;
33669 +
33670 + if (!((grsec_enable_execlog && grsec_enable_group &&
33671 + in_group_p(grsec_audit_gid))
33672 + || (grsec_enable_execlog && !grsec_enable_group)))
33673 + return;
33674 +
33675 + down(&gr_exec_arg_sem);
33676 + memset(grarg, 0, sizeof(gr_exec_arg_buf));
33677 +
33678 + if (unlikely(argv == NULL))
33679 + goto log;
33680 +
33681 + for (i = 0; i < bprm->argc && execlen < 128; i++) {
33682 + const char __user *p;
33683 + unsigned int len;
33684 +
33685 + if (copy_from_user(&p, argv + i, sizeof(p)))
33686 + goto log;
33687 + if (!p)
33688 + goto log;
33689 + len = strnlen_user(p, 128 - execlen);
33690 + if (len > 128 - execlen)
33691 + len = 128 - execlen;
33692 + else if (len > 0)
33693 + len--;
33694 + if (copy_from_user(grarg + execlen, p, len))
33695 + goto log;
33696 +
33697 + /* rewrite unprintable characters */
33698 + for (x = 0; x < len; x++) {
33699 + c = *(grarg + execlen + x);
33700 + if (c < 32 || c > 126)
33701 + *(grarg + execlen + x) = ' ';
33702 + }
33703 +
33704 + execlen += len;
33705 + *(grarg + execlen) = ' ';
33706 + *(grarg + execlen + 1) = '\0';
33707 + execlen++;
33708 + }
33709 +
33710 + log:
33711 + gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
33712 + bprm->file->f_path.mnt, grarg);
33713 + up(&gr_exec_arg_sem);
33714 +#endif
33715 + return;
33716 +}
33717 diff -urNp linux-2.6.31.1/grsecurity/grsec_fifo.c linux-2.6.31.1/grsecurity/grsec_fifo.c
33718 --- linux-2.6.31.1/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
33719 +++ linux-2.6.31.1/grsecurity/grsec_fifo.c 2009-10-01 20:12:44.000000000 -0400
33720 @@ -0,0 +1,24 @@
33721 +#include <linux/kernel.h>
33722 +#include <linux/sched.h>
33723 +#include <linux/fs.h>
33724 +#include <linux/file.h>
33725 +#include <linux/grinternal.h>
33726 +
33727 +int
33728 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
33729 + const struct dentry *dir, const int flag, const int acc_mode)
33730 +{
33731 +#ifdef CONFIG_GRKERNSEC_FIFO
33732 + const struct cred *cred = current_cred();
33733 +
33734 + if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
33735 + !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
33736 + (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
33737 + (cred->fsuid != dentry->d_inode->i_uid)) {
33738 + if (!generic_permission(dentry->d_inode, acc_mode, NULL))
33739 + gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
33740 + return -EACCES;
33741 + }
33742 +#endif
33743 + return 0;
33744 +}
33745 diff -urNp linux-2.6.31.1/grsecurity/grsec_fork.c linux-2.6.31.1/grsecurity/grsec_fork.c
33746 --- linux-2.6.31.1/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
33747 +++ linux-2.6.31.1/grsecurity/grsec_fork.c 2009-10-01 20:12:44.000000000 -0400
33748 @@ -0,0 +1,15 @@
33749 +#include <linux/kernel.h>
33750 +#include <linux/sched.h>
33751 +#include <linux/grsecurity.h>
33752 +#include <linux/grinternal.h>
33753 +#include <linux/errno.h>
33754 +
33755 +void
33756 +gr_log_forkfail(const int retval)
33757 +{
33758 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
33759 + if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
33760 + gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
33761 +#endif
33762 + return;
33763 +}
33764 diff -urNp linux-2.6.31.1/grsecurity/grsec_init.c linux-2.6.31.1/grsecurity/grsec_init.c
33765 --- linux-2.6.31.1/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
33766 +++ linux-2.6.31.1/grsecurity/grsec_init.c 2009-10-01 20:12:44.000000000 -0400
33767 @@ -0,0 +1,230 @@
33768 +#include <linux/kernel.h>
33769 +#include <linux/sched.h>
33770 +#include <linux/mm.h>
33771 +#include <linux/smp_lock.h>
33772 +#include <linux/gracl.h>
33773 +#include <linux/slab.h>
33774 +#include <linux/vmalloc.h>
33775 +#include <linux/percpu.h>
33776 +
33777 +int grsec_enable_link;
33778 +int grsec_enable_dmesg;
33779 +int grsec_enable_harden_ptrace;
33780 +int grsec_enable_fifo;
33781 +int grsec_enable_execve;
33782 +int grsec_enable_execlog;
33783 +int grsec_enable_signal;
33784 +int grsec_enable_forkfail;
33785 +int grsec_enable_time;
33786 +int grsec_enable_audit_textrel;
33787 +int grsec_enable_group;
33788 +int grsec_audit_gid;
33789 +int grsec_enable_chdir;
33790 +int grsec_enable_mount;
33791 +int grsec_enable_chroot_findtask;
33792 +int grsec_enable_chroot_mount;
33793 +int grsec_enable_chroot_shmat;
33794 +int grsec_enable_chroot_fchdir;
33795 +int grsec_enable_chroot_double;
33796 +int grsec_enable_chroot_pivot;
33797 +int grsec_enable_chroot_chdir;
33798 +int grsec_enable_chroot_chmod;
33799 +int grsec_enable_chroot_mknod;
33800 +int grsec_enable_chroot_nice;
33801 +int grsec_enable_chroot_execlog;
33802 +int grsec_enable_chroot_caps;
33803 +int grsec_enable_chroot_sysctl;
33804 +int grsec_enable_chroot_unix;
33805 +int grsec_enable_tpe;
33806 +int grsec_tpe_gid;
33807 +int grsec_enable_tpe_all;
33808 +int grsec_enable_socket_all;
33809 +int grsec_socket_all_gid;
33810 +int grsec_enable_socket_client;
33811 +int grsec_socket_client_gid;
33812 +int grsec_enable_socket_server;
33813 +int grsec_socket_server_gid;
33814 +int grsec_resource_logging;
33815 +int grsec_lock;
33816 +
33817 +DEFINE_SPINLOCK(grsec_alert_lock);
33818 +unsigned long grsec_alert_wtime = 0;
33819 +unsigned long grsec_alert_fyet = 0;
33820 +
33821 +DEFINE_SPINLOCK(grsec_audit_lock);
33822 +
33823 +DEFINE_RWLOCK(grsec_exec_file_lock);
33824 +
33825 +char *gr_shared_page[4];
33826 +
33827 +char *gr_alert_log_fmt;
33828 +char *gr_audit_log_fmt;
33829 +char *gr_alert_log_buf;
33830 +char *gr_audit_log_buf;
33831 +
33832 +extern struct gr_arg *gr_usermode;
33833 +extern unsigned char *gr_system_salt;
33834 +extern unsigned char *gr_system_sum;
33835 +
33836 +void __init
33837 +grsecurity_init(void)
33838 +{
33839 + int j;
33840 + /* create the per-cpu shared pages */
33841 +
33842 +#ifdef CONFIG_X86
33843 + memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
33844 +#endif
33845 +
33846 + for (j = 0; j < 4; j++) {
33847 + gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(unsigned long long));
33848 + if (gr_shared_page[j] == NULL) {
33849 + panic("Unable to allocate grsecurity shared page");
33850 + return;
33851 + }
33852 + }
33853 +
33854 + /* allocate log buffers */
33855 + gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
33856 + if (!gr_alert_log_fmt) {
33857 + panic("Unable to allocate grsecurity alert log format buffer");
33858 + return;
33859 + }
33860 + gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
33861 + if (!gr_audit_log_fmt) {
33862 + panic("Unable to allocate grsecurity audit log format buffer");
33863 + return;
33864 + }
33865 + gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
33866 + if (!gr_alert_log_buf) {
33867 + panic("Unable to allocate grsecurity alert log buffer");
33868 + return;
33869 + }
33870 + gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
33871 + if (!gr_audit_log_buf) {
33872 + panic("Unable to allocate grsecurity audit log buffer");
33873 + return;
33874 + }
33875 +
33876 + /* allocate memory for authentication structure */
33877 + gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
33878 + gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
33879 + gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
33880 +
33881 + if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
33882 + panic("Unable to allocate grsecurity authentication structure");
33883 + return;
33884 + }
33885 +
33886 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
33887 +#ifndef CONFIG_GRKERNSEC_SYSCTL
33888 + grsec_lock = 1;
33889 +#endif
33890 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
33891 + grsec_enable_audit_textrel = 1;
33892 +#endif
33893 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
33894 + grsec_enable_group = 1;
33895 + grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
33896 +#endif
33897 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
33898 + grsec_enable_chdir = 1;
33899 +#endif
33900 +#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
33901 + grsec_enable_harden_ptrace = 1;
33902 +#endif
33903 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
33904 + grsec_enable_mount = 1;
33905 +#endif
33906 +#ifdef CONFIG_GRKERNSEC_LINK
33907 + grsec_enable_link = 1;
33908 +#endif
33909 +#ifdef CONFIG_GRKERNSEC_DMESG
33910 + grsec_enable_dmesg = 1;
33911 +#endif
33912 +#ifdef CONFIG_GRKERNSEC_FIFO
33913 + grsec_enable_fifo = 1;
33914 +#endif
33915 +#ifdef CONFIG_GRKERNSEC_EXECVE
33916 + grsec_enable_execve = 1;
33917 +#endif
33918 +#ifdef CONFIG_GRKERNSEC_EXECLOG
33919 + grsec_enable_execlog = 1;
33920 +#endif
33921 +#ifdef CONFIG_GRKERNSEC_SIGNAL
33922 + grsec_enable_signal = 1;
33923 +#endif
33924 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
33925 + grsec_enable_forkfail = 1;
33926 +#endif
33927 +#ifdef CONFIG_GRKERNSEC_TIME
33928 + grsec_enable_time = 1;
33929 +#endif
33930 +#ifdef CONFIG_GRKERNSEC_RESLOG
33931 + grsec_resource_logging = 1;
33932 +#endif
33933 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
33934 + grsec_enable_chroot_findtask = 1;
33935 +#endif
33936 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
33937 + grsec_enable_chroot_unix = 1;
33938 +#endif
33939 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
33940 + grsec_enable_chroot_mount = 1;
33941 +#endif
33942 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
33943 + grsec_enable_chroot_fchdir = 1;
33944 +#endif
33945 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
33946 + grsec_enable_chroot_shmat = 1;
33947 +#endif
33948 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
33949 + grsec_enable_chroot_double = 1;
33950 +#endif
33951 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
33952 + grsec_enable_chroot_pivot = 1;
33953 +#endif
33954 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
33955 + grsec_enable_chroot_chdir = 1;
33956 +#endif
33957 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
33958 + grsec_enable_chroot_chmod = 1;
33959 +#endif
33960 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
33961 + grsec_enable_chroot_mknod = 1;
33962 +#endif
33963 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
33964 + grsec_enable_chroot_nice = 1;
33965 +#endif
33966 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
33967 + grsec_enable_chroot_execlog = 1;
33968 +#endif
33969 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
33970 + grsec_enable_chroot_caps = 1;
33971 +#endif
33972 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
33973 + grsec_enable_chroot_sysctl = 1;
33974 +#endif
33975 +#ifdef CONFIG_GRKERNSEC_TPE
33976 + grsec_enable_tpe = 1;
33977 + grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
33978 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
33979 + grsec_enable_tpe_all = 1;
33980 +#endif
33981 +#endif
33982 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
33983 + grsec_enable_socket_all = 1;
33984 + grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
33985 +#endif
33986 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
33987 + grsec_enable_socket_client = 1;
33988 + grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
33989 +#endif
33990 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
33991 + grsec_enable_socket_server = 1;
33992 + grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
33993 +#endif
33994 +#endif
33995 +
33996 + return;
33997 +}
33998 diff -urNp linux-2.6.31.1/grsecurity/grsec_link.c linux-2.6.31.1/grsecurity/grsec_link.c
33999 --- linux-2.6.31.1/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
34000 +++ linux-2.6.31.1/grsecurity/grsec_link.c 2009-10-01 20:12:44.000000000 -0400
34001 @@ -0,0 +1,43 @@
34002 +#include <linux/kernel.h>
34003 +#include <linux/sched.h>
34004 +#include <linux/fs.h>
34005 +#include <linux/file.h>
34006 +#include <linux/grinternal.h>
34007 +
34008 +int
34009 +gr_handle_follow_link(const struct inode *parent,
34010 + const struct inode *inode,
34011 + const struct dentry *dentry, const struct vfsmount *mnt)
34012 +{
34013 +#ifdef CONFIG_GRKERNSEC_LINK
34014 + const struct cred *cred = current_cred();
34015 +
34016 + if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
34017 + (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
34018 + (parent->i_mode & S_IWOTH) && (cred->fsuid != inode->i_uid)) {
34019 + gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
34020 + return -EACCES;
34021 + }
34022 +#endif
34023 + return 0;
34024 +}
34025 +
34026 +int
34027 +gr_handle_hardlink(const struct dentry *dentry,
34028 + const struct vfsmount *mnt,
34029 + struct inode *inode, const int mode, const char *to)
34030 +{
34031 +#ifdef CONFIG_GRKERNSEC_LINK
34032 + const struct cred *cred = current_cred();
34033 +
34034 + if (grsec_enable_link && cred->fsuid != inode->i_uid &&
34035 + (!S_ISREG(mode) || (mode & S_ISUID) ||
34036 + ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
34037 + (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
34038 + !capable(CAP_FOWNER) && cred->uid) {
34039 + gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
34040 + return -EPERM;
34041 + }
34042 +#endif
34043 + return 0;
34044 +}
34045 diff -urNp linux-2.6.31.1/grsecurity/grsec_log.c linux-2.6.31.1/grsecurity/grsec_log.c
34046 --- linux-2.6.31.1/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
34047 +++ linux-2.6.31.1/grsecurity/grsec_log.c 2009-10-01 20:12:44.000000000 -0400
34048 @@ -0,0 +1,294 @@
34049 +#include <linux/kernel.h>
34050 +#include <linux/sched.h>
34051 +#include <linux/file.h>
34052 +#include <linux/tty.h>
34053 +#include <linux/fs.h>
34054 +#include <linux/grinternal.h>
34055 +
34056 +#define BEGIN_LOCKS(x) \
34057 + read_lock(&tasklist_lock); \
34058 + read_lock(&grsec_exec_file_lock); \
34059 + if (x != GR_DO_AUDIT) \
34060 + spin_lock(&grsec_alert_lock); \
34061 + else \
34062 + spin_lock(&grsec_audit_lock)
34063 +
34064 +#define END_LOCKS(x) \
34065 + if (x != GR_DO_AUDIT) \
34066 + spin_unlock(&grsec_alert_lock); \
34067 + else \
34068 + spin_unlock(&grsec_audit_lock); \
34069 + read_unlock(&grsec_exec_file_lock); \
34070 + read_unlock(&tasklist_lock); \
34071 + if (x == GR_DONT_AUDIT) \
34072 + gr_handle_alertkill(current)
34073 +
34074 +enum {
34075 + FLOODING,
34076 + NO_FLOODING
34077 +};
34078 +
34079 +extern char *gr_alert_log_fmt;
34080 +extern char *gr_audit_log_fmt;
34081 +extern char *gr_alert_log_buf;
34082 +extern char *gr_audit_log_buf;
34083 +
34084 +static int gr_log_start(int audit)
34085 +{
34086 + char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
34087 + char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
34088 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
34089 +
34090 + if (audit == GR_DO_AUDIT)
34091 + goto set_fmt;
34092 +
34093 + if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
34094 + grsec_alert_wtime = jiffies;
34095 + grsec_alert_fyet = 0;
34096 + } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
34097 + grsec_alert_fyet++;
34098 + } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
34099 + grsec_alert_wtime = jiffies;
34100 + grsec_alert_fyet++;
34101 + printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
34102 + return FLOODING;
34103 + } else return FLOODING;
34104 +
34105 +set_fmt:
34106 + memset(buf, 0, PAGE_SIZE);
34107 + if (current->signal->curr_ip && gr_acl_is_enabled()) {
34108 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
34109 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
34110 + } else if (current->signal->curr_ip) {
34111 + sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
34112 + snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
34113 + } else if (gr_acl_is_enabled()) {
34114 + sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
34115 + snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
34116 + } else {
34117 + sprintf(fmt, "%s%s", loglevel, "grsec: ");
34118 + strcpy(buf, fmt);
34119 + }
34120 +
34121 + return NO_FLOODING;
34122 +}
34123 +
34124 +static void gr_log_middle(int audit, const char *msg, va_list ap)
34125 + __attribute__ ((format (printf, 2, 0)));
34126 +
34127 +static void gr_log_middle(int audit, const char *msg, va_list ap)
34128 +{
34129 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
34130 + unsigned int len = strlen(buf);
34131 +
34132 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
34133 +
34134 + return;
34135 +}
34136 +
34137 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
34138 + __attribute__ ((format (printf, 2, 3)));
34139 +
34140 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
34141 +{
34142 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
34143 + unsigned int len = strlen(buf);
34144 + va_list ap;
34145 +
34146 + va_start(ap, msg);
34147 + vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
34148 + va_end(ap);
34149 +
34150 + return;
34151 +}
34152 +
34153 +static void gr_log_end(int audit)
34154 +{
34155 + char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
34156 + unsigned int len = strlen(buf);
34157 +
34158 + snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current, current_cred(), __task_cred(current->parent)));
34159 + printk("%s\n", buf);
34160 +
34161 + return;
34162 +}
34163 +
34164 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
34165 +{
34166 + int logtype;
34167 + char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
34168 + char *str1, *str2, *str3;
34169 + void *voidptr;
34170 + int num1, num2;
34171 + unsigned long ulong1, ulong2;
34172 + struct dentry *dentry;
34173 + struct vfsmount *mnt;
34174 + struct file *file;
34175 + struct task_struct *task;
34176 + const struct cred *cred, *pcred;
34177 + va_list ap;
34178 +
34179 + BEGIN_LOCKS(audit);
34180 + logtype = gr_log_start(audit);
34181 + if (logtype == FLOODING) {
34182 + END_LOCKS(audit);
34183 + return;
34184 + }
34185 + va_start(ap, argtypes);
34186 + switch (argtypes) {
34187 + case GR_TTYSNIFF:
34188 + task = va_arg(ap, struct task_struct *);
34189 + 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);
34190 + break;
34191 + case GR_SYSCTL_HIDDEN:
34192 + str1 = va_arg(ap, char *);
34193 + gr_log_middle_varargs(audit, msg, result, str1);
34194 + break;
34195 + case GR_RBAC:
34196 + dentry = va_arg(ap, struct dentry *);
34197 + mnt = va_arg(ap, struct vfsmount *);
34198 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
34199 + break;
34200 + case GR_RBAC_STR:
34201 + dentry = va_arg(ap, struct dentry *);
34202 + mnt = va_arg(ap, struct vfsmount *);
34203 + str1 = va_arg(ap, char *);
34204 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
34205 + break;
34206 + case GR_STR_RBAC:
34207 + str1 = va_arg(ap, char *);
34208 + dentry = va_arg(ap, struct dentry *);
34209 + mnt = va_arg(ap, struct vfsmount *);
34210 + gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
34211 + break;
34212 + case GR_RBAC_MODE2:
34213 + dentry = va_arg(ap, struct dentry *);
34214 + mnt = va_arg(ap, struct vfsmount *);
34215 + str1 = va_arg(ap, char *);
34216 + str2 = va_arg(ap, char *);
34217 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
34218 + break;
34219 + case GR_RBAC_MODE3:
34220 + dentry = va_arg(ap, struct dentry *);
34221 + mnt = va_arg(ap, struct vfsmount *);
34222 + str1 = va_arg(ap, char *);
34223 + str2 = va_arg(ap, char *);
34224 + str3 = va_arg(ap, char *);
34225 + gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
34226 + break;
34227 + case GR_FILENAME:
34228 + dentry = va_arg(ap, struct dentry *);
34229 + mnt = va_arg(ap, struct vfsmount *);
34230 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
34231 + break;
34232 + case GR_STR_FILENAME:
34233 + str1 = va_arg(ap, char *);
34234 + dentry = va_arg(ap, struct dentry *);
34235 + mnt = va_arg(ap, struct vfsmount *);
34236 + gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
34237 + break;
34238 + case GR_FILENAME_STR:
34239 + dentry = va_arg(ap, struct dentry *);
34240 + mnt = va_arg(ap, struct vfsmount *);
34241 + str1 = va_arg(ap, char *);
34242 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
34243 + break;
34244 + case GR_FILENAME_TWO_INT:
34245 + dentry = va_arg(ap, struct dentry *);
34246 + mnt = va_arg(ap, struct vfsmount *);
34247 + num1 = va_arg(ap, int);
34248 + num2 = va_arg(ap, int);
34249 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
34250 + break;
34251 + case GR_FILENAME_TWO_INT_STR:
34252 + dentry = va_arg(ap, struct dentry *);
34253 + mnt = va_arg(ap, struct vfsmount *);
34254 + num1 = va_arg(ap, int);
34255 + num2 = va_arg(ap, int);
34256 + str1 = va_arg(ap, char *);
34257 + gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
34258 + break;
34259 + case GR_TEXTREL:
34260 + file = va_arg(ap, struct file *);
34261 + ulong1 = va_arg(ap, unsigned long);
34262 + ulong2 = va_arg(ap, unsigned long);
34263 + gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
34264 + break;
34265 + case GR_PTRACE:
34266 + task = va_arg(ap, struct task_struct *);
34267 + gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_path.dentry, task->exec_file->f_path.mnt) : "(none)", task->comm, task->pid);
34268 + break;
34269 + case GR_RESOURCE:
34270 + task = va_arg(ap, struct task_struct *);
34271 + cred = __task_cred(task);
34272 + pcred = __task_cred(task->parent);
34273 + ulong1 = va_arg(ap, unsigned long);
34274 + str1 = va_arg(ap, char *);
34275 + ulong2 = va_arg(ap, unsigned long);
34276 + gr_log_middle_varargs(audit, msg, ulong1, str1, ulong2, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid);
34277 + break;
34278 + case GR_CAP:
34279 + task = va_arg(ap, struct task_struct *);
34280 + cred = __task_cred(task);
34281 + pcred = __task_cred(task->parent);
34282 + str1 = va_arg(ap, char *);
34283 + gr_log_middle_varargs(audit, msg, str1, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid);
34284 + break;
34285 + case GR_SIG:
34286 + str1 = va_arg(ap, char *);
34287 + voidptr = va_arg(ap, void *);
34288 + gr_log_middle_varargs(audit, msg, str1, voidptr);
34289 + break;
34290 + case GR_SIG2:
34291 + task = va_arg(ap, struct task_struct *);
34292 + cred = __task_cred(task);
34293 + pcred = __task_cred(task->parent);
34294 + num1 = va_arg(ap, int);
34295 + gr_log_middle_varargs(audit, msg, num1, gr_task_fullpath0(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid);
34296 + break;
34297 + case GR_CRASH1:
34298 + task = va_arg(ap, struct task_struct *);
34299 + cred = __task_cred(task);
34300 + pcred = __task_cred(task->parent);
34301 + ulong1 = va_arg(ap, unsigned long);
34302 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid, cred->uid, ulong1);
34303 + break;
34304 + case GR_CRASH2:
34305 + task = va_arg(ap, struct task_struct *);
34306 + cred = __task_cred(task);
34307 + pcred = __task_cred(task->parent);
34308 + ulong1 = va_arg(ap, unsigned long);
34309 + gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid, ulong1);
34310 + break;
34311 + case GR_PSACCT:
34312 + {
34313 + unsigned int wday, cday;
34314 + __u8 whr, chr;
34315 + __u8 wmin, cmin;
34316 + __u8 wsec, csec;
34317 + char cur_tty[64] = { 0 };
34318 + char parent_tty[64] = { 0 };
34319 +
34320 + task = va_arg(ap, struct task_struct *);
34321 + wday = va_arg(ap, unsigned int);
34322 + cday = va_arg(ap, unsigned int);
34323 + whr = va_arg(ap, int);
34324 + chr = va_arg(ap, int);
34325 + wmin = va_arg(ap, int);
34326 + cmin = va_arg(ap, int);
34327 + wsec = va_arg(ap, int);
34328 + csec = va_arg(ap, int);
34329 + ulong1 = va_arg(ap, unsigned long);
34330 + cred = __task_cred(task);
34331 + pcred = __task_cred(task->parent);
34332 +
34333 + 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), cred->uid, cred->euid, cred->gid, cred->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), pcred->uid, pcred->euid, pcred->gid, pcred->egid);
34334 + }
34335 + break;
34336 + default:
34337 + gr_log_middle(audit, msg, ap);
34338 + }
34339 + va_end(ap);
34340 + gr_log_end(audit);
34341 + END_LOCKS(audit);
34342 +}
34343 diff -urNp linux-2.6.31.1/grsecurity/grsec_mem.c linux-2.6.31.1/grsecurity/grsec_mem.c
34344 --- linux-2.6.31.1/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
34345 +++ linux-2.6.31.1/grsecurity/grsec_mem.c 2009-10-01 20:12:44.000000000 -0400
34346 @@ -0,0 +1,79 @@
34347 +#include <linux/kernel.h>
34348 +#include <linux/sched.h>
34349 +#include <linux/mm.h>
34350 +#include <linux/mman.h>
34351 +#include <linux/grinternal.h>
34352 +
34353 +void
34354 +gr_handle_ioperm(void)
34355 +{
34356 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
34357 + return;
34358 +}
34359 +
34360 +void
34361 +gr_handle_iopl(void)
34362 +{
34363 + gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
34364 + return;
34365 +}
34366 +
34367 +void
34368 +gr_handle_mem_write(void)
34369 +{
34370 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
34371 + return;
34372 +}
34373 +
34374 +void
34375 +gr_handle_kmem_write(void)
34376 +{
34377 + gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
34378 + return;
34379 +}
34380 +
34381 +void
34382 +gr_handle_open_port(void)
34383 +{
34384 + gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
34385 + return;
34386 +}
34387 +
34388 +int
34389 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
34390 +{
34391 + unsigned long start, end;
34392 +
34393 + start = offset;
34394 + end = start + vma->vm_end - vma->vm_start;
34395 +
34396 + if (start > end) {
34397 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
34398 + return -EPERM;
34399 + }
34400 +
34401 + /* allowed ranges : ISA I/O BIOS */
34402 + if ((start >= __pa(high_memory))
34403 +#if defined(CONFIG_X86) || defined(CONFIG_PPC)
34404 + || (start >= 0x000a0000 && end <= 0x00100000)
34405 + || (start >= 0x00000000 && end <= 0x00001000)
34406 +#endif
34407 + )
34408 + return 0;
34409 +
34410 + if (vma->vm_flags & VM_WRITE) {
34411 + gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
34412 + return -EPERM;
34413 + } else
34414 + vma->vm_flags &= ~VM_MAYWRITE;
34415 +
34416 + return 0;
34417 +}
34418 +
34419 +void
34420 +gr_log_nonroot_mod_load(const char *modname)
34421 +{
34422 + gr_log_str(GR_DONT_AUDIT, GR_NONROOT_MODLOAD_MSG, modname);
34423 + return;
34424 +}
34425 +
34426 diff -urNp linux-2.6.31.1/grsecurity/grsec_mount.c linux-2.6.31.1/grsecurity/grsec_mount.c
34427 --- linux-2.6.31.1/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
34428 +++ linux-2.6.31.1/grsecurity/grsec_mount.c 2009-10-01 20:12:44.000000000 -0400
34429 @@ -0,0 +1,34 @@
34430 +#include <linux/kernel.h>
34431 +#include <linux/sched.h>
34432 +#include <linux/grsecurity.h>
34433 +#include <linux/grinternal.h>
34434 +
34435 +void
34436 +gr_log_remount(const char *devname, const int retval)
34437 +{
34438 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
34439 + if (grsec_enable_mount && (retval >= 0))
34440 + gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
34441 +#endif
34442 + return;
34443 +}
34444 +
34445 +void
34446 +gr_log_unmount(const char *devname, const int retval)
34447 +{
34448 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
34449 + if (grsec_enable_mount && (retval >= 0))
34450 + gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
34451 +#endif
34452 + return;
34453 +}
34454 +
34455 +void
34456 +gr_log_mount(const char *from, const char *to, const int retval)
34457 +{
34458 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
34459 + if (grsec_enable_mount && (retval >= 0))
34460 + gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
34461 +#endif
34462 + return;
34463 +}
34464 diff -urNp linux-2.6.31.1/grsecurity/grsec_sig.c linux-2.6.31.1/grsecurity/grsec_sig.c
34465 --- linux-2.6.31.1/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
34466 +++ linux-2.6.31.1/grsecurity/grsec_sig.c 2009-10-01 20:12:44.000000000 -0400
34467 @@ -0,0 +1,65 @@
34468 +#include <linux/kernel.h>
34469 +#include <linux/sched.h>
34470 +#include <linux/delay.h>
34471 +#include <linux/grsecurity.h>
34472 +#include <linux/grinternal.h>
34473 +
34474 +char *signames[] = {
34475 + [SIGSEGV] = "Segmentation fault",
34476 + [SIGILL] = "Illegal instruction",
34477 + [SIGABRT] = "Abort",
34478 + [SIGBUS] = "Invalid alignment/Bus error"
34479 +};
34480 +
34481 +void
34482 +gr_log_signal(const int sig, const void *addr, const struct task_struct *t)
34483 +{
34484 +#ifdef CONFIG_GRKERNSEC_SIGNAL
34485 + if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
34486 + (sig == SIGABRT) || (sig == SIGBUS))) {
34487 + if (t->pid == current->pid) {
34488 + gr_log_sig_addr(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, signames[sig], addr);
34489 + } else {
34490 + gr_log_sig_task(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
34491 + }
34492 + }
34493 +#endif
34494 + return;
34495 +}
34496 +
34497 +int
34498 +gr_handle_signal(const struct task_struct *p, const int sig)
34499 +{
34500 +#ifdef CONFIG_GRKERNSEC
34501 + if (current->pid > 1 && gr_check_protected_task(p)) {
34502 + gr_log_sig_task(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
34503 + return -EPERM;
34504 + } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
34505 + return -EPERM;
34506 + }
34507 +#endif
34508 + return 0;
34509 +}
34510 +
34511 +void gr_handle_brute_attach(struct task_struct *p)
34512 +{
34513 +#ifdef CONFIG_GRKERNSEC_BRUTE
34514 + read_lock(&tasklist_lock);
34515 + read_lock(&grsec_exec_file_lock);
34516 + if (p->parent && p->parent->exec_file == p->exec_file)
34517 + p->parent->brute = 1;
34518 + read_unlock(&grsec_exec_file_lock);
34519 + read_unlock(&tasklist_lock);
34520 +#endif
34521 + return;
34522 +}
34523 +
34524 +void gr_handle_brute_check(void)
34525 +{
34526 +#ifdef CONFIG_GRKERNSEC_BRUTE
34527 + if (current->brute)
34528 + msleep(30 * 1000);
34529 +#endif
34530 + return;
34531 +}
34532 +
34533 diff -urNp linux-2.6.31.1/grsecurity/grsec_sock.c linux-2.6.31.1/grsecurity/grsec_sock.c
34534 --- linux-2.6.31.1/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
34535 +++ linux-2.6.31.1/grsecurity/grsec_sock.c 2009-10-01 20:12:44.000000000 -0400
34536 @@ -0,0 +1,269 @@
34537 +#include <linux/kernel.h>
34538 +#include <linux/module.h>
34539 +#include <linux/sched.h>
34540 +#include <linux/file.h>
34541 +#include <linux/net.h>
34542 +#include <linux/in.h>
34543 +#include <linux/ip.h>
34544 +#include <net/sock.h>
34545 +#include <net/inet_sock.h>
34546 +#include <linux/grsecurity.h>
34547 +#include <linux/grinternal.h>
34548 +#include <linux/gracl.h>
34549 +
34550 +kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
34551 +EXPORT_SYMBOL(gr_cap_rtnetlink);
34552 +
34553 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
34554 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
34555 +
34556 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
34557 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
34558 +
34559 +#ifdef CONFIG_UNIX_MODULE
34560 +EXPORT_SYMBOL(gr_acl_handle_unix);
34561 +EXPORT_SYMBOL(gr_acl_handle_mknod);
34562 +EXPORT_SYMBOL(gr_handle_chroot_unix);
34563 +EXPORT_SYMBOL(gr_handle_create);
34564 +#endif
34565 +
34566 +#ifdef CONFIG_GRKERNSEC
34567 +#define gr_conn_table_size 32749
34568 +struct conn_table_entry {
34569 + struct conn_table_entry *next;
34570 + struct signal_struct *sig;
34571 +};
34572 +
34573 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
34574 +DEFINE_SPINLOCK(gr_conn_table_lock);
34575 +
34576 +extern const char * gr_socktype_to_name(unsigned char type);
34577 +extern const char * gr_proto_to_name(unsigned char proto);
34578 +
34579 +static __inline__ int
34580 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
34581 +{
34582 + return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
34583 +}
34584 +
34585 +static __inline__ int
34586 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
34587 + __u16 sport, __u16 dport)
34588 +{
34589 + if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
34590 + sig->gr_sport == sport && sig->gr_dport == dport))
34591 + return 1;
34592 + else
34593 + return 0;
34594 +}
34595 +
34596 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
34597 +{
34598 + struct conn_table_entry **match;
34599 + unsigned int index;
34600 +
34601 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
34602 + sig->gr_sport, sig->gr_dport,
34603 + gr_conn_table_size);
34604 +
34605 + newent->sig = sig;
34606 +
34607 + match = &gr_conn_table[index];
34608 + newent->next = *match;
34609 + *match = newent;
34610 +
34611 + return;
34612 +}
34613 +
34614 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
34615 +{
34616 + struct conn_table_entry *match, *last = NULL;
34617 + unsigned int index;
34618 +
34619 + index = conn_hash(sig->gr_saddr, sig->gr_daddr,
34620 + sig->gr_sport, sig->gr_dport,
34621 + gr_conn_table_size);
34622 +
34623 + match = gr_conn_table[index];
34624 + while (match && !conn_match(match->sig,
34625 + sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
34626 + sig->gr_dport)) {
34627 + last = match;
34628 + match = match->next;
34629 + }
34630 +
34631 + if (match) {
34632 + if (last)
34633 + last->next = match->next;
34634 + else
34635 + gr_conn_table[index] = NULL;
34636 + kfree(match);
34637 + }
34638 +
34639 + return;
34640 +}
34641 +
34642 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
34643 + __u16 sport, __u16 dport)
34644 +{
34645 + struct conn_table_entry *match;
34646 + unsigned int index;
34647 +
34648 + index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
34649 +
34650 + match = gr_conn_table[index];
34651 + while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
34652 + match = match->next;
34653 +
34654 + if (match)
34655 + return match->sig;
34656 + else
34657 + return NULL;
34658 +}
34659 +
34660 +#endif
34661 +
34662 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
34663 +{
34664 +#ifdef CONFIG_GRKERNSEC
34665 + struct signal_struct *sig = task->signal;
34666 + struct conn_table_entry *newent;
34667 +
34668 + newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
34669 + if (newent == NULL)
34670 + return;
34671 + /* no bh lock needed since we are called with bh disabled */
34672 + spin_lock(&gr_conn_table_lock);
34673 + gr_del_task_from_ip_table_nolock(sig);
34674 + sig->gr_saddr = inet->rcv_saddr;
34675 + sig->gr_daddr = inet->daddr;
34676 + sig->gr_sport = inet->sport;
34677 + sig->gr_dport = inet->dport;
34678 + gr_add_to_task_ip_table_nolock(sig, newent);
34679 + spin_unlock(&gr_conn_table_lock);
34680 +#endif
34681 + return;
34682 +}
34683 +
34684 +void gr_del_task_from_ip_table(struct task_struct *task)
34685 +{
34686 +#ifdef CONFIG_GRKERNSEC
34687 + spin_lock_bh(&gr_conn_table_lock);
34688 + gr_del_task_from_ip_table_nolock(task->signal);
34689 + spin_unlock_bh(&gr_conn_table_lock);
34690 +#endif
34691 + return;
34692 +}
34693 +
34694 +void
34695 +gr_attach_curr_ip(const struct sock *sk)
34696 +{
34697 +#ifdef CONFIG_GRKERNSEC
34698 + struct signal_struct *p, *set;
34699 + const struct inet_sock *inet = inet_sk(sk);
34700 +
34701 + if (unlikely(sk->sk_protocol != IPPROTO_TCP))
34702 + return;
34703 +
34704 + set = current->signal;
34705 +
34706 + spin_lock_bh(&gr_conn_table_lock);
34707 + p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
34708 + inet->dport, inet->sport);
34709 + if (unlikely(p != NULL)) {
34710 + set->curr_ip = p->curr_ip;
34711 + set->used_accept = 1;
34712 + gr_del_task_from_ip_table_nolock(p);
34713 + spin_unlock_bh(&gr_conn_table_lock);
34714 + return;
34715 + }
34716 + spin_unlock_bh(&gr_conn_table_lock);
34717 +
34718 + set->curr_ip = inet->daddr;
34719 + set->used_accept = 1;
34720 +#endif
34721 + return;
34722 +}
34723 +
34724 +int
34725 +gr_handle_sock_all(const int family, const int type, const int protocol)
34726 +{
34727 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
34728 + if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
34729 + (family != AF_UNIX) && (family != AF_LOCAL)) {
34730 + gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
34731 + return -EACCES;
34732 + }
34733 +#endif
34734 + return 0;
34735 +}
34736 +
34737 +int
34738 +gr_handle_sock_server(const struct sockaddr *sck)
34739 +{
34740 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
34741 + if (grsec_enable_socket_server &&
34742 + in_group_p(grsec_socket_server_gid) &&
34743 + sck && (sck->sa_family != AF_UNIX) &&
34744 + (sck->sa_family != AF_LOCAL)) {
34745 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
34746 + return -EACCES;
34747 + }
34748 +#endif
34749 + return 0;
34750 +}
34751 +
34752 +int
34753 +gr_handle_sock_server_other(const struct sock *sck)
34754 +{
34755 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
34756 + if (grsec_enable_socket_server &&
34757 + in_group_p(grsec_socket_server_gid) &&
34758 + sck && (sck->sk_family != AF_UNIX) &&
34759 + (sck->sk_family != AF_LOCAL)) {
34760 + gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
34761 + return -EACCES;
34762 + }
34763 +#endif
34764 + return 0;
34765 +}
34766 +
34767 +int
34768 +gr_handle_sock_client(const struct sockaddr *sck)
34769 +{
34770 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
34771 + if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
34772 + sck && (sck->sa_family != AF_UNIX) &&
34773 + (sck->sa_family != AF_LOCAL)) {
34774 + gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
34775 + return -EACCES;
34776 + }
34777 +#endif
34778 + return 0;
34779 +}
34780 +
34781 +kernel_cap_t
34782 +gr_cap_rtnetlink(struct sock *sock)
34783 +{
34784 +#ifdef CONFIG_GRKERNSEC
34785 + if (!gr_acl_is_enabled())
34786 + return current_cap();
34787 + else if (sock->sk_protocol == NETLINK_ISCSI &&
34788 + cap_raised(current_cap(), CAP_SYS_ADMIN) &&
34789 + gr_is_capable(CAP_SYS_ADMIN))
34790 + return current_cap();
34791 + else if (sock->sk_protocol == NETLINK_AUDIT &&
34792 + cap_raised(current_cap(), CAP_AUDIT_WRITE) &&
34793 + gr_is_capable(CAP_AUDIT_WRITE) &&
34794 + cap_raised(current_cap(), CAP_AUDIT_CONTROL) &&
34795 + gr_is_capable(CAP_AUDIT_CONTROL))
34796 + return current_cap();
34797 + else if (cap_raised(current_cap(), CAP_NET_ADMIN) &&
34798 + gr_is_capable(CAP_NET_ADMIN))
34799 + return current_cap();
34800 + else
34801 + return __cap_empty_set;
34802 +#else
34803 + return current_cap();
34804 +#endif
34805 +}
34806 diff -urNp linux-2.6.31.1/grsecurity/grsec_sysctl.c linux-2.6.31.1/grsecurity/grsec_sysctl.c
34807 --- linux-2.6.31.1/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
34808 +++ linux-2.6.31.1/grsecurity/grsec_sysctl.c 2009-10-01 20:12:44.000000000 -0400
34809 @@ -0,0 +1,403 @@
34810 +#include <linux/kernel.h>
34811 +#include <linux/sched.h>
34812 +#include <linux/sysctl.h>
34813 +#include <linux/grsecurity.h>
34814 +#include <linux/grinternal.h>
34815 +
34816 +int
34817 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
34818 +{
34819 +#ifdef CONFIG_GRKERNSEC_SYSCTL
34820 + if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
34821 + gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
34822 + return -EACCES;
34823 + }
34824 +#endif
34825 + return 0;
34826 +}
34827 +
34828 +#if defined(CONFIG_GRKERNSEC_SYSCTL)
34829 +ctl_table grsecurity_table[] = {
34830 +#ifdef CONFIG_GRKERNSEC_SYSCTL
34831 +#ifdef CONFIG_GRKERNSEC_LINK
34832 + {
34833 + .ctl_name = CTL_UNNUMBERED,
34834 + .procname = "linking_restrictions",
34835 + .data = &grsec_enable_link,
34836 + .maxlen = sizeof(int),
34837 + .mode = 0600,
34838 + .proc_handler = &proc_dointvec,
34839 + },
34840 +#endif
34841 +#ifdef CONFIG_GRKERNSEC_FIFO
34842 + {
34843 + .ctl_name = CTL_UNNUMBERED,
34844 + .procname = "fifo_restrictions",
34845 + .data = &grsec_enable_fifo,
34846 + .maxlen = sizeof(int),
34847 + .mode = 0600,
34848 + .proc_handler = &proc_dointvec,
34849 + },
34850 +#endif
34851 +#ifdef CONFIG_GRKERNSEC_EXECVE
34852 + {
34853 + .ctl_name = CTL_UNNUMBERED,
34854 + .procname = "execve_limiting",
34855 + .data = &grsec_enable_execve,
34856 + .maxlen = sizeof(int),
34857 + .mode = 0600,
34858 + .proc_handler = &proc_dointvec,
34859 + },
34860 +#endif
34861 +#ifdef CONFIG_GRKERNSEC_EXECLOG
34862 + {
34863 + .ctl_name = CTL_UNNUMBERED,
34864 + .procname = "exec_logging",
34865 + .data = &grsec_enable_execlog,
34866 + .maxlen = sizeof(int),
34867 + .mode = 0600,
34868 + .proc_handler = &proc_dointvec,
34869 + },
34870 +#endif
34871 +#ifdef CONFIG_GRKERNSEC_SIGNAL
34872 + {
34873 + .ctl_name = CTL_UNNUMBERED,
34874 + .procname = "signal_logging",
34875 + .data = &grsec_enable_signal,
34876 + .maxlen = sizeof(int),
34877 + .mode = 0600,
34878 + .proc_handler = &proc_dointvec,
34879 + },
34880 +#endif
34881 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
34882 + {
34883 + .ctl_name = CTL_UNNUMBERED,
34884 + .procname = "forkfail_logging",
34885 + .data = &grsec_enable_forkfail,
34886 + .maxlen = sizeof(int),
34887 + .mode = 0600,
34888 + .proc_handler = &proc_dointvec,
34889 + },
34890 +#endif
34891 +#ifdef CONFIG_GRKERNSEC_TIME
34892 + {
34893 + .ctl_name = CTL_UNNUMBERED,
34894 + .procname = "timechange_logging",
34895 + .data = &grsec_enable_time,
34896 + .maxlen = sizeof(int),
34897 + .mode = 0600,
34898 + .proc_handler = &proc_dointvec,
34899 + },
34900 +#endif
34901 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
34902 + {
34903 + .ctl_name = CTL_UNNUMBERED,
34904 + .procname = "chroot_deny_shmat",
34905 + .data = &grsec_enable_chroot_shmat,
34906 + .maxlen = sizeof(int),
34907 + .mode = 0600,
34908 + .proc_handler = &proc_dointvec,
34909 + },
34910 +#endif
34911 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
34912 + {
34913 + .ctl_name = CTL_UNNUMBERED,
34914 + .procname = "chroot_deny_unix",
34915 + .data = &grsec_enable_chroot_unix,
34916 + .maxlen = sizeof(int),
34917 + .mode = 0600,
34918 + .proc_handler = &proc_dointvec,
34919 + },
34920 +#endif
34921 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
34922 + {
34923 + .ctl_name = CTL_UNNUMBERED,
34924 + .procname = "chroot_deny_mount",
34925 + .data = &grsec_enable_chroot_mount,
34926 + .maxlen = sizeof(int),
34927 + .mode = 0600,
34928 + .proc_handler = &proc_dointvec,
34929 + },
34930 +#endif
34931 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
34932 + {
34933 + .ctl_name = CTL_UNNUMBERED,
34934 + .procname = "chroot_deny_fchdir",
34935 + .data = &grsec_enable_chroot_fchdir,
34936 + .maxlen = sizeof(int),
34937 + .mode = 0600,
34938 + .proc_handler = &proc_dointvec,
34939 + },
34940 +#endif
34941 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
34942 + {
34943 + .ctl_name = CTL_UNNUMBERED,
34944 + .procname = "chroot_deny_chroot",
34945 + .data = &grsec_enable_chroot_double,
34946 + .maxlen = sizeof(int),
34947 + .mode = 0600,
34948 + .proc_handler = &proc_dointvec,
34949 + },
34950 +#endif
34951 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
34952 + {
34953 + .ctl_name = CTL_UNNUMBERED,
34954 + .procname = "chroot_deny_pivot",
34955 + .data = &grsec_enable_chroot_pivot,
34956 + .maxlen = sizeof(int),
34957 + .mode = 0600,
34958 + .proc_handler = &proc_dointvec,
34959 + },
34960 +#endif
34961 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
34962 + {
34963 + .ctl_name = CTL_UNNUMBERED,
34964 + .procname = "chroot_enforce_chdir",
34965 + .data = &grsec_enable_chroot_chdir,
34966 + .maxlen = sizeof(int),
34967 + .mode = 0600,
34968 + .proc_handler = &proc_dointvec,
34969 + },
34970 +#endif
34971 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
34972 + {
34973 + .ctl_name = CTL_UNNUMBERED,
34974 + .procname = "chroot_deny_chmod",
34975 + .data = &grsec_enable_chroot_chmod,
34976 + .maxlen = sizeof(int),
34977 + .mode = 0600,
34978 + .proc_handler = &proc_dointvec,
34979 + },
34980 +#endif
34981 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
34982 + {
34983 + .ctl_name = CTL_UNNUMBERED,
34984 + .procname = "chroot_deny_mknod",
34985 + .data = &grsec_enable_chroot_mknod,
34986 + .maxlen = sizeof(int),
34987 + .mode = 0600,
34988 + .proc_handler = &proc_dointvec,
34989 + },
34990 +#endif
34991 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
34992 + {
34993 + .ctl_name = CTL_UNNUMBERED,
34994 + .procname = "chroot_restrict_nice",
34995 + .data = &grsec_enable_chroot_nice,
34996 + .maxlen = sizeof(int),
34997 + .mode = 0600,
34998 + .proc_handler = &proc_dointvec,
34999 + },
35000 +#endif
35001 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
35002 + {
35003 + .ctl_name = CTL_UNNUMBERED,
35004 + .procname = "chroot_execlog",
35005 + .data = &grsec_enable_chroot_execlog,
35006 + .maxlen = sizeof(int),
35007 + .mode = 0600,
35008 + .proc_handler = &proc_dointvec,
35009 + },
35010 +#endif
35011 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
35012 + {
35013 + .ctl_name = CTL_UNNUMBERED,
35014 + .procname = "chroot_caps",
35015 + .data = &grsec_enable_chroot_caps,
35016 + .maxlen = sizeof(int),
35017 + .mode = 0600,
35018 + .proc_handler = &proc_dointvec,
35019 + },
35020 +#endif
35021 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
35022 + {
35023 + .ctl_name = CTL_UNNUMBERED,
35024 + .procname = "chroot_deny_sysctl",
35025 + .data = &grsec_enable_chroot_sysctl,
35026 + .maxlen = sizeof(int),
35027 + .mode = 0600,
35028 + .proc_handler = &proc_dointvec,
35029 + },
35030 +#endif
35031 +#ifdef CONFIG_GRKERNSEC_TPE
35032 + {
35033 + .ctl_name = CTL_UNNUMBERED,
35034 + .procname = "tpe",
35035 + .data = &grsec_enable_tpe,
35036 + .maxlen = sizeof(int),
35037 + .mode = 0600,
35038 + .proc_handler = &proc_dointvec,
35039 + },
35040 + {
35041 + .ctl_name = CTL_UNNUMBERED,
35042 + .procname = "tpe_gid",
35043 + .data = &grsec_tpe_gid,
35044 + .maxlen = sizeof(int),
35045 + .mode = 0600,
35046 + .proc_handler = &proc_dointvec,
35047 + },
35048 +#endif
35049 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
35050 + {
35051 + .ctl_name = CTL_UNNUMBERED,
35052 + .procname = "tpe_restrict_all",
35053 + .data = &grsec_enable_tpe_all,
35054 + .maxlen = sizeof(int),
35055 + .mode = 0600,
35056 + .proc_handler = &proc_dointvec,
35057 + },
35058 +#endif
35059 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
35060 + {
35061 + .ctl_name = CTL_UNNUMBERED,
35062 + .procname = "socket_all",
35063 + .data = &grsec_enable_socket_all,
35064 + .maxlen = sizeof(int),
35065 + .mode = 0600,
35066 + .proc_handler = &proc_dointvec,
35067 + },
35068 + {
35069 + .ctl_name = CTL_UNNUMBERED,
35070 + .procname = "socket_all_gid",
35071 + .data = &grsec_socket_all_gid,
35072 + .maxlen = sizeof(int),
35073 + .mode = 0600,
35074 + .proc_handler = &proc_dointvec,
35075 + },
35076 +#endif
35077 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
35078 + {
35079 + .ctl_name = CTL_UNNUMBERED,
35080 + .procname = "socket_client",
35081 + .data = &grsec_enable_socket_client,
35082 + .maxlen = sizeof(int),
35083 + .mode = 0600,
35084 + .proc_handler = &proc_dointvec,
35085 + },
35086 + {
35087 + .ctl_name = CTL_UNNUMBERED,
35088 + .procname = "socket_client_gid",
35089 + .data = &grsec_socket_client_gid,
35090 + .maxlen = sizeof(int),
35091 + .mode = 0600,
35092 + .proc_handler = &proc_dointvec,
35093 + },
35094 +#endif
35095 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
35096 + {
35097 + .ctl_name = CTL_UNNUMBERED,
35098 + .procname = "socket_server",
35099 + .data = &grsec_enable_socket_server,
35100 + .maxlen = sizeof(int),
35101 + .mode = 0600,
35102 + .proc_handler = &proc_dointvec,
35103 + },
35104 + {
35105 + .ctl_name = CTL_UNNUMBERED,
35106 + .procname = "socket_server_gid",
35107 + .data = &grsec_socket_server_gid,
35108 + .maxlen = sizeof(int),
35109 + .mode = 0600,
35110 + .proc_handler = &proc_dointvec,
35111 + },
35112 +#endif
35113 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
35114 + {
35115 + .ctl_name = CTL_UNNUMBERED,
35116 + .procname = "audit_group",
35117 + .data = &grsec_enable_group,
35118 + .maxlen = sizeof(int),
35119 + .mode = 0600,
35120 + .proc_handler = &proc_dointvec,
35121 + },
35122 + {
35123 + .ctl_name = CTL_UNNUMBERED,
35124 + .procname = "audit_gid",
35125 + .data = &grsec_audit_gid,
35126 + .maxlen = sizeof(int),
35127 + .mode = 0600,
35128 + .proc_handler = &proc_dointvec,
35129 + },
35130 +#endif
35131 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
35132 + {
35133 + .ctl_name = CTL_UNNUMBERED,
35134 + .procname = "audit_chdir",
35135 + .data = &grsec_enable_chdir,
35136 + .maxlen = sizeof(int),
35137 + .mode = 0600,
35138 + .proc_handler = &proc_dointvec,
35139 + },
35140 +#endif
35141 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
35142 + {
35143 + .ctl_name = CTL_UNNUMBERED,
35144 + .procname = "audit_mount",
35145 + .data = &grsec_enable_mount,
35146 + .maxlen = sizeof(int),
35147 + .mode = 0600,
35148 + .proc_handler = &proc_dointvec,
35149 + },
35150 +#endif
35151 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
35152 + {
35153 + .ctl_name = CTL_UNNUMBERED,
35154 + .procname = "audit_textrel",
35155 + .data = &grsec_enable_audit_textrel,
35156 + .maxlen = sizeof(int),
35157 + .mode = 0600,
35158 + .proc_handler = &proc_dointvec,
35159 + },
35160 +#endif
35161 +#ifdef CONFIG_GRKERNSEC_DMESG
35162 + {
35163 + .ctl_name = CTL_UNNUMBERED,
35164 + .procname = "dmesg",
35165 + .data = &grsec_enable_dmesg,
35166 + .maxlen = sizeof(int),
35167 + .mode = 0600,
35168 + .proc_handler = &proc_dointvec,
35169 + },
35170 +#endif
35171 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
35172 + {
35173 + .ctl_name = CTL_UNNUMBERED,
35174 + .procname = "chroot_findtask",
35175 + .data = &grsec_enable_chroot_findtask,
35176 + .maxlen = sizeof(int),
35177 + .mode = 0600,
35178 + .proc_handler = &proc_dointvec,
35179 + },
35180 +#endif
35181 +#ifdef CONFIG_GRKERNSEC_RESLOG
35182 + {
35183 + .ctl_name = CTL_UNNUMBERED,
35184 + .procname = "resource_logging",
35185 + .data = &grsec_resource_logging,
35186 + .maxlen = sizeof(int),
35187 + .mode = 0600,
35188 + .proc_handler = &proc_dointvec,
35189 + },
35190 +#endif
35191 +#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
35192 + {
35193 + .ctl_name = CTL_UNNUMBERED,
35194 + .procname = "harden_ptrace",
35195 + .data = &grsec_enable_harden_ptrace,
35196 + .maxlen = sizeof(int),
35197 + .mode = 0600,
35198 + .proc_handler = &proc_dointvec,
35199 + },
35200 +#endif
35201 + {
35202 + .ctl_name = CTL_UNNUMBERED,
35203 + .procname = "grsec_lock",
35204 + .data = &grsec_lock,
35205 + .maxlen = sizeof(int),
35206 + .mode = 0600,
35207 + .proc_handler = &proc_dointvec,
35208 + },
35209 +#endif
35210 + { .ctl_name = 0 }
35211 +};
35212 +#endif
35213 diff -urNp linux-2.6.31.1/grsecurity/grsec_textrel.c linux-2.6.31.1/grsecurity/grsec_textrel.c
35214 --- linux-2.6.31.1/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
35215 +++ linux-2.6.31.1/grsecurity/grsec_textrel.c 2009-10-01 20:12:44.000000000 -0400
35216 @@ -0,0 +1,16 @@
35217 +#include <linux/kernel.h>
35218 +#include <linux/sched.h>
35219 +#include <linux/mm.h>
35220 +#include <linux/file.h>
35221 +#include <linux/grinternal.h>
35222 +#include <linux/grsecurity.h>
35223 +
35224 +void
35225 +gr_log_textrel(struct vm_area_struct * vma)
35226 +{
35227 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
35228 + if (grsec_enable_audit_textrel)
35229 + gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
35230 +#endif
35231 + return;
35232 +}
35233 diff -urNp linux-2.6.31.1/grsecurity/grsec_time.c linux-2.6.31.1/grsecurity/grsec_time.c
35234 --- linux-2.6.31.1/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
35235 +++ linux-2.6.31.1/grsecurity/grsec_time.c 2009-10-01 20:12:44.000000000 -0400
35236 @@ -0,0 +1,13 @@
35237 +#include <linux/kernel.h>
35238 +#include <linux/sched.h>
35239 +#include <linux/grinternal.h>
35240 +
35241 +void
35242 +gr_log_timechange(void)
35243 +{
35244 +#ifdef CONFIG_GRKERNSEC_TIME
35245 + if (grsec_enable_time)
35246 + gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
35247 +#endif
35248 + return;
35249 +}
35250 diff -urNp linux-2.6.31.1/grsecurity/grsec_tpe.c linux-2.6.31.1/grsecurity/grsec_tpe.c
35251 --- linux-2.6.31.1/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
35252 +++ linux-2.6.31.1/grsecurity/grsec_tpe.c 2009-10-01 20:12:44.000000000 -0400
35253 @@ -0,0 +1,38 @@
35254 +#include <linux/kernel.h>
35255 +#include <linux/sched.h>
35256 +#include <linux/file.h>
35257 +#include <linux/fs.h>
35258 +#include <linux/grinternal.h>
35259 +
35260 +extern int gr_acl_tpe_check(void);
35261 +
35262 +int
35263 +gr_tpe_allow(const struct file *file)
35264 +{
35265 +#ifdef CONFIG_GRKERNSEC
35266 + struct inode *inode = file->f_path.dentry->d_parent->d_inode;
35267 + const struct cred *cred = current_cred();
35268 +
35269 + if (cred->uid && ((grsec_enable_tpe &&
35270 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
35271 + !in_group_p(grsec_tpe_gid)
35272 +#else
35273 + in_group_p(grsec_tpe_gid)
35274 +#endif
35275 + ) || gr_acl_tpe_check()) &&
35276 + (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
35277 + (inode->i_mode & S_IWOTH))))) {
35278 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
35279 + return 0;
35280 + }
35281 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
35282 + if (cred->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
35283 + ((inode->i_uid && (inode->i_uid != cred->uid)) ||
35284 + (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
35285 + gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
35286 + return 0;
35287 + }
35288 +#endif
35289 +#endif
35290 + return 1;
35291 +}
35292 diff -urNp linux-2.6.31.1/grsecurity/grsum.c linux-2.6.31.1/grsecurity/grsum.c
35293 --- linux-2.6.31.1/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
35294 +++ linux-2.6.31.1/grsecurity/grsum.c 2009-10-01 20:12:44.000000000 -0400
35295 @@ -0,0 +1,59 @@
35296 +#include <linux/err.h>
35297 +#include <linux/kernel.h>
35298 +#include <linux/sched.h>
35299 +#include <linux/mm.h>
35300 +#include <linux/scatterlist.h>
35301 +#include <linux/crypto.h>
35302 +#include <linux/gracl.h>
35303 +
35304 +
35305 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
35306 +#error "crypto and sha256 must be built into the kernel"
35307 +#endif
35308 +
35309 +int
35310 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
35311 +{
35312 + char *p;
35313 + struct crypto_hash *tfm;
35314 + struct hash_desc desc;
35315 + struct scatterlist sg;
35316 + unsigned char temp_sum[GR_SHA_LEN];
35317 + volatile int retval = 0;
35318 + volatile int dummy = 0;
35319 + unsigned int i;
35320 +
35321 + tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
35322 + if (IS_ERR(tfm)) {
35323 + /* should never happen, since sha256 should be built in */
35324 + return 1;
35325 + }
35326 +
35327 + desc.tfm = tfm;
35328 + desc.flags = 0;
35329 +
35330 + crypto_hash_init(&desc);
35331 +
35332 + p = salt;
35333 + sg_set_buf(&sg, p, GR_SALT_LEN);
35334 + crypto_hash_update(&desc, &sg, sg.length);
35335 +
35336 + p = entry->pw;
35337 + sg_set_buf(&sg, p, strlen(p));
35338 +
35339 + crypto_hash_update(&desc, &sg, sg.length);
35340 +
35341 + crypto_hash_final(&desc, temp_sum);
35342 +
35343 + memset(entry->pw, 0, GR_PW_LEN);
35344 +
35345 + for (i = 0; i < GR_SHA_LEN; i++)
35346 + if (sum[i] != temp_sum[i])
35347 + retval = 1;
35348 + else
35349 + dummy = 1; // waste a cycle
35350 +
35351 + crypto_free_hash(tfm);
35352 +
35353 + return retval;
35354 +}
35355 diff -urNp linux-2.6.31.1/grsecurity/Kconfig linux-2.6.31.1/grsecurity/Kconfig
35356 --- linux-2.6.31.1/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
35357 +++ linux-2.6.31.1/grsecurity/Kconfig 2009-10-01 20:12:44.000000000 -0400
35358 @@ -0,0 +1,908 @@
35359 +#
35360 +# grecurity configuration
35361 +#
35362 +
35363 +menu "Grsecurity"
35364 +
35365 +config GRKERNSEC
35366 + bool "Grsecurity"
35367 + select CRYPTO
35368 + select CRYPTO_SHA256
35369 + help
35370 + If you say Y here, you will be able to configure many features
35371 + that will enhance the security of your system. It is highly
35372 + recommended that you say Y here and read through the help
35373 + for each option so that you fully understand the features and
35374 + can evaluate their usefulness for your machine.
35375 +
35376 +choice
35377 + prompt "Security Level"
35378 + depends on GRKERNSEC
35379 + default GRKERNSEC_CUSTOM
35380 +
35381 +config GRKERNSEC_LOW
35382 + bool "Low"
35383 + select GRKERNSEC_LINK
35384 + select GRKERNSEC_FIFO
35385 + select GRKERNSEC_EXECVE
35386 + select GRKERNSEC_RANDNET
35387 + select GRKERNSEC_DMESG
35388 + select GRKERNSEC_CHROOT
35389 + select GRKERNSEC_CHROOT_CHDIR
35390 +
35391 + help
35392 + If you choose this option, several of the grsecurity options will
35393 + be enabled that will give you greater protection against a number
35394 + of attacks, while assuring that none of your software will have any
35395 + conflicts with the additional security measures. If you run a lot
35396 + of unusual software, or you are having problems with the higher
35397 + security levels, you should say Y here. With this option, the
35398 + following features are enabled:
35399 +
35400 + - Linking restrictions
35401 + - FIFO restrictions
35402 + - Enforcing RLIMIT_NPROC on execve
35403 + - Restricted dmesg
35404 + - Enforced chdir("/") on chroot
35405 + - Runtime module disabling
35406 +
35407 +config GRKERNSEC_MEDIUM
35408 + bool "Medium"
35409 + select PAX
35410 + select PAX_EI_PAX
35411 + select PAX_PT_PAX_FLAGS
35412 + select PAX_HAVE_ACL_FLAGS
35413 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
35414 + select GRKERNSEC_CHROOT
35415 + select GRKERNSEC_CHROOT_SYSCTL
35416 + select GRKERNSEC_LINK
35417 + select GRKERNSEC_FIFO
35418 + select GRKERNSEC_EXECVE
35419 + select GRKERNSEC_DMESG
35420 + select GRKERNSEC_RANDNET
35421 + select GRKERNSEC_FORKFAIL
35422 + select GRKERNSEC_TIME
35423 + select GRKERNSEC_SIGNAL
35424 + select GRKERNSEC_CHROOT
35425 + select GRKERNSEC_CHROOT_UNIX
35426 + select GRKERNSEC_CHROOT_MOUNT
35427 + select GRKERNSEC_CHROOT_PIVOT
35428 + select GRKERNSEC_CHROOT_DOUBLE
35429 + select GRKERNSEC_CHROOT_CHDIR
35430 + select GRKERNSEC_CHROOT_MKNOD
35431 + select GRKERNSEC_PROC
35432 + select GRKERNSEC_PROC_USERGROUP
35433 + select PAX_RANDUSTACK
35434 + select PAX_ASLR
35435 + select PAX_RANDMMAP
35436 + select PAX_REFCOUNT if (X86 || SPARC64)
35437 + select PAX_USERCOPY if ((X86 || SPARC32 || SPARC64 || PPC32 || PPC64) && (SLAB || SLUB || SLOB))
35438 +
35439 + help
35440 + If you say Y here, several features in addition to those included
35441 + in the low additional security level will be enabled. These
35442 + features provide even more security to your system, though in rare
35443 + cases they may be incompatible with very old or poorly written
35444 + software. If you enable this option, make sure that your auth
35445 + service (identd) is running as gid 1001. With this option,
35446 + the following features (in addition to those provided in the
35447 + low additional security level) will be enabled:
35448 +
35449 + - Failed fork logging
35450 + - Time change logging
35451 + - Signal logging
35452 + - Deny mounts in chroot
35453 + - Deny double chrooting
35454 + - Deny sysctl writes in chroot
35455 + - Deny mknod in chroot
35456 + - Deny access to abstract AF_UNIX sockets out of chroot
35457 + - Deny pivot_root in chroot
35458 + - Denied writes of /dev/kmem, /dev/mem, and /dev/port
35459 + - /proc restrictions with special GID set to 10 (usually wheel)
35460 + - Address Space Layout Randomization (ASLR)
35461 + - Prevent exploitation of most refcount overflows
35462 + - Bounds checking of copying between the kernel and userland
35463 +
35464 +config GRKERNSEC_HIGH
35465 + bool "High"
35466 + select GRKERNSEC_LINK
35467 + select GRKERNSEC_FIFO
35468 + select GRKERNSEC_EXECVE
35469 + select GRKERNSEC_DMESG
35470 + select GRKERNSEC_FORKFAIL
35471 + select GRKERNSEC_TIME
35472 + select GRKERNSEC_SIGNAL
35473 + select GRKERNSEC_CHROOT
35474 + select GRKERNSEC_CHROOT_SHMAT
35475 + select GRKERNSEC_CHROOT_UNIX
35476 + select GRKERNSEC_CHROOT_MOUNT
35477 + select GRKERNSEC_CHROOT_FCHDIR
35478 + select GRKERNSEC_CHROOT_PIVOT
35479 + select GRKERNSEC_CHROOT_DOUBLE
35480 + select GRKERNSEC_CHROOT_CHDIR
35481 + select GRKERNSEC_CHROOT_MKNOD
35482 + select GRKERNSEC_CHROOT_CAPS
35483 + select GRKERNSEC_CHROOT_SYSCTL
35484 + select GRKERNSEC_CHROOT_FINDTASK
35485 + select GRKERNSEC_PROC
35486 + select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
35487 + select GRKERNSEC_HIDESYM
35488 + select GRKERNSEC_BRUTE
35489 + select GRKERNSEC_PROC_USERGROUP
35490 + select GRKERNSEC_KMEM
35491 + select GRKERNSEC_RESLOG
35492 + select GRKERNSEC_RANDNET
35493 + select GRKERNSEC_PROC_ADD
35494 + select GRKERNSEC_CHROOT_CHMOD
35495 + select GRKERNSEC_CHROOT_NICE
35496 + select GRKERNSEC_AUDIT_MOUNT
35497 + select GRKERNSEC_MODHARDEN if (MODULES)
35498 + select GRKERNSEC_HARDEN_PTRACE
35499 + select PAX
35500 + select PAX_RANDUSTACK
35501 + select PAX_ASLR
35502 + select PAX_RANDMMAP
35503 + select PAX_NOEXEC
35504 + select PAX_MPROTECT
35505 + select PAX_EI_PAX
35506 + select PAX_PT_PAX_FLAGS
35507 + select PAX_HAVE_ACL_FLAGS
35508 + select PAX_KERNEXEC if (X86 && (!X86_32 || X86_WP_WORKS_OK))
35509 + select PAX_MEMORY_UDEREF if (X86_32)
35510 + select PAX_RANDKSTACK if (X86_TSC && !X86_64)
35511 + select PAX_SEGMEXEC if (X86_32)
35512 + select PAX_PAGEEXEC
35513 + select PAX_EMUPLT if (ALPHA || PARISC || SPARC32 || SPARC64)
35514 + select PAX_EMUTRAMP if (PARISC)
35515 + select PAX_EMUSIGRT if (PARISC)
35516 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
35517 + select PAX_REFCOUNT if (X86 || SPARC64)
35518 + select PAX_USERCOPY if ((X86 || PPC32 || PPC64 || SPARC32 || SPARC64) && (SLAB || SLUB || SLOB))
35519 + help
35520 + If you say Y here, many of the features of grsecurity will be
35521 + enabled, which will protect you against many kinds of attacks
35522 + against your system. The heightened security comes at a cost
35523 + of an increased chance of incompatibilities with rare software
35524 + on your machine. Since this security level enables PaX, you should
35525 + view <http://pax.grsecurity.net> and read about the PaX
35526 + project. While you are there, download chpax and run it on
35527 + binaries that cause problems with PaX. Also remember that
35528 + since the /proc restrictions are enabled, you must run your
35529 + identd as gid 1001. This security level enables the following
35530 + features in addition to those listed in the low and medium
35531 + security levels:
35532 +
35533 + - Additional /proc restrictions
35534 + - Chmod restrictions in chroot
35535 + - No signals, ptrace, or viewing of processes outside of chroot
35536 + - Capability restrictions in chroot
35537 + - Deny fchdir out of chroot
35538 + - Priority restrictions in chroot
35539 + - Segmentation-based implementation of PaX
35540 + - Mprotect restrictions
35541 + - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
35542 + - Kernel stack randomization
35543 + - Mount/unmount/remount logging
35544 + - Kernel symbol hiding
35545 + - Prevention of memory exhaustion-based exploits
35546 + - Hardening of module auto-loading
35547 + - Ptrace restrictions
35548 +
35549 +config GRKERNSEC_CUSTOM
35550 + bool "Custom"
35551 + help
35552 + If you say Y here, you will be able to configure every grsecurity
35553 + option, which allows you to enable many more features that aren't
35554 + covered in the basic security levels. These additional features
35555 + include TPE, socket restrictions, and the sysctl system for
35556 + grsecurity. It is advised that you read through the help for
35557 + each option to determine its usefulness in your situation.
35558 +
35559 +endchoice
35560 +
35561 +menu "Address Space Protection"
35562 +depends on GRKERNSEC
35563 +
35564 +config GRKERNSEC_KMEM
35565 + bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
35566 + help
35567 + If you say Y here, /dev/kmem and /dev/mem won't be allowed to
35568 + be written to via mmap or otherwise to modify the running kernel.
35569 + /dev/port will also not be allowed to be opened. If you have module
35570 + support disabled, enabling this will close up four ways that are
35571 + currently used to insert malicious code into the running kernel.
35572 + Even with all these features enabled, we still highly recommend that
35573 + you use the RBAC system, as it is still possible for an attacker to
35574 + modify the running kernel through privileged I/O granted by ioperm/iopl.
35575 + If you are not using XFree86, you may be able to stop this additional
35576 + case by enabling the 'Disable privileged I/O' option. Though nothing
35577 + legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
35578 + but only to video memory, which is the only writing we allow in this
35579 + case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
35580 + not be allowed to mprotect it with PROT_WRITE later.
35581 + It is highly recommended that you say Y here if you meet all the
35582 + conditions above.
35583 +
35584 +config GRKERNSEC_IO
35585 + bool "Disable privileged I/O"
35586 + depends on X86
35587 + select RTC_CLASS
35588 + select RTC_INTF_DEV
35589 + select RTC_DRV_CMOS
35590 +
35591 + help
35592 + If you say Y here, all ioperm and iopl calls will return an error.
35593 + Ioperm and iopl can be used to modify the running kernel.
35594 + Unfortunately, some programs need this access to operate properly,
35595 + the most notable of which are XFree86 and hwclock. hwclock can be
35596 + remedied by having RTC support in the kernel, so real-time
35597 + clock support is enabled if this option is enabled, to ensure
35598 + that hwclock operates correctly. XFree86 still will not
35599 + operate correctly with this option enabled, so DO NOT CHOOSE Y
35600 + IF YOU USE XFree86. If you use XFree86 and you still want to
35601 + protect your kernel against modification, use the RBAC system.
35602 +
35603 +config GRKERNSEC_PROC_MEMMAP
35604 + bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
35605 + default y if (PAX_NOEXEC || PAX_ASLR)
35606 + depends on PAX_NOEXEC || PAX_ASLR
35607 + help
35608 + If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
35609 + give no information about the addresses of its mappings if
35610 + PaX features that rely on random addresses are enabled on the task.
35611 + If you use PaX it is greatly recommended that you say Y here as it
35612 + closes up a hole that makes the full ASLR useless for suid
35613 + binaries.
35614 +
35615 +config GRKERNSEC_BRUTE
35616 + bool "Deter exploit bruteforcing"
35617 + help
35618 + If you say Y here, attempts to bruteforce exploits against forking
35619 + daemons such as apache or sshd will be deterred. When a child of a
35620 + forking daemon is killed by PaX or crashes due to an illegal
35621 + instruction, the parent process will be delayed 30 seconds upon every
35622 + subsequent fork until the administrator is able to assess the
35623 + situation and restart the daemon. It is recommended that you also
35624 + enable signal logging in the auditing section so that logs are
35625 + generated when a process performs an illegal instruction.
35626 +
35627 +config GRKERNSEC_MODHARDEN
35628 + bool "Harden module auto-loading"
35629 + depends on MODULES
35630 + help
35631 + If you say Y here, module auto-loading in response to use of some
35632 + feature implemented by an unloaded module will be restricted to
35633 + root users. Enabling this option helps defend against attacks
35634 + by unprivileged users who abuse the auto-loading behavior to
35635 + cause a vulnerable module to load that is then exploited.
35636 +
35637 + If this option prevents a legitimate use of auto-loading for a
35638 + non-root user, the administrator can execute modprobe manually
35639 + with the exact name of the module mentioned in the alert log.
35640 + Alternatively, the administrator can add the module to the list
35641 + of modules loaded at boot by modifying init scripts.
35642 +
35643 + Modification of init scripts will most likely be needed on
35644 + Ubuntu servers with encrypted home directory support enabled,
35645 + as the first non-root user logging in will cause the ecb(aes),
35646 + ecb(aes)-all, cbc(aes), and cbc(aes)-all modules to be loaded.
35647 +
35648 +config GRKERNSEC_HIDESYM
35649 + bool "Hide kernel symbols"
35650 + help
35651 + If you say Y here, getting information on loaded modules, and
35652 + displaying all kernel symbols through a syscall will be restricted
35653 + to users with CAP_SYS_MODULE. For software compatibility reasons,
35654 + /proc/kallsyms will be restricted to the root user. The RBAC
35655 + system can hide that entry even from root. Note that this option
35656 + is only effective provided the following conditions are met:
35657 + 1) The kernel using grsecurity is not precompiled by some distribution
35658 + 2) You are using the RBAC system and hiding other files such as your
35659 + kernel image and System.map. Alternatively, enabling this option
35660 + causes the permissions on /boot, /lib/modules, and the kernel
35661 + source directory to change at compile time to prevent
35662 + reading by non-root users.
35663 + If the above conditions are met, this option will aid in providing a
35664 + useful protection against local kernel exploitation of overflows
35665 + and arbitrary read/write vulnerabilities.
35666 +
35667 +endmenu
35668 +menu "Role Based Access Control Options"
35669 +depends on GRKERNSEC
35670 +
35671 +config GRKERNSEC_NO_RBAC
35672 + bool "Disable RBAC system"
35673 + help
35674 + If you say Y here, the /dev/grsec device will be removed from the kernel,
35675 + preventing the RBAC system from being enabled. You should only say Y
35676 + here if you have no intention of using the RBAC system, so as to prevent
35677 + an attacker with root access from misusing the RBAC system to hide files
35678 + and processes when loadable module support and /dev/[k]mem have been
35679 + locked down.
35680 +
35681 +config GRKERNSEC_ACL_HIDEKERN
35682 + bool "Hide kernel processes"
35683 + help
35684 + If you say Y here, all kernel threads will be hidden to all
35685 + processes but those whose subject has the "view hidden processes"
35686 + flag.
35687 +
35688 +config GRKERNSEC_ACL_MAXTRIES
35689 + int "Maximum tries before password lockout"
35690 + default 3
35691 + help
35692 + This option enforces the maximum number of times a user can attempt
35693 + to authorize themselves with the grsecurity RBAC system before being
35694 + denied the ability to attempt authorization again for a specified time.
35695 + The lower the number, the harder it will be to brute-force a password.
35696 +
35697 +config GRKERNSEC_ACL_TIMEOUT
35698 + int "Time to wait after max password tries, in seconds"
35699 + default 30
35700 + help
35701 + This option specifies the time the user must wait after attempting to
35702 + authorize to the RBAC system with the maximum number of invalid
35703 + passwords. The higher the number, the harder it will be to brute-force
35704 + a password.
35705 +
35706 +endmenu
35707 +menu "Filesystem Protections"
35708 +depends on GRKERNSEC
35709 +
35710 +config GRKERNSEC_PROC
35711 + bool "Proc restrictions"
35712 + help
35713 + If you say Y here, the permissions of the /proc filesystem
35714 + will be altered to enhance system security and privacy. You MUST
35715 + choose either a user only restriction or a user and group restriction.
35716 + Depending upon the option you choose, you can either restrict users to
35717 + see only the processes they themselves run, or choose a group that can
35718 + view all processes and files normally restricted to root if you choose
35719 + the "restrict to user only" option. NOTE: If you're running identd as
35720 + a non-root user, you will have to run it as the group you specify here.
35721 +
35722 +config GRKERNSEC_PROC_USER
35723 + bool "Restrict /proc to user only"
35724 + depends on GRKERNSEC_PROC
35725 + help
35726 + If you say Y here, non-root users will only be able to view their own
35727 + processes, and restricts them from viewing network-related information,
35728 + and viewing kernel symbol and module information.
35729 +
35730 +config GRKERNSEC_PROC_USERGROUP
35731 + bool "Allow special group"
35732 + depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
35733 + help
35734 + If you say Y here, you will be able to select a group that will be
35735 + able to view all processes, network-related information, and
35736 + kernel and symbol information. This option is useful if you want
35737 + to run identd as a non-root user.
35738 +
35739 +config GRKERNSEC_PROC_GID
35740 + int "GID for special group"
35741 + depends on GRKERNSEC_PROC_USERGROUP
35742 + default 1001
35743 +
35744 +config GRKERNSEC_PROC_ADD
35745 + bool "Additional restrictions"
35746 + depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
35747 + help
35748 + If you say Y here, additional restrictions will be placed on
35749 + /proc that keep normal users from viewing device information and
35750 + slabinfo information that could be useful for exploits.
35751 +
35752 +config GRKERNSEC_LINK
35753 + bool "Linking restrictions"
35754 + help
35755 + If you say Y here, /tmp race exploits will be prevented, since users
35756 + will no longer be able to follow symlinks owned by other users in
35757 + world-writable +t directories (i.e. /tmp), unless the owner of the
35758 + symlink is the owner of the directory. users will also not be
35759 + able to hardlink to files they do not own. If the sysctl option is
35760 + enabled, a sysctl option with name "linking_restrictions" is created.
35761 +
35762 +config GRKERNSEC_FIFO
35763 + bool "FIFO restrictions"
35764 + help
35765 + If you say Y here, users will not be able to write to FIFOs they don't
35766 + own in world-writable +t directories (i.e. /tmp), unless the owner of
35767 + the FIFO is the same owner of the directory it's held in. If the sysctl
35768 + option is enabled, a sysctl option with name "fifo_restrictions" is
35769 + created.
35770 +
35771 +config GRKERNSEC_CHROOT
35772 + bool "Chroot jail restrictions"
35773 + help
35774 + If you say Y here, you will be able to choose several options that will
35775 + make breaking out of a chrooted jail much more difficult. If you
35776 + encounter no software incompatibilities with the following options, it
35777 + is recommended that you enable each one.
35778 +
35779 +config GRKERNSEC_CHROOT_MOUNT
35780 + bool "Deny mounts"
35781 + depends on GRKERNSEC_CHROOT
35782 + help
35783 + If you say Y here, processes inside a chroot will not be able to
35784 + mount or remount filesystems. If the sysctl option is enabled, a
35785 + sysctl option with name "chroot_deny_mount" is created.
35786 +
35787 +config GRKERNSEC_CHROOT_DOUBLE
35788 + bool "Deny double-chroots"
35789 + depends on GRKERNSEC_CHROOT
35790 + help
35791 + If you say Y here, processes inside a chroot will not be able to chroot
35792 + again outside the chroot. This is a widely used method of breaking
35793 + out of a chroot jail and should not be allowed. If the sysctl
35794 + option is enabled, a sysctl option with name
35795 + "chroot_deny_chroot" is created.
35796 +
35797 +config GRKERNSEC_CHROOT_PIVOT
35798 + bool "Deny pivot_root in chroot"
35799 + depends on GRKERNSEC_CHROOT
35800 + help
35801 + If you say Y here, processes inside a chroot will not be able to use
35802 + a function called pivot_root() that was introduced in Linux 2.3.41. It
35803 + works similar to chroot in that it changes the root filesystem. This
35804 + function could be misused in a chrooted process to attempt to break out
35805 + of the chroot, and therefore should not be allowed. If the sysctl
35806 + option is enabled, a sysctl option with name "chroot_deny_pivot" is
35807 + created.
35808 +
35809 +config GRKERNSEC_CHROOT_CHDIR
35810 + bool "Enforce chdir(\"/\") on all chroots"
35811 + depends on GRKERNSEC_CHROOT
35812 + help
35813 + If you say Y here, the current working directory of all newly-chrooted
35814 + applications will be set to the the root directory of the chroot.
35815 + The man page on chroot(2) states:
35816 + Note that this call does not change the current working
35817 + directory, so that `.' can be outside the tree rooted at
35818 + `/'. In particular, the super-user can escape from a
35819 + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
35820 +
35821 + It is recommended that you say Y here, since it's not known to break
35822 + any software. If the sysctl option is enabled, a sysctl option with
35823 + name "chroot_enforce_chdir" is created.
35824 +
35825 +config GRKERNSEC_CHROOT_CHMOD
35826 + bool "Deny (f)chmod +s"
35827 + depends on GRKERNSEC_CHROOT
35828 + help
35829 + If you say Y here, processes inside a chroot will not be able to chmod
35830 + or fchmod files to make them have suid or sgid bits. This protects
35831 + against another published method of breaking a chroot. If the sysctl
35832 + option is enabled, a sysctl option with name "chroot_deny_chmod" is
35833 + created.
35834 +
35835 +config GRKERNSEC_CHROOT_FCHDIR
35836 + bool "Deny fchdir out of chroot"
35837 + depends on GRKERNSEC_CHROOT
35838 + help
35839 + If you say Y here, a well-known method of breaking chroots by fchdir'ing
35840 + to a file descriptor of the chrooting process that points to a directory
35841 + outside the filesystem will be stopped. If the sysctl option
35842 + is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
35843 +
35844 +config GRKERNSEC_CHROOT_MKNOD
35845 + bool "Deny mknod"
35846 + depends on GRKERNSEC_CHROOT
35847 + help
35848 + If you say Y here, processes inside a chroot will not be allowed to
35849 + mknod. The problem with using mknod inside a chroot is that it
35850 + would allow an attacker to create a device entry that is the same
35851 + as one on the physical root of your system, which could range from
35852 + anything from the console device to a device for your harddrive (which
35853 + they could then use to wipe the drive or steal data). It is recommended
35854 + that you say Y here, unless you run into software incompatibilities.
35855 + If the sysctl option is enabled, a sysctl option with name
35856 + "chroot_deny_mknod" is created.
35857 +
35858 +config GRKERNSEC_CHROOT_SHMAT
35859 + bool "Deny shmat() out of chroot"
35860 + depends on GRKERNSEC_CHROOT
35861 + help
35862 + If you say Y here, processes inside a chroot will not be able to attach
35863 + to shared memory segments that were created outside of the chroot jail.
35864 + It is recommended that you say Y here. If the sysctl option is enabled,
35865 + a sysctl option with name "chroot_deny_shmat" is created.
35866 +
35867 +config GRKERNSEC_CHROOT_UNIX
35868 + bool "Deny access to abstract AF_UNIX sockets out of chroot"
35869 + depends on GRKERNSEC_CHROOT
35870 + help
35871 + If you say Y here, processes inside a chroot will not be able to
35872 + connect to abstract (meaning not belonging to a filesystem) Unix
35873 + domain sockets that were bound outside of a chroot. It is recommended
35874 + that you say Y here. If the sysctl option is enabled, a sysctl option
35875 + with name "chroot_deny_unix" is created.
35876 +
35877 +config GRKERNSEC_CHROOT_FINDTASK
35878 + bool "Protect outside processes"
35879 + depends on GRKERNSEC_CHROOT
35880 + help
35881 + If you say Y here, processes inside a chroot will not be able to
35882 + kill, send signals with fcntl, ptrace, capget, getpgid, setpgid,
35883 + getsid, or view any process outside of the chroot. If the sysctl
35884 + option is enabled, a sysctl option with name "chroot_findtask" is
35885 + created.
35886 +
35887 +config GRKERNSEC_CHROOT_NICE
35888 + bool "Restrict priority changes"
35889 + depends on GRKERNSEC_CHROOT
35890 + help
35891 + If you say Y here, processes inside a chroot will not be able to raise
35892 + the priority of processes in the chroot, or alter the priority of
35893 + processes outside the chroot. This provides more security than simply
35894 + removing CAP_SYS_NICE from the process' capability set. If the
35895 + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
35896 + is created.
35897 +
35898 +config GRKERNSEC_CHROOT_SYSCTL
35899 + bool "Deny sysctl writes"
35900 + depends on GRKERNSEC_CHROOT
35901 + help
35902 + If you say Y here, an attacker in a chroot will not be able to
35903 + write to sysctl entries, either by sysctl(2) or through a /proc
35904 + interface. It is strongly recommended that you say Y here. If the
35905 + sysctl option is enabled, a sysctl option with name
35906 + "chroot_deny_sysctl" is created.
35907 +
35908 +config GRKERNSEC_CHROOT_CAPS
35909 + bool "Capability restrictions"
35910 + depends on GRKERNSEC_CHROOT
35911 + help
35912 + If you say Y here, the capabilities on all root processes within a
35913 + chroot jail will be lowered to stop module insertion, raw i/o,
35914 + system and net admin tasks, rebooting the system, modifying immutable
35915 + files, modifying IPC owned by another, and changing the system time.
35916 + This is left an option because it can break some apps. Disable this
35917 + if your chrooted apps are having problems performing those kinds of
35918 + tasks. If the sysctl option is enabled, a sysctl option with
35919 + name "chroot_caps" is created.
35920 +
35921 +endmenu
35922 +menu "Kernel Auditing"
35923 +depends on GRKERNSEC
35924 +
35925 +config GRKERNSEC_AUDIT_GROUP
35926 + bool "Single group for auditing"
35927 + help
35928 + If you say Y here, the exec, chdir, and (un)mount logging features
35929 + will only operate on a group you specify. This option is recommended
35930 + if you only want to watch certain users instead of having a large
35931 + amount of logs from the entire system. If the sysctl option is enabled,
35932 + a sysctl option with name "audit_group" is created.
35933 +
35934 +config GRKERNSEC_AUDIT_GID
35935 + int "GID for auditing"
35936 + depends on GRKERNSEC_AUDIT_GROUP
35937 + default 1007
35938 +
35939 +config GRKERNSEC_EXECLOG
35940 + bool "Exec logging"
35941 + help
35942 + If you say Y here, all execve() calls will be logged (since the
35943 + other exec*() calls are frontends to execve(), all execution
35944 + will be logged). Useful for shell-servers that like to keep track
35945 + of their users. If the sysctl option is enabled, a sysctl option with
35946 + name "exec_logging" is created.
35947 + WARNING: This option when enabled will produce a LOT of logs, especially
35948 + on an active system.
35949 +
35950 +config GRKERNSEC_RESLOG
35951 + bool "Resource logging"
35952 + help
35953 + If you say Y here, all attempts to overstep resource limits will
35954 + be logged with the resource name, the requested size, and the current
35955 + limit. It is highly recommended that you say Y here. If the sysctl
35956 + option is enabled, a sysctl option with name "resource_logging" is
35957 + created. If the RBAC system is enabled, the sysctl value is ignored.
35958 +
35959 +config GRKERNSEC_CHROOT_EXECLOG
35960 + bool "Log execs within chroot"
35961 + help
35962 + If you say Y here, all executions inside a chroot jail will be logged
35963 + to syslog. This can cause a large amount of logs if certain
35964 + applications (eg. djb's daemontools) are installed on the system, and
35965 + is therefore left as an option. If the sysctl option is enabled, a
35966 + sysctl option with name "chroot_execlog" is created.
35967 +
35968 +config GRKERNSEC_AUDIT_CHDIR
35969 + bool "Chdir logging"
35970 + help
35971 + If you say Y here, all chdir() calls will be logged. If the sysctl
35972 + option is enabled, a sysctl option with name "audit_chdir" is created.
35973 +
35974 +config GRKERNSEC_AUDIT_MOUNT
35975 + bool "(Un)Mount logging"
35976 + help
35977 + If you say Y here, all mounts and unmounts will be logged. If the
35978 + sysctl option is enabled, a sysctl option with name "audit_mount" is
35979 + created.
35980 +
35981 +config GRKERNSEC_SIGNAL
35982 + bool "Signal logging"
35983 + help
35984 + If you say Y here, certain important signals will be logged, such as
35985 + SIGSEGV, which will as a result inform you of when a error in a program
35986 + occurred, which in some cases could mean a possible exploit attempt.
35987 + If the sysctl option is enabled, a sysctl option with name
35988 + "signal_logging" is created.
35989 +
35990 +config GRKERNSEC_FORKFAIL
35991 + bool "Fork failure logging"
35992 + help
35993 + If you say Y here, all failed fork() attempts will be logged.
35994 + This could suggest a fork bomb, or someone attempting to overstep
35995 + their process limit. If the sysctl option is enabled, a sysctl option
35996 + with name "forkfail_logging" is created.
35997 +
35998 +config GRKERNSEC_TIME
35999 + bool "Time change logging"
36000 + help
36001 + If you say Y here, any changes of the system clock will be logged.
36002 + If the sysctl option is enabled, a sysctl option with name
36003 + "timechange_logging" is created.
36004 +
36005 +config GRKERNSEC_PROC_IPADDR
36006 + bool "/proc/<pid>/ipaddr support"
36007 + help
36008 + If you say Y here, a new entry will be added to each /proc/<pid>
36009 + directory that contains the IP address of the person using the task.
36010 + The IP is carried across local TCP and AF_UNIX stream sockets.
36011 + This information can be useful for IDS/IPSes to perform remote response
36012 + to a local attack. The entry is readable by only the owner of the
36013 + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
36014 + the RBAC system), and thus does not create privacy concerns.
36015 +
36016 +config GRKERNSEC_AUDIT_TEXTREL
36017 + bool 'ELF text relocations logging (READ HELP)'
36018 + depends on PAX_MPROTECT
36019 + help
36020 + If you say Y here, text relocations will be logged with the filename
36021 + of the offending library or binary. The purpose of the feature is
36022 + to help Linux distribution developers get rid of libraries and
36023 + binaries that need text relocations which hinder the future progress
36024 + of PaX. Only Linux distribution developers should say Y here, and
36025 + never on a production machine, as this option creates an information
36026 + leak that could aid an attacker in defeating the randomization of
36027 + a single memory region. If the sysctl option is enabled, a sysctl
36028 + option with name "audit_textrel" is created.
36029 +
36030 +endmenu
36031 +
36032 +menu "Executable Protections"
36033 +depends on GRKERNSEC
36034 +
36035 +config GRKERNSEC_EXECVE
36036 + bool "Enforce RLIMIT_NPROC on execs"
36037 + help
36038 + If you say Y here, users with a resource limit on processes will
36039 + have the value checked during execve() calls. The current system
36040 + only checks the system limit during fork() calls. If the sysctl option
36041 + is enabled, a sysctl option with name "execve_limiting" is created.
36042 +
36043 +config GRKERNSEC_DMESG
36044 + bool "Dmesg(8) restriction"
36045 + help
36046 + If you say Y here, non-root users will not be able to use dmesg(8)
36047 + to view up to the last 4kb of messages in the kernel's log buffer.
36048 + If the sysctl option is enabled, a sysctl option with name "dmesg" is
36049 + created.
36050 +
36051 +config GRKERNSEC_HARDEN_PTRACE
36052 + bool "Deter ptrace-based process snooping"
36053 + help
36054 + If you say Y here, TTY sniffers and other malicious monitoring
36055 + programs implemented through ptrace will be defeated. If you
36056 + have been using the RBAC system, this option has already been
36057 + enabled for several years for all users, with the ability to make
36058 + fine-grained exceptions.
36059 +
36060 + This option only affects the ability of non-root users to ptrace
36061 + processes that are not a descendent of the ptracing process.
36062 + This means that strace ./binary and gdb ./binary will still work,
36063 + but attaching to arbitrary processes will not. If the sysctl
36064 + option is enabled, a sysctl option with name "harden_ptrace" is
36065 + created.
36066 +
36067 +config GRKERNSEC_TPE
36068 + bool "Trusted Path Execution (TPE)"
36069 + help
36070 + If you say Y here, you will be able to choose a gid to add to the
36071 + supplementary groups of users you want to mark as "untrusted."
36072 + These users will not be able to execute any files that are not in
36073 + root-owned directories writable only by root. If the sysctl option
36074 + is enabled, a sysctl option with name "tpe" is created.
36075 +
36076 +config GRKERNSEC_TPE_ALL
36077 + bool "Partially restrict non-root users"
36078 + depends on GRKERNSEC_TPE
36079 + help
36080 + If you say Y here, All non-root users other than the ones in the
36081 + group specified in the main TPE option will only be allowed to
36082 + execute files in directories they own that are not group or
36083 + world-writable, or in directories owned by root and writable only by
36084 + root. If the sysctl option is enabled, a sysctl option with name
36085 + "tpe_restrict_all" is created.
36086 +
36087 +config GRKERNSEC_TPE_INVERT
36088 + bool "Invert GID option"
36089 + depends on GRKERNSEC_TPE
36090 + help
36091 + If you say Y here, the group you specify in the TPE configuration will
36092 + decide what group TPE restrictions will be *disabled* for. This
36093 + option is useful if you want TPE restrictions to be applied to most
36094 + users on the system.
36095 +
36096 +config GRKERNSEC_TPE_GID
36097 + int "GID for untrusted users"
36098 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
36099 + default 1005
36100 + help
36101 + If you have selected the "Invert GID option" above, setting this
36102 + GID determines what group TPE restrictions will be *disabled* for.
36103 + If you have not selected the "Invert GID option" above, setting this
36104 + GID determines what group TPE restrictions will be *enabled* for.
36105 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
36106 + is created.
36107 +
36108 +config GRKERNSEC_TPE_GID
36109 + int "GID for trusted users"
36110 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
36111 + default 1005
36112 + help
36113 + If you have selected the "Invert GID option" above, setting this
36114 + GID determines what group TPE restrictions will be *disabled* for.
36115 + If you have not selected the "Invert GID option" above, setting this
36116 + GID determines what group TPE restrictions will be *enabled* for.
36117 + If the sysctl option is enabled, a sysctl option with name "tpe_gid"
36118 + is created.
36119 +
36120 +endmenu
36121 +menu "Network Protections"
36122 +depends on GRKERNSEC
36123 +
36124 +config GRKERNSEC_RANDNET
36125 + bool "Larger entropy pools"
36126 + help
36127 + If you say Y here, the entropy pools used for many features of Linux
36128 + and grsecurity will be doubled in size. Since several grsecurity
36129 + features use additional randomness, it is recommended that you say Y
36130 + here. Saying Y here has a similar effect as modifying
36131 + /proc/sys/kernel/random/poolsize.
36132 +
36133 +config GRKERNSEC_BLACKHOLE
36134 + bool "TCP/UDP blackhole"
36135 + help
36136 + If you say Y here, neither TCP resets nor ICMP
36137 + destination-unreachable packets will be sent in response to packets
36138 + send to ports for which no associated listening process exists.
36139 + This feature supports both IPV4 and IPV6 and exempts the
36140 + loopback interface from blackholing. Enabling this feature
36141 + makes a host more resilient to DoS attacks and reduces network
36142 + visibility against scanners.
36143 +
36144 +config GRKERNSEC_SOCKET
36145 + bool "Socket restrictions"
36146 + help
36147 + If you say Y here, you will be able to choose from several options.
36148 + If you assign a GID on your system and add it to the supplementary
36149 + groups of users you want to restrict socket access to, this patch
36150 + will perform up to three things, based on the option(s) you choose.
36151 +
36152 +config GRKERNSEC_SOCKET_ALL
36153 + bool "Deny any sockets to group"
36154 + depends on GRKERNSEC_SOCKET
36155 + help
36156 + If you say Y here, you will be able to choose a GID of whose users will
36157 + be unable to connect to other hosts from your machine or run server
36158 + applications from your machine. If the sysctl option is enabled, a
36159 + sysctl option with name "socket_all" is created.
36160 +
36161 +config GRKERNSEC_SOCKET_ALL_GID
36162 + int "GID to deny all sockets for"
36163 + depends on GRKERNSEC_SOCKET_ALL
36164 + default 1004
36165 + help
36166 + Here you can choose the GID to disable socket access for. Remember to
36167 + add the users you want socket access disabled for to the GID
36168 + specified here. If the sysctl option is enabled, a sysctl option
36169 + with name "socket_all_gid" is created.
36170 +
36171 +config GRKERNSEC_SOCKET_CLIENT
36172 + bool "Deny client sockets to group"
36173 + depends on GRKERNSEC_SOCKET
36174 + help
36175 + If you say Y here, you will be able to choose a GID of whose users will
36176 + be unable to connect to other hosts from your machine, but will be
36177 + able to run servers. If this option is enabled, all users in the group
36178 + you specify will have to use passive mode when initiating ftp transfers
36179 + from the shell on your machine. If the sysctl option is enabled, a
36180 + sysctl option with name "socket_client" is created.
36181 +
36182 +config GRKERNSEC_SOCKET_CLIENT_GID
36183 + int "GID to deny client sockets for"
36184 + depends on GRKERNSEC_SOCKET_CLIENT
36185 + default 1003
36186 + help
36187 + Here you can choose the GID to disable client socket access for.
36188 + Remember to add the users you want client socket access disabled for to
36189 + the GID specified here. If the sysctl option is enabled, a sysctl
36190 + option with name "socket_client_gid" is created.
36191 +
36192 +config GRKERNSEC_SOCKET_SERVER
36193 + bool "Deny server sockets to group"
36194 + depends on GRKERNSEC_SOCKET
36195 + help
36196 + If you say Y here, you will be able to choose a GID of whose users will
36197 + be unable to run server applications from your machine. If the sysctl
36198 + option is enabled, a sysctl option with name "socket_server" is created.
36199 +
36200 +config GRKERNSEC_SOCKET_SERVER_GID
36201 + int "GID to deny server sockets for"
36202 + depends on GRKERNSEC_SOCKET_SERVER
36203 + default 1002
36204 + help
36205 + Here you can choose the GID to disable server socket access for.
36206 + Remember to add the users you want server socket access disabled for to
36207 + the GID specified here. If the sysctl option is enabled, a sysctl
36208 + option with name "socket_server_gid" is created.
36209 +
36210 +endmenu
36211 +menu "Sysctl support"
36212 +depends on GRKERNSEC && SYSCTL
36213 +
36214 +config GRKERNSEC_SYSCTL
36215 + bool "Sysctl support"
36216 + help
36217 + If you say Y here, you will be able to change the options that
36218 + grsecurity runs with at bootup, without having to recompile your
36219 + kernel. You can echo values to files in /proc/sys/kernel/grsecurity
36220 + to enable (1) or disable (0) various features. All the sysctl entries
36221 + are mutable until the "grsec_lock" entry is set to a non-zero value.
36222 + All features enabled in the kernel configuration are disabled at boot
36223 + if you do not say Y to the "Turn on features by default" option.
36224 + All options should be set at startup, and the grsec_lock entry should
36225 + be set to a non-zero value after all the options are set.
36226 + *THIS IS EXTREMELY IMPORTANT*
36227 +
36228 +config GRKERNSEC_SYSCTL_ON
36229 + bool "Turn on features by default"
36230 + depends on GRKERNSEC_SYSCTL
36231 + help
36232 + If you say Y here, instead of having all features enabled in the
36233 + kernel configuration disabled at boot time, the features will be
36234 + enabled at boot time. It is recommended you say Y here unless
36235 + there is some reason you would want all sysctl-tunable features to
36236 + be disabled by default. As mentioned elsewhere, it is important
36237 + to enable the grsec_lock entry once you have finished modifying
36238 + the sysctl entries.
36239 +
36240 +endmenu
36241 +menu "Logging Options"
36242 +depends on GRKERNSEC
36243 +
36244 +config GRKERNSEC_FLOODTIME
36245 + int "Seconds in between log messages (minimum)"
36246 + default 10
36247 + help
36248 + This option allows you to enforce the number of seconds between
36249 + grsecurity log messages. The default should be suitable for most
36250 + people, however, if you choose to change it, choose a value small enough
36251 + to allow informative logs to be produced, but large enough to
36252 + prevent flooding.
36253 +
36254 +config GRKERNSEC_FLOODBURST
36255 + int "Number of messages in a burst (maximum)"
36256 + default 4
36257 + help
36258 + This option allows you to choose the maximum number of messages allowed
36259 + within the flood time interval you chose in a separate option. The
36260 + default should be suitable for most people, however if you find that
36261 + many of your logs are being interpreted as flooding, you may want to
36262 + raise this value.
36263 +
36264 +endmenu
36265 +
36266 +endmenu
36267 diff -urNp linux-2.6.31.1/grsecurity/Makefile linux-2.6.31.1/grsecurity/Makefile
36268 --- linux-2.6.31.1/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
36269 +++ linux-2.6.31.1/grsecurity/Makefile 2009-10-01 20:12:44.000000000 -0400
36270 @@ -0,0 +1,29 @@
36271 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
36272 +# during 2001-2009 it has been completely redesigned by Brad Spengler
36273 +# into an RBAC system
36274 +#
36275 +# All code in this directory and various hooks inserted throughout the kernel
36276 +# are copyright Brad Spengler - Open Source Security, Inc., and released
36277 +# under the GPL v2 or higher
36278 +
36279 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
36280 + grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
36281 + grsec_time.o grsec_tpe.o grsec_link.o grsec_textrel.o
36282 +
36283 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
36284 + gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
36285 + gracl_learn.o grsec_log.o
36286 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
36287 +
36288 +ifndef CONFIG_GRKERNSEC
36289 +obj-y += grsec_disabled.o
36290 +endif
36291 +
36292 +ifdef CONFIG_GRKERNSEC_HIDESYM
36293 +extra-y := grsec_hidesym.o
36294 +$(obj)/grsec_hidesym.o:
36295 + @-chmod -f 500 /boot
36296 + @-chmod -f 500 /lib/modules
36297 + @-chmod -f 700 .
36298 + @echo ' grsec: protected kernel image paths'
36299 +endif
36300 diff -urNp linux-2.6.31.1/include/asm-generic/atomic.h linux-2.6.31.1/include/asm-generic/atomic.h
36301 --- linux-2.6.31.1/include/asm-generic/atomic.h 2009-09-24 11:45:25.000000000 -0400
36302 +++ linux-2.6.31.1/include/asm-generic/atomic.h 2009-10-01 20:12:44.000000000 -0400
36303 @@ -36,6 +36,15 @@
36304 #define atomic_read(v) ((v)->counter)
36305
36306 /**
36307 + * atomic_read_unchecked - read atomic variable
36308 + * @v: pointer of type atomic_unchecked_t
36309 + *
36310 + * Atomically reads the value of @v. Note that the guaranteed
36311 + * useful range of an atomic_unchecked_t is only 24 bits.
36312 + */
36313 +#define atomic_read_unchecked(v) ((v)->counter)
36314 +
36315 +/**
36316 * atomic_set - set atomic variable
36317 * @v: pointer of type atomic_t
36318 * @i: required value
36319 @@ -45,6 +54,16 @@
36320 */
36321 #define atomic_set(v, i) (((v)->counter) = (i))
36322
36323 +/**
36324 + * atomic_set_unchecked - set atomic variable
36325 + * @v: pointer of type atomic_unchecked_t
36326 + * @i: required value
36327 + *
36328 + * Atomically sets the value of @v to @i. Note that the guaranteed
36329 + * useful range of an atomic_unchecked_t is only 24 bits.
36330 + */
36331 +#define atomic_set_unchecked(v, i) (((v)->counter) = (i))
36332 +
36333 #include <asm/system.h>
36334
36335 /**
36336 @@ -101,16 +120,31 @@ static inline void atomic_add(int i, ato
36337 atomic_add_return(i, v);
36338 }
36339
36340 +static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
36341 +{
36342 + atomic_add_return(i, (atomic_t *)v);
36343 +}
36344 +
36345 static inline void atomic_sub(int i, atomic_t *v)
36346 {
36347 atomic_sub_return(i, v);
36348 }
36349
36350 +static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
36351 +{
36352 + atomic_sub_return(i, (atomic_t *)v);
36353 +}
36354 +
36355 static inline void atomic_inc(atomic_t *v)
36356 {
36357 atomic_add_return(1, v);
36358 }
36359
36360 +static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
36361 +{
36362 + atomic_add_return(1, (atomic_t *)v);
36363 +}
36364 +
36365 static inline void atomic_dec(atomic_t *v)
36366 {
36367 atomic_sub_return(1, v);
36368 diff -urNp linux-2.6.31.1/include/asm-generic/futex.h linux-2.6.31.1/include/asm-generic/futex.h
36369 --- linux-2.6.31.1/include/asm-generic/futex.h 2009-09-24 11:45:25.000000000 -0400
36370 +++ linux-2.6.31.1/include/asm-generic/futex.h 2009-10-01 20:12:44.000000000 -0400
36371 @@ -6,7 +6,7 @@
36372 #include <asm/errno.h>
36373
36374 static inline int
36375 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
36376 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
36377 {
36378 int op = (encoded_op >> 28) & 7;
36379 int cmp = (encoded_op >> 24) & 15;
36380 @@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
36381 }
36382
36383 static inline int
36384 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
36385 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
36386 {
36387 return -ENOSYS;
36388 }
36389 diff -urNp linux-2.6.31.1/include/asm-generic/int-l64.h linux-2.6.31.1/include/asm-generic/int-l64.h
36390 --- linux-2.6.31.1/include/asm-generic/int-l64.h 2009-09-24 11:45:25.000000000 -0400
36391 +++ linux-2.6.31.1/include/asm-generic/int-l64.h 2009-10-01 20:12:44.000000000 -0400
36392 @@ -46,6 +46,8 @@ typedef unsigned int u32;
36393 typedef signed long s64;
36394 typedef unsigned long u64;
36395
36396 +typedef unsigned int intoverflow_t __attribute__ ((mode(TI)));
36397 +
36398 #define S8_C(x) x
36399 #define U8_C(x) x ## U
36400 #define S16_C(x) x
36401 diff -urNp linux-2.6.31.1/include/asm-generic/int-ll64.h linux-2.6.31.1/include/asm-generic/int-ll64.h
36402 --- linux-2.6.31.1/include/asm-generic/int-ll64.h 2009-09-24 11:45:25.000000000 -0400
36403 +++ linux-2.6.31.1/include/asm-generic/int-ll64.h 2009-10-01 20:12:44.000000000 -0400
36404 @@ -51,6 +51,8 @@ typedef unsigned int u32;
36405 typedef signed long long s64;
36406 typedef unsigned long long u64;
36407
36408 +typedef unsigned long long intoverflow_t;
36409 +
36410 #define S8_C(x) x
36411 #define U8_C(x) x ## U
36412 #define S16_C(x) x
36413 diff -urNp linux-2.6.31.1/include/asm-generic/kmap_types.h linux-2.6.31.1/include/asm-generic/kmap_types.h
36414 --- linux-2.6.31.1/include/asm-generic/kmap_types.h 2009-09-24 11:45:25.000000000 -0400
36415 +++ linux-2.6.31.1/include/asm-generic/kmap_types.h 2009-10-01 20:12:44.000000000 -0400
36416 @@ -27,7 +27,8 @@ D(15) KM_UML_USERCOPY, /* UML specific,
36417 D(16) KM_IRQ_PTE,
36418 D(17) KM_NMI,
36419 D(18) KM_NMI_PTE,
36420 -D(19) KM_TYPE_NR
36421 +D(19) KM_CLEARPAGE,
36422 +D(20) KM_TYPE_NR
36423 };
36424
36425 #undef D
36426 diff -urNp linux-2.6.31.1/include/asm-generic/vmlinux.lds.h linux-2.6.31.1/include/asm-generic/vmlinux.lds.h
36427 --- linux-2.6.31.1/include/asm-generic/vmlinux.lds.h 2009-09-24 11:45:25.000000000 -0400
36428 +++ linux-2.6.31.1/include/asm-generic/vmlinux.lds.h 2009-10-01 20:12:44.000000000 -0400
36429 @@ -201,6 +201,7 @@
36430 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
36431 VMLINUX_SYMBOL(__start_rodata) = .; \
36432 *(.rodata) *(.rodata.*) \
36433 + *(.data.read_only) \
36434 *(__vermagic) /* Kernel version magic */ \
36435 *(__markers_strings) /* Markers: strings */ \
36436 *(__tracepoints_strings)/* Tracepoints: strings */ \
36437 @@ -641,22 +642,24 @@
36438 * section in the linker script will go there too. @phdr should have
36439 * a leading colon.
36440 *
36441 - * Note that this macros defines __per_cpu_load as an absolute symbol.
36442 + * Note that this macros defines per_cpu_load as an absolute symbol.
36443 * If there is no need to put the percpu section at a predetermined
36444 * address, use PERCPU().
36445 */
36446 #define PERCPU_VADDR(vaddr, phdr) \
36447 - VMLINUX_SYMBOL(__per_cpu_load) = .; \
36448 - .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
36449 + per_cpu_load = .; \
36450 + .data.percpu vaddr : AT(VMLINUX_SYMBOL(per_cpu_load) \
36451 - LOAD_OFFSET) { \
36452 + VMLINUX_SYMBOL(__per_cpu_load) = . + per_cpu_load; \
36453 VMLINUX_SYMBOL(__per_cpu_start) = .; \
36454 *(.data.percpu.first) \
36455 - *(.data.percpu.page_aligned) \
36456 *(.data.percpu) \
36457 + . = ALIGN(PAGE_SIZE); \
36458 + *(.data.percpu.page_aligned) \
36459 *(.data.percpu.shared_aligned) \
36460 VMLINUX_SYMBOL(__per_cpu_end) = .; \
36461 } phdr \
36462 - . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu);
36463 + . = VMLINUX_SYMBOL(per_cpu_load) + SIZEOF(.data.percpu);
36464
36465 /**
36466 * PERCPU - define output section for percpu area, simple version
36467 diff -urNp linux-2.6.31.1/include/drm/drm_pciids.h linux-2.6.31.1/include/drm/drm_pciids.h
36468 --- linux-2.6.31.1/include/drm/drm_pciids.h 2009-09-24 11:45:25.000000000 -0400
36469 +++ linux-2.6.31.1/include/drm/drm_pciids.h 2009-10-01 20:12:44.000000000 -0400
36470 @@ -375,7 +375,7 @@
36471 {0x1002, 0x9712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
36472 {0x1002, 0x9713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
36473 {0x1002, 0x9714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
36474 - {0, 0, 0}
36475 + {0, 0, 0, 0, 0, 0}
36476
36477 #define r128_PCI_IDS \
36478 {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36479 @@ -415,14 +415,14 @@
36480 {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36481 {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36482 {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36483 - {0, 0, 0}
36484 + {0, 0, 0, 0, 0, 0}
36485
36486 #define mga_PCI_IDS \
36487 {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
36488 {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
36489 {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
36490 {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
36491 - {0, 0, 0}
36492 + {0, 0, 0, 0, 0, 0}
36493
36494 #define mach64_PCI_IDS \
36495 {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36496 @@ -445,7 +445,7 @@
36497 {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36498 {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36499 {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36500 - {0, 0, 0}
36501 + {0, 0, 0, 0, 0, 0}
36502
36503 #define sisdrv_PCI_IDS \
36504 {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36505 @@ -456,7 +456,7 @@
36506 {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36507 {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
36508 {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
36509 - {0, 0, 0}
36510 + {0, 0, 0, 0, 0, 0}
36511
36512 #define tdfx_PCI_IDS \
36513 {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36514 @@ -465,7 +465,7 @@
36515 {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36516 {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36517 {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36518 - {0, 0, 0}
36519 + {0, 0, 0, 0, 0, 0}
36520
36521 #define viadrv_PCI_IDS \
36522 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36523 @@ -477,14 +477,14 @@
36524 {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36525 {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
36526 {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
36527 - {0, 0, 0}
36528 + {0, 0, 0, 0, 0, 0}
36529
36530 #define i810_PCI_IDS \
36531 {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36532 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36533 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36534 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36535 - {0, 0, 0}
36536 + {0, 0, 0, 0, 0, 0}
36537
36538 #define i830_PCI_IDS \
36539 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36540 @@ -492,11 +492,11 @@
36541 {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36542 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36543 {0x8086, 0x358e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36544 - {0, 0, 0}
36545 + {0, 0, 0, 0, 0, 0}
36546
36547 #define gamma_PCI_IDS \
36548 {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
36549 - {0, 0, 0}
36550 + {0, 0, 0, 0, 0, 0}
36551
36552 #define savage_PCI_IDS \
36553 {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
36554 @@ -522,10 +522,10 @@
36555 {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
36556 {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
36557 {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
36558 - {0, 0, 0}
36559 + {0, 0, 0, 0, 0, 0}
36560
36561 #define ffb_PCI_IDS \
36562 - {0, 0, 0}
36563 + {0, 0, 0, 0, 0, 0}
36564
36565 #define i915_PCI_IDS \
36566 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
36567 @@ -557,4 +557,4 @@
36568 {0x8086, 0x35e8, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
36569 {0x8086, 0x0042, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
36570 {0x8086, 0x0046, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
36571 - {0, 0, 0}
36572 + {0, 0, 0, 0, 0, 0}
36573 diff -urNp linux-2.6.31.1/include/drm/drmP.h linux-2.6.31.1/include/drm/drmP.h
36574 --- linux-2.6.31.1/include/drm/drmP.h 2009-09-24 11:45:25.000000000 -0400
36575 +++ linux-2.6.31.1/include/drm/drmP.h 2009-10-01 20:12:44.000000000 -0400
36576 @@ -787,7 +787,7 @@ struct drm_driver {
36577 void (*gem_free_object) (struct drm_gem_object *obj);
36578
36579 /* Driver private ops for this object */
36580 - struct vm_operations_struct *gem_vm_ops;
36581 + const struct vm_operations_struct *gem_vm_ops;
36582
36583 int major;
36584 int minor;
36585 @@ -890,7 +890,7 @@ struct drm_device {
36586
36587 /** \name Usage Counters */
36588 /*@{ */
36589 - int open_count; /**< Outstanding files open */
36590 + atomic_t open_count; /**< Outstanding files open */
36591 atomic_t ioctl_count; /**< Outstanding IOCTLs pending */
36592 atomic_t vma_count; /**< Outstanding vma areas open */
36593 int buf_use; /**< Buffers in use -- cannot alloc */
36594 @@ -901,7 +901,7 @@ struct drm_device {
36595 /*@{ */
36596 unsigned long counters;
36597 enum drm_stat_type types[15];
36598 - atomic_t counts[15];
36599 + atomic_unchecked_t counts[15];
36600 /*@} */
36601
36602 struct list_head filelist;
36603 diff -urNp linux-2.6.31.1/include/linux/agp_backend.h linux-2.6.31.1/include/linux/agp_backend.h
36604 --- linux-2.6.31.1/include/linux/agp_backend.h 2009-09-24 11:45:25.000000000 -0400
36605 +++ linux-2.6.31.1/include/linux/agp_backend.h 2009-10-01 20:12:44.000000000 -0400
36606 @@ -53,7 +53,7 @@ struct agp_kern_info {
36607 int current_memory;
36608 bool cant_use_aperture;
36609 unsigned long page_mask;
36610 - struct vm_operations_struct *vm_ops;
36611 + const struct vm_operations_struct *vm_ops;
36612 };
36613
36614 /*
36615 diff -urNp linux-2.6.31.1/include/linux/a.out.h linux-2.6.31.1/include/linux/a.out.h
36616 --- linux-2.6.31.1/include/linux/a.out.h 2009-09-24 11:45:25.000000000 -0400
36617 +++ linux-2.6.31.1/include/linux/a.out.h 2009-10-01 20:12:44.000000000 -0400
36618 @@ -39,6 +39,14 @@ enum machine_type {
36619 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
36620 };
36621
36622 +/* Constants for the N_FLAGS field */
36623 +#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
36624 +#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
36625 +#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
36626 +#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
36627 +/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
36628 +#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
36629 +
36630 #if !defined (N_MAGIC)
36631 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
36632 #endif
36633 diff -urNp linux-2.6.31.1/include/linux/atmdev.h linux-2.6.31.1/include/linux/atmdev.h
36634 --- linux-2.6.31.1/include/linux/atmdev.h 2009-09-24 11:45:25.000000000 -0400
36635 +++ linux-2.6.31.1/include/linux/atmdev.h 2009-10-01 20:12:44.000000000 -0400
36636 @@ -237,7 +237,7 @@ struct compat_atm_iobuf {
36637 #endif
36638
36639 struct k_atm_aal_stats {
36640 -#define __HANDLE_ITEM(i) atomic_t i
36641 +#define __HANDLE_ITEM(i) atomic_unchecked_t i
36642 __AAL_STAT_ITEMS
36643 #undef __HANDLE_ITEM
36644 };
36645 diff -urNp linux-2.6.31.1/include/linux/binfmts.h linux-2.6.31.1/include/linux/binfmts.h
36646 --- linux-2.6.31.1/include/linux/binfmts.h 2009-09-24 11:45:25.000000000 -0400
36647 +++ linux-2.6.31.1/include/linux/binfmts.h 2009-10-01 20:12:44.000000000 -0400
36648 @@ -78,6 +78,7 @@ struct linux_binfmt {
36649 int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
36650 int (*load_shlib)(struct file *);
36651 int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
36652 + void (*handle_mprotect)(struct vm_area_struct *vma, unsigned long newflags);
36653 unsigned long min_coredump; /* minimal dump size */
36654 int hasvdso;
36655 };
36656 diff -urNp linux-2.6.31.1/include/linux/cache.h linux-2.6.31.1/include/linux/cache.h
36657 --- linux-2.6.31.1/include/linux/cache.h 2009-09-24 11:45:25.000000000 -0400
36658 +++ linux-2.6.31.1/include/linux/cache.h 2009-10-01 20:12:44.000000000 -0400
36659 @@ -16,6 +16,10 @@
36660 #define __read_mostly
36661 #endif
36662
36663 +#ifndef __read_only
36664 +#define __read_only __read_mostly
36665 +#endif
36666 +
36667 #ifndef ____cacheline_aligned
36668 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
36669 #endif
36670 diff -urNp linux-2.6.31.1/include/linux/capability.h linux-2.6.31.1/include/linux/capability.h
36671 --- linux-2.6.31.1/include/linux/capability.h 2009-09-24 11:45:25.000000000 -0400
36672 +++ linux-2.6.31.1/include/linux/capability.h 2009-10-01 20:12:44.000000000 -0400
36673 @@ -563,6 +563,7 @@ extern const kernel_cap_t __cap_init_eff
36674 (security_real_capable_noaudit((t), (cap)) == 0)
36675
36676 extern int capable(int cap);
36677 +int capable_nolog(int cap);
36678
36679 /* audit system wants to get cap info from files as well */
36680 struct dentry;
36681 diff -urNp linux-2.6.31.1/include/linux/cgroup.h linux-2.6.31.1/include/linux/cgroup.h
36682 --- linux-2.6.31.1/include/linux/cgroup.h 2009-09-24 11:45:25.000000000 -0400
36683 +++ linux-2.6.31.1/include/linux/cgroup.h 2009-10-01 20:12:44.000000000 -0400
36684 @@ -37,7 +37,7 @@ extern void cgroup_exit(struct task_stru
36685 extern int cgroupstats_build(struct cgroupstats *stats,
36686 struct dentry *dentry);
36687
36688 -extern struct file_operations proc_cgroup_operations;
36689 +extern const struct file_operations proc_cgroup_operations;
36690
36691 /* Define the enumeration of all cgroup subsystems */
36692 #define SUBSYS(_x) _x ## _subsys_id,
36693 diff -urNp linux-2.6.31.1/include/linux/compiler-gcc4.h linux-2.6.31.1/include/linux/compiler-gcc4.h
36694 --- linux-2.6.31.1/include/linux/compiler-gcc4.h 2009-09-24 11:45:25.000000000 -0400
36695 +++ linux-2.6.31.1/include/linux/compiler-gcc4.h 2009-10-01 20:12:44.000000000 -0400
36696 @@ -36,4 +36,8 @@
36697 the kernel context */
36698 #define __cold __attribute__((__cold__))
36699
36700 +#define __alloc_size(...) __attribute((alloc_size(__VA_ARGS__)))
36701 +#define __bos(ptr, arg) __builtin_object_size((ptr), (arg))
36702 +#define __bos0(ptr) __bos((ptr), 0)
36703 +#define __bos1(ptr) __bos((ptr), 1)
36704 #endif
36705 diff -urNp linux-2.6.31.1/include/linux/compiler.h linux-2.6.31.1/include/linux/compiler.h
36706 --- linux-2.6.31.1/include/linux/compiler.h 2009-09-24 11:45:25.000000000 -0400
36707 +++ linux-2.6.31.1/include/linux/compiler.h 2009-10-01 20:12:44.000000000 -0400
36708 @@ -256,6 +256,22 @@ void ftrace_likely_update(struct ftrace_
36709 #define __cold
36710 #endif
36711
36712 +#ifndef __alloc_size
36713 +#define __alloc_size
36714 +#endif
36715 +
36716 +#ifndef __bos
36717 +#define __bos
36718 +#endif
36719 +
36720 +#ifndef __bos0
36721 +#define __bos0
36722 +#endif
36723 +
36724 +#ifndef __bos1
36725 +#define __bos1
36726 +#endif
36727 +
36728 /* Simple shorthand for a section definition */
36729 #ifndef __section
36730 # define __section(S) __attribute__ ((__section__(#S)))
36731 diff -urNp linux-2.6.31.1/include/linux/cpumask.h linux-2.6.31.1/include/linux/cpumask.h
36732 --- linux-2.6.31.1/include/linux/cpumask.h 2009-09-24 11:45:25.000000000 -0400
36733 +++ linux-2.6.31.1/include/linux/cpumask.h 2009-10-01 20:12:44.000000000 -0400
36734 @@ -142,7 +142,6 @@
36735 #include <linux/bitmap.h>
36736
36737 typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
36738 -extern cpumask_t _unused_cpumask_arg_;
36739
36740 #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS
36741 #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
36742 diff -urNp linux-2.6.31.1/include/linux/decompress/mm.h linux-2.6.31.1/include/linux/decompress/mm.h
36743 --- linux-2.6.31.1/include/linux/decompress/mm.h 2009-09-24 11:45:25.000000000 -0400
36744 +++ linux-2.6.31.1/include/linux/decompress/mm.h 2009-10-01 20:12:44.000000000 -0400
36745 @@ -68,7 +68,7 @@ static void free(void *where)
36746 * warnings when not needed (indeed large_malloc / large_free are not
36747 * needed by inflate */
36748
36749 -#define malloc(a) kmalloc(a, GFP_KERNEL)
36750 +#define malloc(a) kmalloc((a), GFP_KERNEL)
36751 #define free(a) kfree(a)
36752
36753 #define large_malloc(a) vmalloc(a)
36754 diff -urNp linux-2.6.31.1/include/linux/elf.h linux-2.6.31.1/include/linux/elf.h
36755 --- linux-2.6.31.1/include/linux/elf.h 2009-09-24 11:45:25.000000000 -0400
36756 +++ linux-2.6.31.1/include/linux/elf.h 2009-10-01 20:12:44.000000000 -0400
36757 @@ -49,6 +49,17 @@ typedef __s64 Elf64_Sxword;
36758 #define PT_GNU_EH_FRAME 0x6474e550
36759
36760 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
36761 +#define PT_GNU_RELRO (PT_LOOS + 0x474e552)
36762 +
36763 +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
36764 +
36765 +/* Constants for the e_flags field */
36766 +#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
36767 +#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
36768 +#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
36769 +#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
36770 +/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
36771 +#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
36772
36773 /* These constants define the different elf file types */
36774 #define ET_NONE 0
36775 @@ -84,6 +95,8 @@ typedef __s64 Elf64_Sxword;
36776 #define DT_DEBUG 21
36777 #define DT_TEXTREL 22
36778 #define DT_JMPREL 23
36779 +#define DT_FLAGS 30
36780 + #define DF_TEXTREL 0x00000004
36781 #define DT_ENCODING 32
36782 #define OLD_DT_LOOS 0x60000000
36783 #define DT_LOOS 0x6000000d
36784 @@ -230,6 +243,19 @@ typedef struct elf64_hdr {
36785 #define PF_W 0x2
36786 #define PF_X 0x1
36787
36788 +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
36789 +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
36790 +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
36791 +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
36792 +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
36793 +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
36794 +/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
36795 +/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
36796 +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
36797 +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
36798 +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
36799 +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
36800 +
36801 typedef struct elf32_phdr{
36802 Elf32_Word p_type;
36803 Elf32_Off p_offset;
36804 @@ -322,6 +348,8 @@ typedef struct elf64_shdr {
36805 #define EI_OSABI 7
36806 #define EI_PAD 8
36807
36808 +#define EI_PAX 14
36809 +
36810 #define ELFMAG0 0x7f /* EI_MAG */
36811 #define ELFMAG1 'E'
36812 #define ELFMAG2 'L'
36813 @@ -385,6 +413,7 @@ extern Elf32_Dyn _DYNAMIC [];
36814 #define elf_phdr elf32_phdr
36815 #define elf_note elf32_note
36816 #define elf_addr_t Elf32_Off
36817 +#define elf_dyn Elf32_Dyn
36818
36819 #else
36820
36821 @@ -393,6 +422,7 @@ extern Elf64_Dyn _DYNAMIC [];
36822 #define elf_phdr elf64_phdr
36823 #define elf_note elf64_note
36824 #define elf_addr_t Elf64_Off
36825 +#define elf_dyn Elf64_Dyn
36826
36827 #endif
36828
36829 diff -urNp linux-2.6.31.1/include/linux/fs.h linux-2.6.31.1/include/linux/fs.h
36830 --- linux-2.6.31.1/include/linux/fs.h 2009-09-24 11:45:25.000000000 -0400
36831 +++ linux-2.6.31.1/include/linux/fs.h 2009-10-01 20:12:44.000000000 -0400
36832 @@ -87,6 +87,10 @@ struct inodes_stat_t {
36833 */
36834 #define FMODE_NOCMTIME ((__force fmode_t)2048)
36835
36836 +/* Hack for grsec so as not to require read permission simply to execute
36837 + a binary */
36838 +#define FMODE_GREXEC ((__force fmode_t)8192)
36839 +
36840 /*
36841 * The below are the various read and write types that we support. Some of
36842 * them include behavioral modifiers that send information down to the
36843 @@ -2430,7 +2434,7 @@ static int __fops ## _open(struct inode
36844 __simple_attr_check_format(__fmt, 0ull); \
36845 return simple_attr_open(inode, file, __get, __set, __fmt); \
36846 } \
36847 -static struct file_operations __fops = { \
36848 +static const struct file_operations __fops = { \
36849 .owner = THIS_MODULE, \
36850 .open = __fops ## _open, \
36851 .release = simple_attr_release, \
36852 diff -urNp linux-2.6.31.1/include/linux/fs_struct.h linux-2.6.31.1/include/linux/fs_struct.h
36853 --- linux-2.6.31.1/include/linux/fs_struct.h 2009-09-24 11:45:25.000000000 -0400
36854 +++ linux-2.6.31.1/include/linux/fs_struct.h 2009-10-01 20:12:44.000000000 -0400
36855 @@ -4,7 +4,7 @@
36856 #include <linux/path.h>
36857
36858 struct fs_struct {
36859 - int users;
36860 + atomic_t users;
36861 rwlock_t lock;
36862 int umask;
36863 int in_exec;
36864 diff -urNp linux-2.6.31.1/include/linux/genhd.h linux-2.6.31.1/include/linux/genhd.h
36865 --- linux-2.6.31.1/include/linux/genhd.h 2009-09-24 11:45:25.000000000 -0400
36866 +++ linux-2.6.31.1/include/linux/genhd.h 2009-10-01 20:12:44.000000000 -0400
36867 @@ -161,7 +161,7 @@ struct gendisk {
36868
36869 struct timer_rand_state *random;
36870
36871 - atomic_t sync_io; /* RAID */
36872 + atomic_unchecked_t sync_io; /* RAID */
36873 struct work_struct async_notify;
36874 #ifdef CONFIG_BLK_DEV_INTEGRITY
36875 struct blk_integrity *integrity;
36876 diff -urNp linux-2.6.31.1/include/linux/gracl.h linux-2.6.31.1/include/linux/gracl.h
36877 --- linux-2.6.31.1/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
36878 +++ linux-2.6.31.1/include/linux/gracl.h 2009-10-01 20:12:44.000000000 -0400
36879 @@ -0,0 +1,318 @@
36880 +#ifndef GR_ACL_H
36881 +#define GR_ACL_H
36882 +
36883 +#include <linux/grdefs.h>
36884 +#include <linux/resource.h>
36885 +#include <linux/capability.h>
36886 +#include <linux/dcache.h>
36887 +#include <asm/resource.h>
36888 +
36889 +/* Major status information */
36890 +
36891 +#define GR_VERSION "grsecurity 2.1.14"
36892 +#define GRSECURITY_VERSION 0x2114
36893 +
36894 +enum {
36895 + GR_SHUTDOWN = 0,
36896 + GR_ENABLE = 1,
36897 + GR_SPROLE = 2,
36898 + GR_RELOAD = 3,
36899 + GR_SEGVMOD = 4,
36900 + GR_STATUS = 5,
36901 + GR_UNSPROLE = 6,
36902 + GR_PASSSET = 7,
36903 + GR_SPROLEPAM = 8,
36904 +};
36905 +
36906 +/* Password setup definitions
36907 + * kernel/grhash.c */
36908 +enum {
36909 + GR_PW_LEN = 128,
36910 + GR_SALT_LEN = 16,
36911 + GR_SHA_LEN = 32,
36912 +};
36913 +
36914 +enum {
36915 + GR_SPROLE_LEN = 64,
36916 +};
36917 +
36918 +#define GR_NLIMITS 32
36919 +
36920 +/* Begin Data Structures */
36921 +
36922 +struct sprole_pw {
36923 + unsigned char *rolename;
36924 + unsigned char salt[GR_SALT_LEN];
36925 + unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
36926 +};
36927 +
36928 +struct name_entry {
36929 + __u32 key;
36930 + ino_t inode;
36931 + dev_t device;
36932 + char *name;
36933 + __u16 len;
36934 + __u8 deleted;
36935 + struct name_entry *prev;
36936 + struct name_entry *next;
36937 +};
36938 +
36939 +struct inodev_entry {
36940 + struct name_entry *nentry;
36941 + struct inodev_entry *prev;
36942 + struct inodev_entry *next;
36943 +};
36944 +
36945 +struct acl_role_db {
36946 + struct acl_role_label **r_hash;
36947 + __u32 r_size;
36948 +};
36949 +
36950 +struct inodev_db {
36951 + struct inodev_entry **i_hash;
36952 + __u32 i_size;
36953 +};
36954 +
36955 +struct name_db {
36956 + struct name_entry **n_hash;
36957 + __u32 n_size;
36958 +};
36959 +
36960 +struct crash_uid {
36961 + uid_t uid;
36962 + unsigned long expires;
36963 +};
36964 +
36965 +struct gr_hash_struct {
36966 + void **table;
36967 + void **nametable;
36968 + void *first;
36969 + __u32 table_size;
36970 + __u32 used_size;
36971 + int type;
36972 +};
36973 +
36974 +/* Userspace Grsecurity ACL data structures */
36975 +
36976 +struct acl_subject_label {
36977 + char *filename;
36978 + ino_t inode;
36979 + dev_t device;
36980 + __u32 mode;
36981 + kernel_cap_t cap_mask;
36982 + kernel_cap_t cap_lower;
36983 +
36984 + struct rlimit res[GR_NLIMITS];
36985 + __u32 resmask;
36986 +
36987 + __u8 user_trans_type;
36988 + __u8 group_trans_type;
36989 + uid_t *user_transitions;
36990 + gid_t *group_transitions;
36991 + __u16 user_trans_num;
36992 + __u16 group_trans_num;
36993 +
36994 + __u32 ip_proto[8];
36995 + __u32 ip_type;
36996 + struct acl_ip_label **ips;
36997 + __u32 ip_num;
36998 + __u32 inaddr_any_override;
36999 +
37000 + __u32 crashes;
37001 + unsigned long expires;
37002 +
37003 + struct acl_subject_label *parent_subject;
37004 + struct gr_hash_struct *hash;
37005 + struct acl_subject_label *prev;
37006 + struct acl_subject_label *next;
37007 +
37008 + struct acl_object_label **obj_hash;
37009 + __u32 obj_hash_size;
37010 + __u16 pax_flags;
37011 +};
37012 +
37013 +struct role_allowed_ip {
37014 + __u32 addr;
37015 + __u32 netmask;
37016 +
37017 + struct role_allowed_ip *prev;
37018 + struct role_allowed_ip *next;
37019 +};
37020 +
37021 +struct role_transition {
37022 + char *rolename;
37023 +
37024 + struct role_transition *prev;
37025 + struct role_transition *next;
37026 +};
37027 +
37028 +struct acl_role_label {
37029 + char *rolename;
37030 + uid_t uidgid;
37031 + __u16 roletype;
37032 +
37033 + __u16 auth_attempts;
37034 + unsigned long expires;
37035 +
37036 + struct acl_subject_label *root_label;
37037 + struct gr_hash_struct *hash;
37038 +
37039 + struct acl_role_label *prev;
37040 + struct acl_role_label *next;
37041 +
37042 + struct role_transition *transitions;
37043 + struct role_allowed_ip *allowed_ips;
37044 + uid_t *domain_children;
37045 + __u16 domain_child_num;
37046 +
37047 + struct acl_subject_label **subj_hash;
37048 + __u32 subj_hash_size;
37049 +};
37050 +
37051 +struct user_acl_role_db {
37052 + struct acl_role_label **r_table;
37053 + __u32 num_pointers; /* Number of allocations to track */
37054 + __u32 num_roles; /* Number of roles */
37055 + __u32 num_domain_children; /* Number of domain children */
37056 + __u32 num_subjects; /* Number of subjects */
37057 + __u32 num_objects; /* Number of objects */
37058 +};
37059 +
37060 +struct acl_object_label {
37061 + char *filename;
37062 + ino_t inode;
37063 + dev_t device;
37064 + __u32 mode;
37065 +
37066 + struct acl_subject_label *nested;
37067 + struct acl_object_label *globbed;
37068 +
37069 + /* next two structures not used */
37070 +
37071 + struct acl_object_label *prev;
37072 + struct acl_object_label *next;
37073 +};
37074 +
37075 +struct acl_ip_label {
37076 + char *iface;
37077 + __u32 addr;
37078 + __u32 netmask;
37079 + __u16 low, high;
37080 + __u8 mode;
37081 + __u32 type;
37082 + __u32 proto[8];
37083 +
37084 + /* next two structures not used */
37085 +
37086 + struct acl_ip_label *prev;
37087 + struct acl_ip_label *next;
37088 +};
37089 +
37090 +struct gr_arg {
37091 + struct user_acl_role_db role_db;
37092 + unsigned char pw[GR_PW_LEN];
37093 + unsigned char salt[GR_SALT_LEN];
37094 + unsigned char sum[GR_SHA_LEN];
37095 + unsigned char sp_role[GR_SPROLE_LEN];
37096 + struct sprole_pw *sprole_pws;
37097 + dev_t segv_device;
37098 + ino_t segv_inode;
37099 + uid_t segv_uid;
37100 + __u16 num_sprole_pws;
37101 + __u16 mode;
37102 +};
37103 +
37104 +struct gr_arg_wrapper {
37105 + struct gr_arg *arg;
37106 + __u32 version;
37107 + __u32 size;
37108 +};
37109 +
37110 +struct subject_map {
37111 + struct acl_subject_label *user;
37112 + struct acl_subject_label *kernel;
37113 + struct subject_map *prev;
37114 + struct subject_map *next;
37115 +};
37116 +
37117 +struct acl_subj_map_db {
37118 + struct subject_map **s_hash;
37119 + __u32 s_size;
37120 +};
37121 +
37122 +/* End Data Structures Section */
37123 +
37124 +/* Hash functions generated by empirical testing by Brad Spengler
37125 + Makes good use of the low bits of the inode. Generally 0-1 times
37126 + in loop for successful match. 0-3 for unsuccessful match.
37127 + Shift/add algorithm with modulus of table size and an XOR*/
37128 +
37129 +static __inline__ unsigned int
37130 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
37131 +{
37132 + return (((uid << type) + (uid ^ type)) % sz);
37133 +}
37134 +
37135 + static __inline__ unsigned int
37136 +shash(const struct acl_subject_label *userp, const unsigned int sz)
37137 +{
37138 + return ((const unsigned long)userp % sz);
37139 +}
37140 +
37141 +static __inline__ unsigned int
37142 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
37143 +{
37144 + return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
37145 +}
37146 +
37147 +static __inline__ unsigned int
37148 +nhash(const char *name, const __u16 len, const unsigned int sz)
37149 +{
37150 + return full_name_hash((const unsigned char *)name, len) % sz;
37151 +}
37152 +
37153 +#define FOR_EACH_ROLE_START(role,iter) \
37154 + role = NULL; \
37155 + iter = 0; \
37156 + while (iter < acl_role_set.r_size) { \
37157 + if (role == NULL) \
37158 + role = acl_role_set.r_hash[iter]; \
37159 + if (role == NULL) { \
37160 + iter++; \
37161 + continue; \
37162 + }
37163 +
37164 +#define FOR_EACH_ROLE_END(role,iter) \
37165 + role = role->next; \
37166 + if (role == NULL) \
37167 + iter++; \
37168 + }
37169 +
37170 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
37171 + subj = NULL; \
37172 + iter = 0; \
37173 + while (iter < role->subj_hash_size) { \
37174 + if (subj == NULL) \
37175 + subj = role->subj_hash[iter]; \
37176 + if (subj == NULL) { \
37177 + iter++; \
37178 + continue; \
37179 + }
37180 +
37181 +#define FOR_EACH_SUBJECT_END(subj,iter) \
37182 + subj = subj->next; \
37183 + if (subj == NULL) \
37184 + iter++; \
37185 + }
37186 +
37187 +
37188 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
37189 + subj = role->hash->first; \
37190 + while (subj != NULL) {
37191 +
37192 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
37193 + subj = subj->next; \
37194 + }
37195 +
37196 +#endif
37197 +
37198 diff -urNp linux-2.6.31.1/include/linux/gralloc.h linux-2.6.31.1/include/linux/gralloc.h
37199 --- linux-2.6.31.1/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
37200 +++ linux-2.6.31.1/include/linux/gralloc.h 2009-10-01 20:12:44.000000000 -0400
37201 @@ -0,0 +1,9 @@
37202 +#ifndef __GRALLOC_H
37203 +#define __GRALLOC_H
37204 +
37205 +void acl_free_all(void);
37206 +int acl_alloc_stack_init(unsigned long size);
37207 +void *acl_alloc(unsigned long len);
37208 +void *acl_alloc_num(unsigned long num, unsigned long len);
37209 +
37210 +#endif
37211 diff -urNp linux-2.6.31.1/include/linux/grdefs.h linux-2.6.31.1/include/linux/grdefs.h
37212 --- linux-2.6.31.1/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
37213 +++ linux-2.6.31.1/include/linux/grdefs.h 2009-10-01 20:12:44.000000000 -0400
37214 @@ -0,0 +1,136 @@
37215 +#ifndef GRDEFS_H
37216 +#define GRDEFS_H
37217 +
37218 +/* Begin grsecurity status declarations */
37219 +
37220 +enum {
37221 + GR_READY = 0x01,
37222 + GR_STATUS_INIT = 0x00 // disabled state
37223 +};
37224 +
37225 +/* Begin ACL declarations */
37226 +
37227 +/* Role flags */
37228 +
37229 +enum {
37230 + GR_ROLE_USER = 0x0001,
37231 + GR_ROLE_GROUP = 0x0002,
37232 + GR_ROLE_DEFAULT = 0x0004,
37233 + GR_ROLE_SPECIAL = 0x0008,
37234 + GR_ROLE_AUTH = 0x0010,
37235 + GR_ROLE_NOPW = 0x0020,
37236 + GR_ROLE_GOD = 0x0040,
37237 + GR_ROLE_LEARN = 0x0080,
37238 + GR_ROLE_TPE = 0x0100,
37239 + GR_ROLE_DOMAIN = 0x0200,
37240 + GR_ROLE_PAM = 0x0400
37241 +};
37242 +
37243 +/* ACL Subject and Object mode flags */
37244 +enum {
37245 + GR_DELETED = 0x80000000
37246 +};
37247 +
37248 +/* ACL Object-only mode flags */
37249 +enum {
37250 + GR_READ = 0x00000001,
37251 + GR_APPEND = 0x00000002,
37252 + GR_WRITE = 0x00000004,
37253 + GR_EXEC = 0x00000008,
37254 + GR_FIND = 0x00000010,
37255 + GR_INHERIT = 0x00000020,
37256 + GR_SETID = 0x00000040,
37257 + GR_CREATE = 0x00000080,
37258 + GR_DELETE = 0x00000100,
37259 + GR_LINK = 0x00000200,
37260 + GR_AUDIT_READ = 0x00000400,
37261 + GR_AUDIT_APPEND = 0x00000800,
37262 + GR_AUDIT_WRITE = 0x00001000,
37263 + GR_AUDIT_EXEC = 0x00002000,
37264 + GR_AUDIT_FIND = 0x00004000,
37265 + GR_AUDIT_INHERIT= 0x00008000,
37266 + GR_AUDIT_SETID = 0x00010000,
37267 + GR_AUDIT_CREATE = 0x00020000,
37268 + GR_AUDIT_DELETE = 0x00040000,
37269 + GR_AUDIT_LINK = 0x00080000,
37270 + GR_PTRACERD = 0x00100000,
37271 + GR_NOPTRACE = 0x00200000,
37272 + GR_SUPPRESS = 0x00400000,
37273 + GR_NOLEARN = 0x00800000
37274 +};
37275 +
37276 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
37277 + GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
37278 + GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
37279 +
37280 +/* ACL subject-only mode flags */
37281 +enum {
37282 + GR_KILL = 0x00000001,
37283 + GR_VIEW = 0x00000002,
37284 + GR_PROTECTED = 0x00000004,
37285 + GR_LEARN = 0x00000008,
37286 + GR_OVERRIDE = 0x00000010,
37287 + /* just a placeholder, this mode is only used in userspace */
37288 + GR_DUMMY = 0x00000020,
37289 + GR_PROTSHM = 0x00000040,
37290 + GR_KILLPROC = 0x00000080,
37291 + GR_KILLIPPROC = 0x00000100,
37292 + /* just a placeholder, this mode is only used in userspace */
37293 + GR_NOTROJAN = 0x00000200,
37294 + GR_PROTPROCFD = 0x00000400,
37295 + GR_PROCACCT = 0x00000800,
37296 + GR_RELAXPTRACE = 0x00001000,
37297 + GR_NESTED = 0x00002000,
37298 + GR_INHERITLEARN = 0x00004000,
37299 + GR_PROCFIND = 0x00008000,
37300 + GR_POVERRIDE = 0x00010000,
37301 + GR_KERNELAUTH = 0x00020000,
37302 +};
37303 +
37304 +enum {
37305 + GR_PAX_ENABLE_SEGMEXEC = 0x0001,
37306 + GR_PAX_ENABLE_PAGEEXEC = 0x0002,
37307 + GR_PAX_ENABLE_MPROTECT = 0x0004,
37308 + GR_PAX_ENABLE_RANDMMAP = 0x0008,
37309 + GR_PAX_ENABLE_EMUTRAMP = 0x0010,
37310 + GR_PAX_DISABLE_SEGMEXEC = 0x0100,
37311 + GR_PAX_DISABLE_PAGEEXEC = 0x0200,
37312 + GR_PAX_DISABLE_MPROTECT = 0x0400,
37313 + GR_PAX_DISABLE_RANDMMAP = 0x0800,
37314 + GR_PAX_DISABLE_EMUTRAMP = 0x1000,
37315 +};
37316 +
37317 +enum {
37318 + GR_ID_USER = 0x01,
37319 + GR_ID_GROUP = 0x02,
37320 +};
37321 +
37322 +enum {
37323 + GR_ID_ALLOW = 0x01,
37324 + GR_ID_DENY = 0x02,
37325 +};
37326 +
37327 +#define GR_CRASH_RES 31
37328 +#define GR_UIDTABLE_MAX 500
37329 +
37330 +/* begin resource learning section */
37331 +enum {
37332 + GR_RLIM_CPU_BUMP = 60,
37333 + GR_RLIM_FSIZE_BUMP = 50000,
37334 + GR_RLIM_DATA_BUMP = 10000,
37335 + GR_RLIM_STACK_BUMP = 1000,
37336 + GR_RLIM_CORE_BUMP = 10000,
37337 + GR_RLIM_RSS_BUMP = 500000,
37338 + GR_RLIM_NPROC_BUMP = 1,
37339 + GR_RLIM_NOFILE_BUMP = 5,
37340 + GR_RLIM_MEMLOCK_BUMP = 50000,
37341 + GR_RLIM_AS_BUMP = 500000,
37342 + GR_RLIM_LOCKS_BUMP = 2,
37343 + GR_RLIM_SIGPENDING_BUMP = 5,
37344 + GR_RLIM_MSGQUEUE_BUMP = 10000,
37345 + GR_RLIM_NICE_BUMP = 1,
37346 + GR_RLIM_RTPRIO_BUMP = 1,
37347 + GR_RLIM_RTTIME_BUMP = 1000000
37348 +};
37349 +
37350 +#endif
37351 diff -urNp linux-2.6.31.1/include/linux/grinternal.h linux-2.6.31.1/include/linux/grinternal.h
37352 --- linux-2.6.31.1/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
37353 +++ linux-2.6.31.1/include/linux/grinternal.h 2009-10-01 21:50:27.000000000 -0400
37354 @@ -0,0 +1,211 @@
37355 +#ifndef __GRINTERNAL_H
37356 +#define __GRINTERNAL_H
37357 +
37358 +#ifdef CONFIG_GRKERNSEC
37359 +
37360 +#include <linux/fs.h>
37361 +#include <linux/mnt_namespace.h>
37362 +#include <linux/nsproxy.h>
37363 +#include <linux/gracl.h>
37364 +#include <linux/grdefs.h>
37365 +#include <linux/grmsg.h>
37366 +
37367 +void gr_add_learn_entry(const char *fmt, ...)
37368 + __attribute__ ((format (printf, 1, 2)));
37369 +__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
37370 + const struct vfsmount *mnt);
37371 +__u32 gr_check_create(const struct dentry *new_dentry,
37372 + const struct dentry *parent,
37373 + const struct vfsmount *mnt, const __u32 mode);
37374 +int gr_check_protected_task(const struct task_struct *task);
37375 +__u32 to_gr_audit(const __u32 reqmode);
37376 +int gr_set_acls(const int type);
37377 +
37378 +int gr_acl_is_enabled(void);
37379 +char gr_roletype_to_char(void);
37380 +
37381 +void gr_handle_alertkill(struct task_struct *task);
37382 +char *gr_to_filename(const struct dentry *dentry,
37383 + const struct vfsmount *mnt);
37384 +char *gr_to_filename1(const struct dentry *dentry,
37385 + const struct vfsmount *mnt);
37386 +char *gr_to_filename2(const struct dentry *dentry,
37387 + const struct vfsmount *mnt);
37388 +char *gr_to_filename3(const struct dentry *dentry,
37389 + const struct vfsmount *mnt);
37390 +
37391 +extern int grsec_enable_harden_ptrace;
37392 +extern int grsec_enable_link;
37393 +extern int grsec_enable_fifo;
37394 +extern int grsec_enable_execve;
37395 +extern int grsec_enable_shm;
37396 +extern int grsec_enable_execlog;
37397 +extern int grsec_enable_signal;
37398 +extern int grsec_enable_forkfail;
37399 +extern int grsec_enable_time;
37400 +extern int grsec_enable_chroot_shmat;
37401 +extern int grsec_enable_chroot_findtask;
37402 +extern int grsec_enable_chroot_mount;
37403 +extern int grsec_enable_chroot_double;
37404 +extern int grsec_enable_chroot_pivot;
37405 +extern int grsec_enable_chroot_chdir;
37406 +extern int grsec_enable_chroot_chmod;
37407 +extern int grsec_enable_chroot_mknod;
37408 +extern int grsec_enable_chroot_fchdir;
37409 +extern int grsec_enable_chroot_nice;
37410 +extern int grsec_enable_chroot_execlog;
37411 +extern int grsec_enable_chroot_caps;
37412 +extern int grsec_enable_chroot_sysctl;
37413 +extern int grsec_enable_chroot_unix;
37414 +extern int grsec_enable_tpe;
37415 +extern int grsec_tpe_gid;
37416 +extern int grsec_enable_tpe_all;
37417 +extern int grsec_enable_sidcaps;
37418 +extern int grsec_enable_socket_all;
37419 +extern int grsec_socket_all_gid;
37420 +extern int grsec_enable_socket_client;
37421 +extern int grsec_socket_client_gid;
37422 +extern int grsec_enable_socket_server;
37423 +extern int grsec_socket_server_gid;
37424 +extern int grsec_audit_gid;
37425 +extern int grsec_enable_group;
37426 +extern int grsec_enable_audit_textrel;
37427 +extern int grsec_enable_mount;
37428 +extern int grsec_enable_chdir;
37429 +extern int grsec_resource_logging;
37430 +extern int grsec_lock;
37431 +
37432 +extern spinlock_t grsec_alert_lock;
37433 +extern unsigned long grsec_alert_wtime;
37434 +extern unsigned long grsec_alert_fyet;
37435 +
37436 +extern spinlock_t grsec_audit_lock;
37437 +
37438 +extern rwlock_t grsec_exec_file_lock;
37439 +
37440 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
37441 + gr_to_filename2(tsk->exec_file->f_path.dentry, \
37442 + tsk->exec_file->f_vfsmnt) : "/")
37443 +
37444 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
37445 + gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
37446 + tsk->parent->exec_file->f_vfsmnt) : "/")
37447 +
37448 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
37449 + gr_to_filename(tsk->exec_file->f_path.dentry, \
37450 + tsk->exec_file->f_vfsmnt) : "/")
37451 +
37452 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
37453 + gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
37454 + tsk->parent->exec_file->f_vfsmnt) : "/")
37455 +
37456 +#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
37457 + ((init_task.fs->root.dentry != tsk_a->fs->root.dentry) && \
37458 + (tsk_a->nsproxy->mnt_ns->root->mnt_root != \
37459 + tsk_a->fs->root.dentry)))
37460 +
37461 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
37462 + (tsk_a->fs->root.dentry == tsk_b->fs->root.dentry))
37463 +
37464 +#define DEFAULTSECARGS(task, cred, pcred) gr_task_fullpath(task), task->comm, \
37465 + task->pid, cred->uid, \
37466 + cred->euid, cred->gid, cred->egid, \
37467 + gr_parent_task_fullpath(task), \
37468 + task->parent->comm, task->parent->pid, \
37469 + pcred->uid, pcred->euid, \
37470 + pcred->gid, pcred->egid
37471 +
37472 +#define GR_CHROOT_CAPS {{ \
37473 + CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
37474 + CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
37475 + CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
37476 + CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
37477 + CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
37478 + CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
37479 +
37480 +#define security_learn(normal_msg,args...) \
37481 +({ \
37482 + read_lock(&grsec_exec_file_lock); \
37483 + gr_add_learn_entry(normal_msg "\n", ## args); \
37484 + read_unlock(&grsec_exec_file_lock); \
37485 +})
37486 +
37487 +enum {
37488 + GR_DO_AUDIT,
37489 + GR_DONT_AUDIT,
37490 + GR_DONT_AUDIT_GOOD
37491 +};
37492 +
37493 +enum {
37494 + GR_TTYSNIFF,
37495 + GR_RBAC,
37496 + GR_RBAC_STR,
37497 + GR_STR_RBAC,
37498 + GR_RBAC_MODE2,
37499 + GR_RBAC_MODE3,
37500 + GR_FILENAME,
37501 + GR_SYSCTL_HIDDEN,
37502 + GR_NOARGS,
37503 + GR_ONE_INT,
37504 + GR_ONE_INT_TWO_STR,
37505 + GR_ONE_STR,
37506 + GR_STR_INT,
37507 + GR_TWO_INT,
37508 + GR_THREE_INT,
37509 + GR_FIVE_INT_TWO_STR,
37510 + GR_TWO_STR,
37511 + GR_THREE_STR,
37512 + GR_FOUR_STR,
37513 + GR_STR_FILENAME,
37514 + GR_FILENAME_STR,
37515 + GR_FILENAME_TWO_INT,
37516 + GR_FILENAME_TWO_INT_STR,
37517 + GR_TEXTREL,
37518 + GR_PTRACE,
37519 + GR_RESOURCE,
37520 + GR_CAP,
37521 + GR_SIG,
37522 + GR_SIG2,
37523 + GR_CRASH1,
37524 + GR_CRASH2,
37525 + GR_PSACCT
37526 +};
37527 +
37528 +#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
37529 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
37530 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
37531 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
37532 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
37533 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
37534 +#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)
37535 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
37536 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
37537 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
37538 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
37539 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
37540 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
37541 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
37542 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
37543 +#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)
37544 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
37545 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
37546 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
37547 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
37548 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
37549 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
37550 +#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)
37551 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
37552 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
37553 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
37554 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
37555 +#define gr_log_sig_addr(audit, msg, str, addr) gr_log_varargs(audit, msg, GR_SIG, str, addr)
37556 +#define gr_log_sig_task(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG2, task, num)
37557 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
37558 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
37559 +#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)
37560 +
37561 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
37562 +
37563 +#endif
37564 +
37565 +#endif
37566 diff -urNp linux-2.6.31.1/include/linux/grmsg.h linux-2.6.31.1/include/linux/grmsg.h
37567 --- linux-2.6.31.1/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
37568 +++ linux-2.6.31.1/include/linux/grmsg.h 2009-10-01 20:12:44.000000000 -0400
37569 @@ -0,0 +1,103 @@
37570 +#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"
37571 +#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"
37572 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
37573 +#define GR_STOPMOD_MSG "denied modification of module state by "
37574 +#define GR_IOPERM_MSG "denied use of ioperm() by "
37575 +#define GR_IOPL_MSG "denied use of iopl() by "
37576 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
37577 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
37578 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
37579 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
37580 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
37581 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
37582 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
37583 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
37584 +#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"
37585 +#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"
37586 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
37587 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
37588 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
37589 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
37590 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
37591 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
37592 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
37593 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
37594 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
37595 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
37596 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
37597 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
37598 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
37599 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
37600 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
37601 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
37602 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
37603 +#define GR_NPROC_MSG "denied overstep of process limit by "
37604 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
37605 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
37606 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
37607 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
37608 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
37609 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
37610 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
37611 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
37612 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
37613 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
37614 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
37615 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
37616 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
37617 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
37618 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
37619 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
37620 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
37621 +#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"
37622 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
37623 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
37624 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
37625 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
37626 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
37627 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
37628 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
37629 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
37630 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
37631 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
37632 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
37633 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
37634 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
37635 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
37636 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
37637 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
37638 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
37639 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
37640 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
37641 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
37642 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
37643 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
37644 +#define GR_NICE_CHROOT_MSG "denied priority change by "
37645 +#define GR_UNISIGLOG_MSG "%.32s occurred at %p in "
37646 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
37647 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
37648 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
37649 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
37650 +#define GR_TIME_MSG "time set by "
37651 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
37652 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
37653 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
37654 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
37655 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
37656 +#define GR_BIND_MSG "denied bind() by "
37657 +#define GR_CONNECT_MSG "denied connect() by "
37658 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
37659 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
37660 +#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"
37661 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
37662 +#define GR_CAP_ACL_MSG "use of %s denied for "
37663 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
37664 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
37665 +#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
37666 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
37667 +#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
37668 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
37669 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
37670 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
37671 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
37672 +#define GR_NONROOT_MODLOAD_MSG "denied kernel module auto-load of %.64s by "
37673 diff -urNp linux-2.6.31.1/include/linux/grsecurity.h linux-2.6.31.1/include/linux/grsecurity.h
37674 --- linux-2.6.31.1/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
37675 +++ linux-2.6.31.1/include/linux/grsecurity.h 2009-10-01 20:12:44.000000000 -0400
37676 @@ -0,0 +1,197 @@
37677 +#ifndef GR_SECURITY_H
37678 +#define GR_SECURITY_H
37679 +#include <linux/fs.h>
37680 +#include <linux/fs_struct.h>
37681 +#include <linux/binfmts.h>
37682 +#include <linux/gracl.h>
37683 +
37684 +/* notify of brain-dead configs */
37685 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
37686 +#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
37687 +#endif
37688 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
37689 +#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
37690 +#endif
37691 +#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
37692 +#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
37693 +#endif
37694 +#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
37695 +#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
37696 +#endif
37697 +#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
37698 +#error "CONFIG_PAX enabled, but no PaX options are enabled."
37699 +#endif
37700 +
37701 +void gr_handle_brute_attach(struct task_struct *p);
37702 +void gr_handle_brute_check(void);
37703 +
37704 +char gr_roletype_to_char(void);
37705 +
37706 +int gr_check_user_change(int real, int effective, int fs);
37707 +int gr_check_group_change(int real, int effective, int fs);
37708 +
37709 +void gr_del_task_from_ip_table(struct task_struct *p);
37710 +
37711 +int gr_pid_is_chrooted(struct task_struct *p);
37712 +int gr_handle_chroot_nice(void);
37713 +int gr_handle_chroot_sysctl(const int op);
37714 +int gr_handle_chroot_setpriority(struct task_struct *p,
37715 + const int niceval);
37716 +int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
37717 +int gr_handle_chroot_chroot(const struct dentry *dentry,
37718 + const struct vfsmount *mnt);
37719 +int gr_handle_chroot_caps(struct path *path);
37720 +void gr_handle_chroot_chdir(struct path *path);
37721 +int gr_handle_chroot_chmod(const struct dentry *dentry,
37722 + const struct vfsmount *mnt, const int mode);
37723 +int gr_handle_chroot_mknod(const struct dentry *dentry,
37724 + const struct vfsmount *mnt, const int mode);
37725 +int gr_handle_chroot_mount(const struct dentry *dentry,
37726 + const struct vfsmount *mnt,
37727 + const char *dev_name);
37728 +int gr_handle_chroot_pivot(void);
37729 +int gr_handle_chroot_unix(const pid_t pid);
37730 +
37731 +int gr_handle_rawio(const struct inode *inode);
37732 +int gr_handle_nproc(void);
37733 +
37734 +void gr_handle_ioperm(void);
37735 +void gr_handle_iopl(void);
37736 +
37737 +int gr_tpe_allow(const struct file *file);
37738 +
37739 +int gr_random_pid(void);
37740 +
37741 +void gr_log_forkfail(const int retval);
37742 +void gr_log_timechange(void);
37743 +void gr_log_signal(const int sig, const void *addr, const struct task_struct *t);
37744 +void gr_log_chdir(const struct dentry *dentry,
37745 + const struct vfsmount *mnt);
37746 +void gr_log_chroot_exec(const struct dentry *dentry,
37747 + const struct vfsmount *mnt);
37748 +void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
37749 +void gr_log_remount(const char *devname, const int retval);
37750 +void gr_log_unmount(const char *devname, const int retval);
37751 +void gr_log_mount(const char *from, const char *to, const int retval);
37752 +void gr_log_textrel(struct vm_area_struct *vma);
37753 +
37754 +int gr_handle_follow_link(const struct inode *parent,
37755 + const struct inode *inode,
37756 + const struct dentry *dentry,
37757 + const struct vfsmount *mnt);
37758 +int gr_handle_fifo(const struct dentry *dentry,
37759 + const struct vfsmount *mnt,
37760 + const struct dentry *dir, const int flag,
37761 + const int acc_mode);
37762 +int gr_handle_hardlink(const struct dentry *dentry,
37763 + const struct vfsmount *mnt,
37764 + struct inode *inode,
37765 + const int mode, const char *to);
37766 +
37767 +int gr_is_capable(const int cap);
37768 +int gr_is_capable_nolog(const int cap);
37769 +void gr_learn_resource(const struct task_struct *task, const int limit,
37770 + const unsigned long wanted, const int gt);
37771 +void gr_copy_label(struct task_struct *tsk);
37772 +void gr_handle_crash(struct task_struct *task, const int sig);
37773 +int gr_handle_signal(const struct task_struct *p, const int sig);
37774 +int gr_check_crash_uid(const uid_t uid);
37775 +int gr_check_protected_task(const struct task_struct *task);
37776 +int gr_acl_handle_mmap(const struct file *file,
37777 + const unsigned long prot);
37778 +int gr_acl_handle_mprotect(const struct file *file,
37779 + const unsigned long prot);
37780 +int gr_check_hidden_task(const struct task_struct *tsk);
37781 +__u32 gr_acl_handle_truncate(const struct dentry *dentry,
37782 + const struct vfsmount *mnt);
37783 +__u32 gr_acl_handle_utime(const struct dentry *dentry,
37784 + const struct vfsmount *mnt);
37785 +__u32 gr_acl_handle_access(const struct dentry *dentry,
37786 + const struct vfsmount *mnt, const int fmode);
37787 +__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
37788 + const struct vfsmount *mnt, mode_t mode);
37789 +__u32 gr_acl_handle_chmod(const struct dentry *dentry,
37790 + const struct vfsmount *mnt, mode_t mode);
37791 +__u32 gr_acl_handle_chown(const struct dentry *dentry,
37792 + const struct vfsmount *mnt);
37793 +int gr_handle_ptrace(struct task_struct *task, const long request);
37794 +int gr_handle_proc_ptrace(struct task_struct *task);
37795 +__u32 gr_acl_handle_execve(const struct dentry *dentry,
37796 + const struct vfsmount *mnt);
37797 +int gr_check_crash_exec(const struct file *filp);
37798 +int gr_acl_is_enabled(void);
37799 +void gr_set_kernel_label(struct task_struct *task);
37800 +void gr_set_role_label(struct task_struct *task, const uid_t uid,
37801 + const gid_t gid);
37802 +int gr_set_proc_label(const struct dentry *dentry,
37803 + const struct vfsmount *mnt,
37804 + const int unsafe_share);
37805 +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
37806 + const struct vfsmount *mnt);
37807 +__u32 gr_acl_handle_open(const struct dentry *dentry,
37808 + const struct vfsmount *mnt, const int fmode);
37809 +__u32 gr_acl_handle_creat(const struct dentry *dentry,
37810 + const struct dentry *p_dentry,
37811 + const struct vfsmount *p_mnt, const int fmode,
37812 + const int imode);
37813 +void gr_handle_create(const struct dentry *dentry,
37814 + const struct vfsmount *mnt);
37815 +__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
37816 + const struct dentry *parent_dentry,
37817 + const struct vfsmount *parent_mnt,
37818 + const int mode);
37819 +__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
37820 + const struct dentry *parent_dentry,
37821 + const struct vfsmount *parent_mnt);
37822 +__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
37823 + const struct vfsmount *mnt);
37824 +void gr_handle_delete(const ino_t ino, const dev_t dev);
37825 +__u32 gr_acl_handle_unlink(const struct dentry *dentry,
37826 + const struct vfsmount *mnt);
37827 +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
37828 + const struct dentry *parent_dentry,
37829 + const struct vfsmount *parent_mnt,
37830 + const char *from);
37831 +__u32 gr_acl_handle_link(const struct dentry *new_dentry,
37832 + const struct dentry *parent_dentry,
37833 + const struct vfsmount *parent_mnt,
37834 + const struct dentry *old_dentry,
37835 + const struct vfsmount *old_mnt, const char *to);
37836 +int gr_acl_handle_rename(struct dentry *new_dentry,
37837 + struct dentry *parent_dentry,
37838 + const struct vfsmount *parent_mnt,
37839 + struct dentry *old_dentry,
37840 + struct inode *old_parent_inode,
37841 + struct vfsmount *old_mnt, const char *newname);
37842 +void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
37843 + struct dentry *old_dentry,
37844 + struct dentry *new_dentry,
37845 + struct vfsmount *mnt, const __u8 replace);
37846 +__u32 gr_check_link(const struct dentry *new_dentry,
37847 + const struct dentry *parent_dentry,
37848 + const struct vfsmount *parent_mnt,
37849 + const struct dentry *old_dentry,
37850 + const struct vfsmount *old_mnt);
37851 +int gr_acl_handle_filldir(const struct file *file, const char *name,
37852 + const unsigned int namelen, const ino_t ino);
37853 +
37854 +__u32 gr_acl_handle_unix(const struct dentry *dentry,
37855 + const struct vfsmount *mnt);
37856 +void gr_acl_handle_exit(void);
37857 +void gr_acl_handle_psacct(struct task_struct *task, const long code);
37858 +int gr_acl_handle_procpidmem(const struct task_struct *task);
37859 +
37860 +#ifdef CONFIG_GRKERNSEC
37861 +void gr_log_nonroot_mod_load(const char *modname);
37862 +void gr_handle_mem_write(void);
37863 +void gr_handle_kmem_write(void);
37864 +void gr_handle_open_port(void);
37865 +int gr_handle_mem_mmap(const unsigned long offset,
37866 + struct vm_area_struct *vma);
37867 +
37868 +extern int grsec_enable_dmesg;
37869 +extern int grsec_enable_randsrc;
37870 +extern int grsec_enable_shm;
37871 +#endif
37872 +
37873 +#endif
37874 diff -urNp linux-2.6.31.1/include/linux/hdpu_features.h linux-2.6.31.1/include/linux/hdpu_features.h
37875 --- linux-2.6.31.1/include/linux/hdpu_features.h 2009-09-24 11:45:25.000000000 -0400
37876 +++ linux-2.6.31.1/include/linux/hdpu_features.h 2009-10-01 20:12:44.000000000 -0400
37877 @@ -3,7 +3,7 @@
37878 struct cpustate_t {
37879 spinlock_t lock;
37880 int excl;
37881 - int open_count;
37882 + atomic_t open_count;
37883 unsigned char cached_val;
37884 int inited;
37885 unsigned long *set_addr;
37886 diff -urNp linux-2.6.31.1/include/linux/highmem.h linux-2.6.31.1/include/linux/highmem.h
37887 --- linux-2.6.31.1/include/linux/highmem.h 2009-09-24 11:45:25.000000000 -0400
37888 +++ linux-2.6.31.1/include/linux/highmem.h 2009-10-01 20:12:44.000000000 -0400
37889 @@ -137,6 +137,18 @@ static inline void clear_highpage(struct
37890 kunmap_atomic(kaddr, KM_USER0);
37891 }
37892
37893 +static inline void sanitize_highpage(struct page *page)
37894 +{
37895 + void *kaddr;
37896 + unsigned long flags;
37897 +
37898 + local_irq_save(flags);
37899 + kaddr = kmap_atomic(page, KM_CLEARPAGE);
37900 + clear_page(kaddr);
37901 + kunmap_atomic(kaddr, KM_CLEARPAGE);
37902 + local_irq_restore(flags);
37903 +}
37904 +
37905 static inline void zero_user_segments(struct page *page,
37906 unsigned start1, unsigned end1,
37907 unsigned start2, unsigned end2)
37908 diff -urNp linux-2.6.31.1/include/linux/hugetlb.h linux-2.6.31.1/include/linux/hugetlb.h
37909 --- linux-2.6.31.1/include/linux/hugetlb.h 2009-09-24 11:45:25.000000000 -0400
37910 +++ linux-2.6.31.1/include/linux/hugetlb.h 2009-10-01 20:12:44.000000000 -0400
37911 @@ -146,7 +146,7 @@ static inline struct hugetlbfs_sb_info *
37912 }
37913
37914 extern const struct file_operations hugetlbfs_file_operations;
37915 -extern struct vm_operations_struct hugetlb_vm_ops;
37916 +extern const struct vm_operations_struct hugetlb_vm_ops;
37917 struct file *hugetlb_file_setup(const char *name, size_t size, int acct,
37918 struct user_struct **user);
37919 int hugetlb_get_quota(struct address_space *mapping, long delta);
37920 diff -urNp linux-2.6.31.1/include/linux/jbd2.h linux-2.6.31.1/include/linux/jbd2.h
37921 --- linux-2.6.31.1/include/linux/jbd2.h 2009-09-24 11:45:25.000000000 -0400
37922 +++ linux-2.6.31.1/include/linux/jbd2.h 2009-10-01 20:12:44.000000000 -0400
37923 @@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
37924 } \
37925 } while (0)
37926 #else
37927 -#define jbd_debug(f, a...) /**/
37928 +#define jbd_debug(f, a...) do {} while (0)
37929 #endif
37930
37931 static inline void *jbd2_alloc(size_t size, gfp_t flags)
37932 diff -urNp linux-2.6.31.1/include/linux/jbd.h linux-2.6.31.1/include/linux/jbd.h
37933 --- linux-2.6.31.1/include/linux/jbd.h 2009-09-24 11:45:25.000000000 -0400
37934 +++ linux-2.6.31.1/include/linux/jbd.h 2009-10-01 20:12:44.000000000 -0400
37935 @@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
37936 } \
37937 } while (0)
37938 #else
37939 -#define jbd_debug(f, a...) /**/
37940 +#define jbd_debug(f, a...) do {} while (0)
37941 #endif
37942
37943 static inline void *jbd_alloc(size_t size, gfp_t flags)
37944 diff -urNp linux-2.6.31.1/include/linux/kallsyms.h linux-2.6.31.1/include/linux/kallsyms.h
37945 --- linux-2.6.31.1/include/linux/kallsyms.h 2009-09-24 11:45:25.000000000 -0400
37946 +++ linux-2.6.31.1/include/linux/kallsyms.h 2009-10-01 20:12:44.000000000 -0400
37947 @@ -15,7 +15,8 @@
37948
37949 struct module;
37950
37951 -#ifdef CONFIG_KALLSYMS
37952 +#ifndef __INCLUDED_BY_HIDESYM
37953 +#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM)
37954 /* Lookup the address for a symbol. Returns 0 if not found. */
37955 unsigned long kallsyms_lookup_name(const char *name);
37956
37957 @@ -92,6 +93,9 @@ static inline int lookup_symbol_attrs(un
37958 /* Stupid that this does nothing, but I didn't create this mess. */
37959 #define __print_symbol(fmt, addr)
37960 #endif /*CONFIG_KALLSYMS*/
37961 +#else /* when included by kallsyms.c, with HIDESYM enabled */
37962 +extern void __print_symbol(const char *fmt, unsigned long address);
37963 +#endif
37964
37965 /* This macro allows us to keep printk typechecking */
37966 static void __check_printsym_format(const char *fmt, ...)
37967 diff -urNp linux-2.6.31.1/include/linux/kvm_host.h linux-2.6.31.1/include/linux/kvm_host.h
37968 --- linux-2.6.31.1/include/linux/kvm_host.h 2009-09-24 11:45:25.000000000 -0400
37969 +++ linux-2.6.31.1/include/linux/kvm_host.h 2009-10-01 20:12:44.000000000 -0400
37970 @@ -173,7 +173,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vc
37971 void vcpu_load(struct kvm_vcpu *vcpu);
37972 void vcpu_put(struct kvm_vcpu *vcpu);
37973
37974 -int kvm_init(void *opaque, unsigned int vcpu_size,
37975 +int kvm_init(const void *opaque, unsigned int vcpu_size,
37976 struct module *module);
37977 void kvm_exit(void);
37978
37979 @@ -280,7 +280,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(
37980 struct kvm_guest_debug *dbg);
37981 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
37982
37983 -int kvm_arch_init(void *opaque);
37984 +int kvm_arch_init(const void *opaque);
37985 void kvm_arch_exit(void);
37986
37987 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu);
37988 diff -urNp linux-2.6.31.1/include/linux/libata.h linux-2.6.31.1/include/linux/libata.h
37989 --- linux-2.6.31.1/include/linux/libata.h 2009-09-24 11:45:25.000000000 -0400
37990 +++ linux-2.6.31.1/include/linux/libata.h 2009-10-01 20:12:44.000000000 -0400
37991 @@ -64,11 +64,11 @@
37992 #ifdef ATA_VERBOSE_DEBUG
37993 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
37994 #else
37995 -#define VPRINTK(fmt, args...)
37996 +#define VPRINTK(fmt, args...) do {} while (0)
37997 #endif /* ATA_VERBOSE_DEBUG */
37998 #else
37999 -#define DPRINTK(fmt, args...)
38000 -#define VPRINTK(fmt, args...)
38001 +#define DPRINTK(fmt, args...) do {} while (0)
38002 +#define VPRINTK(fmt, args...) do {} while (0)
38003 #endif /* ATA_DEBUG */
38004
38005 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
38006 diff -urNp linux-2.6.31.1/include/linux/mm.h linux-2.6.31.1/include/linux/mm.h
38007 --- linux-2.6.31.1/include/linux/mm.h 2009-09-24 11:45:25.000000000 -0400
38008 +++ linux-2.6.31.1/include/linux/mm.h 2009-10-01 20:12:44.000000000 -0400
38009 @@ -104,6 +104,10 @@ extern unsigned int kobjsize(const void
38010 #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
38011 #define VM_PFN_AT_MMAP 0x40000000 /* PFNMAP vma that is fully mapped at mmap time */
38012
38013 +#ifdef CONFIG_PAX_PAGEEXEC
38014 +#define VM_PAGEEXEC 0x80000000 /* vma->vm_page_prot needs special handling */
38015 +#endif
38016 +
38017 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
38018 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
38019 #endif
38020 @@ -871,6 +875,8 @@ struct shrinker {
38021 extern void register_shrinker(struct shrinker *);
38022 extern void unregister_shrinker(struct shrinker *);
38023
38024 +pgprot_t vm_get_page_prot(unsigned long vm_flags);
38025 +
38026 int vma_wants_writenotify(struct vm_area_struct *vma);
38027
38028 extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
38029 @@ -1141,6 +1147,7 @@ out:
38030 }
38031
38032 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
38033 +extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
38034
38035 extern unsigned long do_brk(unsigned long, unsigned long);
38036
38037 @@ -1195,6 +1202,10 @@ extern struct vm_area_struct * find_vma(
38038 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
38039 struct vm_area_struct **pprev);
38040
38041 +extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
38042 +extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
38043 +extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
38044 +
38045 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
38046 NULL if none. Assume start_addr < end_addr. */
38047 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
38048 @@ -1211,7 +1222,6 @@ static inline unsigned long vma_pages(st
38049 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
38050 }
38051
38052 -pgprot_t vm_get_page_prot(unsigned long vm_flags);
38053 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
38054 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
38055 unsigned long pfn, unsigned long size, pgprot_t);
38056 @@ -1303,5 +1313,12 @@ void vmemmap_populate_print_last(void);
38057 extern int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
38058 size_t size);
38059 extern void refund_locked_memory(struct mm_struct *mm, size_t size);
38060 +
38061 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
38062 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
38063 +#else
38064 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
38065 +#endif
38066 +
38067 #endif /* __KERNEL__ */
38068 #endif /* _LINUX_MM_H */
38069 diff -urNp linux-2.6.31.1/include/linux/mm_types.h linux-2.6.31.1/include/linux/mm_types.h
38070 --- linux-2.6.31.1/include/linux/mm_types.h 2009-09-24 11:45:25.000000000 -0400
38071 +++ linux-2.6.31.1/include/linux/mm_types.h 2009-10-01 20:12:44.000000000 -0400
38072 @@ -171,7 +171,7 @@ struct vm_area_struct {
38073 struct anon_vma *anon_vma; /* Serialized by page_table_lock */
38074
38075 /* Function pointers to deal with this struct. */
38076 - struct vm_operations_struct * vm_ops;
38077 + const struct vm_operations_struct * vm_ops;
38078
38079 /* Information about our backing store: */
38080 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
38081 @@ -186,6 +186,8 @@ struct vm_area_struct {
38082 #ifdef CONFIG_NUMA
38083 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
38084 #endif
38085 +
38086 + struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
38087 };
38088
38089 struct core_thread {
38090 @@ -286,6 +288,24 @@ struct mm_struct {
38091 #ifdef CONFIG_MMU_NOTIFIER
38092 struct mmu_notifier_mm *mmu_notifier_mm;
38093 #endif
38094 +
38095 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
38096 + unsigned long pax_flags;
38097 +#endif
38098 +
38099 +#ifdef CONFIG_PAX_DLRESOLVE
38100 + unsigned long call_dl_resolve;
38101 +#endif
38102 +
38103 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
38104 + unsigned long call_syscall;
38105 +#endif
38106 +
38107 +#ifdef CONFIG_PAX_ASLR
38108 + unsigned long delta_mmap; /* randomized offset */
38109 + unsigned long delta_stack; /* randomized offset */
38110 +#endif
38111 +
38112 };
38113
38114 /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */
38115 diff -urNp linux-2.6.31.1/include/linux/mod_devicetable.h linux-2.6.31.1/include/linux/mod_devicetable.h
38116 --- linux-2.6.31.1/include/linux/mod_devicetable.h 2009-09-24 11:45:25.000000000 -0400
38117 +++ linux-2.6.31.1/include/linux/mod_devicetable.h 2009-10-01 20:12:44.000000000 -0400
38118 @@ -12,7 +12,7 @@
38119 typedef unsigned long kernel_ulong_t;
38120 #endif
38121
38122 -#define PCI_ANY_ID (~0)
38123 +#define PCI_ANY_ID ((__u16)~0)
38124
38125 struct pci_device_id {
38126 __u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
38127 @@ -131,7 +131,7 @@ struct usb_device_id {
38128 #define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
38129 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
38130
38131 -#define HID_ANY_ID (~0)
38132 +#define HID_ANY_ID (~0U)
38133
38134 struct hid_device_id {
38135 __u16 bus;
38136 diff -urNp linux-2.6.31.1/include/linux/module.h linux-2.6.31.1/include/linux/module.h
38137 --- linux-2.6.31.1/include/linux/module.h 2009-09-24 11:45:25.000000000 -0400
38138 +++ linux-2.6.31.1/include/linux/module.h 2009-10-01 20:12:44.000000000 -0400
38139 @@ -283,16 +283,16 @@ struct module
38140 int (*init)(void);
38141
38142 /* If this is non-NULL, vfree after init() returns */
38143 - void *module_init;
38144 + void *module_init_rx, *module_init_rw;
38145
38146 /* Here is the actual code + data, vfree'd on unload. */
38147 - void *module_core;
38148 + void *module_core_rx, *module_core_rw;
38149
38150 /* Here are the sizes of the init and core sections */
38151 - unsigned int init_size, core_size;
38152 + unsigned int init_size_rw, core_size_rw;
38153
38154 /* The size of the executable code in each section. */
38155 - unsigned int init_text_size, core_text_size;
38156 + unsigned int init_size_rx, core_size_rx;
38157
38158 /* Arch-specific module values */
38159 struct mod_arch_specific arch;
38160 @@ -389,16 +389,46 @@ struct module *__module_address(unsigned
38161 bool is_module_address(unsigned long addr);
38162 bool is_module_text_address(unsigned long addr);
38163
38164 +static inline int within_module_range(unsigned long addr, void *start, unsigned long size)
38165 +{
38166 +
38167 +#ifdef CONFIG_PAX_KERNEXEC
38168 + if (ktla_ktva(addr) >= (unsigned long)start &&
38169 + ktla_ktva(addr) < (unsigned long)start + size)
38170 + return 1;
38171 +#endif
38172 +
38173 + return ((void *)addr >= start && (void *)addr < start + size);
38174 +}
38175 +
38176 +static inline int within_module_core_rx(unsigned long addr, struct module *mod)
38177 +{
38178 + return within_module_range(addr, mod->module_core_rx, mod->core_size_rx);
38179 +}
38180 +
38181 +static inline int within_module_core_rw(unsigned long addr, struct module *mod)
38182 +{
38183 + return within_module_range(addr, mod->module_core_rw, mod->core_size_rw);
38184 +}
38185 +
38186 +static inline int within_module_init_rx(unsigned long addr, struct module *mod)
38187 +{
38188 + return within_module_range(addr, mod->module_init_rx, mod->init_size_rx);
38189 +}
38190 +
38191 +static inline int within_module_init_rw(unsigned long addr, struct module *mod)
38192 +{
38193 + return within_module_range(addr, mod->module_init_rw, mod->init_size_rw);
38194 +}
38195 +
38196 static inline int within_module_core(unsigned long addr, struct module *mod)
38197 {
38198 - return (unsigned long)mod->module_core <= addr &&
38199 - addr < (unsigned long)mod->module_core + mod->core_size;
38200 + return within_module_core_rx(addr, mod) || within_module_core_rw(addr, mod);
38201 }
38202
38203 static inline int within_module_init(unsigned long addr, struct module *mod)
38204 {
38205 - return (unsigned long)mod->module_init <= addr &&
38206 - addr < (unsigned long)mod->module_init + mod->init_size;
38207 + return within_module_init_rx(addr, mod) || within_module_init_rw(addr, mod);
38208 }
38209
38210 /* Search for module by name: must hold module_mutex. */
38211 @@ -451,7 +481,11 @@ void symbol_put_addr(void *addr);
38212 static inline local_t *__module_ref_addr(struct module *mod, int cpu)
38213 {
38214 #ifdef CONFIG_SMP
38215 +#ifdef CONFIG_X86_32
38216 + return (local_t *) (mod->refptr + __per_cpu_offset[cpu]);
38217 +#else
38218 return (local_t *) (mod->refptr + per_cpu_offset(cpu));
38219 +#endif
38220 #else
38221 return &mod->ref;
38222 #endif
38223 diff -urNp linux-2.6.31.1/include/linux/moduleloader.h linux-2.6.31.1/include/linux/moduleloader.h
38224 --- linux-2.6.31.1/include/linux/moduleloader.h 2009-09-24 11:45:25.000000000 -0400
38225 +++ linux-2.6.31.1/include/linux/moduleloader.h 2009-10-01 20:12:44.000000000 -0400
38226 @@ -20,9 +20,21 @@ unsigned int arch_mod_section_prepend(st
38227 sections. Returns NULL on failure. */
38228 void *module_alloc(unsigned long size);
38229
38230 +#ifdef CONFIG_PAX_KERNEXEC
38231 +void *module_alloc_exec(unsigned long size);
38232 +#else
38233 +#define module_alloc_exec(x) module_alloc(x)
38234 +#endif
38235 +
38236 /* Free memory returned from module_alloc. */
38237 void module_free(struct module *mod, void *module_region);
38238
38239 +#ifdef CONFIG_PAX_KERNEXEC
38240 +void module_free_exec(struct module *mod, void *module_region);
38241 +#else
38242 +#define module_free_exec(x, y) module_free(x, y)
38243 +#endif
38244 +
38245 /* Apply the given relocation to the (simplified) ELF. Return -error
38246 or 0. */
38247 int apply_relocate(Elf_Shdr *sechdrs,
38248 diff -urNp linux-2.6.31.1/include/linux/moduleparam.h linux-2.6.31.1/include/linux/moduleparam.h
38249 --- linux-2.6.31.1/include/linux/moduleparam.h 2009-09-24 11:45:25.000000000 -0400
38250 +++ linux-2.6.31.1/include/linux/moduleparam.h 2009-10-01 20:12:44.000000000 -0400
38251 @@ -37,7 +37,6 @@ typedef int (*param_set_fn)(const char *
38252 typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp);
38253
38254 /* Flag bits for kernel_param.flags */
38255 -#define KPARAM_KMALLOCED 1
38256 #define KPARAM_ISBOOL 2
38257
38258 struct kernel_param {
38259 diff -urNp linux-2.6.31.1/include/linux/namei.h linux-2.6.31.1/include/linux/namei.h
38260 --- linux-2.6.31.1/include/linux/namei.h 2009-09-24 11:45:25.000000000 -0400
38261 +++ linux-2.6.31.1/include/linux/namei.h 2009-10-01 20:12:44.000000000 -0400
38262 @@ -22,7 +22,7 @@ struct nameidata {
38263 unsigned int flags;
38264 int last_type;
38265 unsigned depth;
38266 - char *saved_names[MAX_NESTED_LINKS + 1];
38267 + const char *saved_names[MAX_NESTED_LINKS + 1];
38268
38269 /* Intent data */
38270 union {
38271 @@ -84,12 +84,12 @@ extern int follow_up(struct path *);
38272 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
38273 extern void unlock_rename(struct dentry *, struct dentry *);
38274
38275 -static inline void nd_set_link(struct nameidata *nd, char *path)
38276 +static inline void nd_set_link(struct nameidata *nd, const char *path)
38277 {
38278 nd->saved_names[nd->depth] = path;
38279 }
38280
38281 -static inline char *nd_get_link(struct nameidata *nd)
38282 +static inline const char *nd_get_link(struct nameidata *nd)
38283 {
38284 return nd->saved_names[nd->depth];
38285 }
38286 diff -urNp linux-2.6.31.1/include/linux/nfsd/nfsd.h linux-2.6.31.1/include/linux/nfsd/nfsd.h
38287 --- linux-2.6.31.1/include/linux/nfsd/nfsd.h 2009-09-24 11:45:25.000000000 -0400
38288 +++ linux-2.6.31.1/include/linux/nfsd/nfsd.h 2009-10-01 20:12:44.000000000 -0400
38289 @@ -57,7 +57,7 @@ extern u32 nfsd_supported_minorversion
38290 extern struct mutex nfsd_mutex;
38291 extern struct svc_serv *nfsd_serv;
38292
38293 -extern struct seq_operations nfs_exports_op;
38294 +extern const struct seq_operations nfs_exports_op;
38295
38296 /*
38297 * Function prototypes.
38298 diff -urNp linux-2.6.31.1/include/linux/nodemask.h linux-2.6.31.1/include/linux/nodemask.h
38299 --- linux-2.6.31.1/include/linux/nodemask.h 2009-09-24 11:45:25.000000000 -0400
38300 +++ linux-2.6.31.1/include/linux/nodemask.h 2009-10-01 20:12:44.000000000 -0400
38301 @@ -464,11 +464,11 @@ static inline int num_node_state(enum no
38302
38303 #define any_online_node(mask) \
38304 ({ \
38305 - int node; \
38306 - for_each_node_mask(node, (mask)) \
38307 - if (node_online(node)) \
38308 + int __node; \
38309 + for_each_node_mask(__node, (mask)) \
38310 + if (node_online(__node)) \
38311 break; \
38312 - node; \
38313 + __node; \
38314 })
38315
38316 #define num_online_nodes() num_node_state(N_ONLINE)
38317 diff -urNp linux-2.6.31.1/include/linux/oprofile.h linux-2.6.31.1/include/linux/oprofile.h
38318 --- linux-2.6.31.1/include/linux/oprofile.h 2009-09-24 11:45:25.000000000 -0400
38319 +++ linux-2.6.31.1/include/linux/oprofile.h 2009-10-01 20:12:44.000000000 -0400
38320 @@ -128,7 +128,7 @@ int oprofilefs_create_ro_ulong(struct su
38321
38322 /** Create a file for read-only access to an atomic_t. */
38323 int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root,
38324 - char const * name, atomic_t * val);
38325 + char const * name, atomic_unchecked_t * val);
38326
38327 /** create a directory */
38328 struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root,
38329 diff -urNp linux-2.6.31.1/include/linux/poison.h linux-2.6.31.1/include/linux/poison.h
38330 --- linux-2.6.31.1/include/linux/poison.h 2009-09-24 11:45:25.000000000 -0400
38331 +++ linux-2.6.31.1/include/linux/poison.h 2009-10-01 20:12:44.000000000 -0400
38332 @@ -7,8 +7,8 @@
38333 * under normal circumstances, used to verify that nobody uses
38334 * non-initialized list entries.
38335 */
38336 -#define LIST_POISON1 ((void *) 0x00100100)
38337 -#define LIST_POISON2 ((void *) 0x00200200)
38338 +#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
38339 +#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
38340
38341 /********** include/linux/timer.h **********/
38342 /*
38343 diff -urNp linux-2.6.31.1/include/linux/proc_fs.h linux-2.6.31.1/include/linux/proc_fs.h
38344 --- linux-2.6.31.1/include/linux/proc_fs.h 2009-09-24 11:45:25.000000000 -0400
38345 +++ linux-2.6.31.1/include/linux/proc_fs.h 2009-10-01 20:12:44.000000000 -0400
38346 @@ -146,6 +146,19 @@ static inline struct proc_dir_entry *pro
38347 return proc_create_data(name, mode, parent, proc_fops, NULL);
38348 }
38349
38350 +static inline struct proc_dir_entry *proc_create_grsec(const char *name, mode_t mode,
38351 + struct proc_dir_entry *parent, const struct file_operations *proc_fops)
38352 +{
38353 +#ifdef CONFIG_GRKERNSEC_PROC_USER
38354 + return proc_create_data(name, S_IRUSR, parent, proc_fops, NULL);
38355 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
38356 + return proc_create_data(name, S_IRUSR | S_IRGRP, parent, proc_fops, NULL);
38357 +#else
38358 + return proc_create_data(name, mode, parent, proc_fops, NULL);
38359 +#endif
38360 +}
38361 +
38362 +
38363 static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
38364 mode_t mode, struct proc_dir_entry *base,
38365 read_proc_t *read_proc, void * data)
38366 diff -urNp linux-2.6.31.1/include/linux/random.h linux-2.6.31.1/include/linux/random.h
38367 --- linux-2.6.31.1/include/linux/random.h 2009-09-24 11:45:25.000000000 -0400
38368 +++ linux-2.6.31.1/include/linux/random.h 2009-10-01 20:12:44.000000000 -0400
38369 @@ -74,6 +74,11 @@ unsigned long randomize_range(unsigned l
38370 u32 random32(void);
38371 void srandom32(u32 seed);
38372
38373 +static inline unsigned long pax_get_random_long(void)
38374 +{
38375 + return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
38376 +}
38377 +
38378 #endif /* __KERNEL___ */
38379
38380 #endif /* _LINUX_RANDOM_H */
38381 diff -urNp linux-2.6.31.1/include/linux/reiserfs_fs.h linux-2.6.31.1/include/linux/reiserfs_fs.h
38382 --- linux-2.6.31.1/include/linux/reiserfs_fs.h 2009-09-24 11:45:25.000000000 -0400
38383 +++ linux-2.6.31.1/include/linux/reiserfs_fs.h 2009-10-01 20:12:44.000000000 -0400
38384 @@ -1326,7 +1326,7 @@ static inline loff_t max_reiserfs_offset
38385 #define REISERFS_USER_MEM 1 /* reiserfs user memory mode */
38386
38387 #define fs_generation(s) (REISERFS_SB(s)->s_generation_counter)
38388 -#define get_generation(s) atomic_read (&fs_generation(s))
38389 +#define get_generation(s) atomic_read_unchecked (&fs_generation(s))
38390 #define FILESYSTEM_CHANGED_TB(tb) (get_generation((tb)->tb_sb) != (tb)->fs_gen)
38391 #define __fs_changed(gen,s) (gen != get_generation (s))
38392 #define fs_changed(gen,s) ({cond_resched(); __fs_changed(gen, s);})
38393 diff -urNp linux-2.6.31.1/include/linux/reiserfs_fs_sb.h linux-2.6.31.1/include/linux/reiserfs_fs_sb.h
38394 --- linux-2.6.31.1/include/linux/reiserfs_fs_sb.h 2009-09-24 11:45:25.000000000 -0400
38395 +++ linux-2.6.31.1/include/linux/reiserfs_fs_sb.h 2009-10-01 20:12:44.000000000 -0400
38396 @@ -377,7 +377,7 @@ struct reiserfs_sb_info {
38397 /* Comment? -Hans */
38398 wait_queue_head_t s_wait;
38399 /* To be obsoleted soon by per buffer seals.. -Hans */
38400 - atomic_t s_generation_counter; // increased by one every time the
38401 + atomic_unchecked_t s_generation_counter; // increased by one every time the
38402 // tree gets re-balanced
38403 unsigned long s_properties; /* File system properties. Currently holds
38404 on-disk FS format */
38405 diff -urNp linux-2.6.31.1/include/linux/sched.h linux-2.6.31.1/include/linux/sched.h
38406 --- linux-2.6.31.1/include/linux/sched.h 2009-09-24 11:45:25.000000000 -0400
38407 +++ linux-2.6.31.1/include/linux/sched.h 2009-10-01 20:12:44.000000000 -0400
38408 @@ -99,6 +99,7 @@ struct bio;
38409 struct fs_struct;
38410 struct bts_context;
38411 struct perf_counter_context;
38412 +struct linux_binprm;
38413
38414 /*
38415 * List of flags we want to share for kernel threads,
38416 @@ -629,6 +630,15 @@ struct signal_struct {
38417 unsigned audit_tty;
38418 struct tty_audit_buf *tty_audit_buf;
38419 #endif
38420 +
38421 +#ifdef CONFIG_GRKERNSEC
38422 + u32 curr_ip;
38423 + u32 gr_saddr;
38424 + u32 gr_daddr;
38425 + u16 gr_sport;
38426 + u16 gr_dport;
38427 + u8 used_accept:1;
38428 +#endif
38429 };
38430
38431 /* Context switch must be unlocked if interrupts are to be enabled */
38432 @@ -1165,7 +1175,7 @@ struct sched_rt_entity {
38433
38434 struct task_struct {
38435 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
38436 - void *stack;
38437 + struct thread_info *stack;
38438 atomic_t usage;
38439 unsigned int flags; /* per process flags, defined below */
38440 unsigned int ptrace;
38441 @@ -1269,8 +1279,8 @@ struct task_struct {
38442 struct list_head thread_group;
38443
38444 struct completion *vfork_done; /* for vfork() */
38445 - int __user *set_child_tid; /* CLONE_CHILD_SETTID */
38446 - int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
38447 + pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
38448 + pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
38449
38450 cputime_t utime, stime, utimescaled, stimescaled;
38451 cputime_t gtime;
38452 @@ -1284,15 +1294,6 @@ struct task_struct {
38453 struct task_cputime cputime_expires;
38454 struct list_head cpu_timers[3];
38455
38456 -/* process credentials */
38457 - const struct cred *real_cred; /* objective and real subjective task
38458 - * credentials (COW) */
38459 - const struct cred *cred; /* effective (overridable) subjective task
38460 - * credentials (COW) */
38461 - struct mutex cred_guard_mutex; /* guard against foreign influences on
38462 - * credential calculations
38463 - * (notably. ptrace) */
38464 -
38465 char comm[TASK_COMM_LEN]; /* executable name excluding path
38466 - access with [gs]et_task_comm (which lock
38467 it with task_lock())
38468 @@ -1429,6 +1430,16 @@ struct task_struct {
38469 struct mutex perf_counter_mutex;
38470 struct list_head perf_counter_list;
38471 #endif
38472 +
38473 +/* process credentials */
38474 + const struct cred *real_cred; /* objective and real subjective task
38475 + * credentials (COW) */
38476 + const struct cred *cred; /* effective (overridable) subjective task
38477 + * credentials (COW) */
38478 + struct mutex cred_guard_mutex; /* guard against foreign influences on
38479 + * credential calculations
38480 + * (notably. ptrace) */
38481 +
38482 #ifdef CONFIG_NUMA
38483 struct mempolicy *mempolicy; /* Protected by alloc_lock */
38484 short il_next;
38485 @@ -1480,8 +1491,66 @@ struct task_struct {
38486 /* bitmask of trace recursion */
38487 unsigned long trace_recursion;
38488 #endif /* CONFIG_TRACING */
38489 +
38490 +#ifdef CONFIG_GRKERNSEC
38491 + /* grsecurity */
38492 + struct acl_subject_label *acl;
38493 + struct acl_role_label *role;
38494 + struct file *exec_file;
38495 + u16 acl_role_id;
38496 + u8 acl_sp_role;
38497 + u8 is_writable;
38498 + u8 brute;
38499 +#endif
38500 +
38501 };
38502
38503 +#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
38504 +#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
38505 +#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
38506 +#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
38507 +/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
38508 +#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
38509 +
38510 +#ifdef CONFIG_PAX_SOFTMODE
38511 +extern unsigned int pax_softmode;
38512 +#endif
38513 +
38514 +extern int pax_check_flags(unsigned long *);
38515 +
38516 +/* if tsk != current then task_lock must be held on it */
38517 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
38518 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
38519 +{
38520 + if (likely(tsk->mm))
38521 + return tsk->mm->pax_flags;
38522 + else
38523 + return 0UL;
38524 +}
38525 +
38526 +/* if tsk != current then task_lock must be held on it */
38527 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
38528 +{
38529 + if (likely(tsk->mm)) {
38530 + tsk->mm->pax_flags = flags;
38531 + return 0;
38532 + }
38533 + return -EINVAL;
38534 +}
38535 +#endif
38536 +
38537 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
38538 +extern void pax_set_initial_flags(struct linux_binprm *bprm);
38539 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
38540 +extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
38541 +#endif
38542 +
38543 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
38544 +void pax_report_insns(void *pc, void *sp);
38545 +void pax_report_refcount_overflow(struct pt_regs *regs);
38546 +void pax_report_leak_to_user(const void *ptr, unsigned long len);
38547 +void pax_report_overflow_from_user(const void *ptr, unsigned long len);
38548 +
38549 /* Future-safe accessor for struct task_struct's cpus_allowed. */
38550 #define tsk_cpumask(tsk) (&(tsk)->cpus_allowed)
38551
38552 @@ -2046,7 +2115,7 @@ extern void __cleanup_sighand(struct sig
38553 extern void exit_itimers(struct signal_struct *);
38554 extern void flush_itimer_signals(void);
38555
38556 -extern NORET_TYPE void do_group_exit(int);
38557 +extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
38558
38559 extern void daemonize(const char *, ...);
38560 extern int allow_signal(int);
38561 @@ -2159,8 +2228,8 @@ static inline void unlock_task_sighand(s
38562
38563 #ifndef __HAVE_THREAD_FUNCTIONS
38564
38565 -#define task_thread_info(task) ((struct thread_info *)(task)->stack)
38566 -#define task_stack_page(task) ((task)->stack)
38567 +#define task_thread_info(task) ((task)->stack)
38568 +#define task_stack_page(task) ((void *)(task)->stack)
38569
38570 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
38571 {
38572 @@ -2175,7 +2244,7 @@ static inline unsigned long *end_of_stac
38573
38574 #endif
38575
38576 -static inline int object_is_on_stack(void *obj)
38577 +static inline int object_is_on_stack(const void *obj)
38578 {
38579 void *stack = task_stack_page(current);
38580
38581 diff -urNp linux-2.6.31.1/include/linux/screen_info.h linux-2.6.31.1/include/linux/screen_info.h
38582 --- linux-2.6.31.1/include/linux/screen_info.h 2009-09-24 11:45:25.000000000 -0400
38583 +++ linux-2.6.31.1/include/linux/screen_info.h 2009-10-01 20:12:44.000000000 -0400
38584 @@ -42,7 +42,8 @@ struct screen_info {
38585 __u16 pages; /* 0x32 */
38586 __u16 vesa_attributes; /* 0x34 */
38587 __u32 capabilities; /* 0x36 */
38588 - __u8 _reserved[6]; /* 0x3a */
38589 + __u16 vesapm_size; /* 0x3a */
38590 + __u8 _reserved[4]; /* 0x3c */
38591 } __attribute__((packed));
38592
38593 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
38594 diff -urNp linux-2.6.31.1/include/linux/security.h linux-2.6.31.1/include/linux/security.h
38595 --- linux-2.6.31.1/include/linux/security.h 2009-09-24 11:45:25.000000000 -0400
38596 +++ linux-2.6.31.1/include/linux/security.h 2009-10-01 20:12:44.000000000 -0400
38597 @@ -34,6 +34,7 @@
38598 #include <linux/key.h>
38599 #include <linux/xfrm.h>
38600 #include <linux/gfp.h>
38601 +#include <linux/grsecurity.h>
38602 #include <net/flow.h>
38603
38604 /* Maximum number of letters for an LSM name string */
38605 diff -urNp linux-2.6.31.1/include/linux/shm.h linux-2.6.31.1/include/linux/shm.h
38606 --- linux-2.6.31.1/include/linux/shm.h 2009-09-24 11:45:25.000000000 -0400
38607 +++ linux-2.6.31.1/include/linux/shm.h 2009-10-01 20:12:44.000000000 -0400
38608 @@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
38609 pid_t shm_cprid;
38610 pid_t shm_lprid;
38611 struct user_struct *mlock_user;
38612 +#ifdef CONFIG_GRKERNSEC
38613 + time_t shm_createtime;
38614 + pid_t shm_lapid;
38615 +#endif
38616 };
38617
38618 /* shm_mode upper byte flags */
38619 diff -urNp linux-2.6.31.1/include/linux/slab.h linux-2.6.31.1/include/linux/slab.h
38620 --- linux-2.6.31.1/include/linux/slab.h 2009-09-24 11:45:25.000000000 -0400
38621 +++ linux-2.6.31.1/include/linux/slab.h 2009-10-01 20:12:44.000000000 -0400
38622 @@ -82,10 +82,9 @@
38623 * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
38624 * Both make kfree a no-op.
38625 */
38626 -#define ZERO_SIZE_PTR ((void *)16)
38627 +#define ZERO_SIZE_PTR ((void *)-1024L)
38628
38629 -#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
38630 - (unsigned long)ZERO_SIZE_PTR)
38631 +#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
38632
38633 /*
38634 * struct kmem_cache related prototypes
38635 @@ -138,6 +137,7 @@ void * __must_check krealloc(const void
38636 void kfree(const void *);
38637 void kzfree(const void *);
38638 size_t ksize(const void *);
38639 +void check_object_size(const void *ptr, unsigned long n, bool to);
38640
38641 /*
38642 * Allocator specific definitions. These are mainly used to establish optimized
38643 @@ -328,4 +328,37 @@ static inline void *kzalloc_node(size_t
38644
38645 void __init kmem_cache_init_late(void);
38646
38647 +#define kmalloc(x, y) \
38648 +({ \
38649 + void *___retval; \
38650 + intoverflow_t ___x = (intoverflow_t)x; \
38651 + if (WARN(___x > ULONG_MAX, "kmalloc size overflow\n"))\
38652 + ___retval = NULL; \
38653 + else \
38654 + ___retval = kmalloc((size_t)___x, (y)); \
38655 + ___retval; \
38656 +})
38657 +
38658 +#define kmalloc_node(x, y, z) \
38659 +({ \
38660 + void *___retval; \
38661 + intoverflow_t ___x = (intoverflow_t)x; \
38662 + if (WARN(___x > ULONG_MAX, "kmalloc_node size overflow\n"))\
38663 + ___retval = NULL; \
38664 + else \
38665 + ___retval = kmalloc_node((size_t)___x, (y), (z));\
38666 + ___retval; \
38667 +})
38668 +
38669 +#define kzalloc(x, y) \
38670 +({ \
38671 + void *___retval; \
38672 + intoverflow_t ___x = (intoverflow_t)x; \
38673 + if (WARN(___x > ULONG_MAX, "kzalloc size overflow\n"))\
38674 + ___retval = NULL; \
38675 + else \
38676 + ___retval = kzalloc((size_t)___x, (y)); \
38677 + ___retval; \
38678 +})
38679 +
38680 #endif /* _LINUX_SLAB_H */
38681 diff -urNp linux-2.6.31.1/include/linux/slub_def.h linux-2.6.31.1/include/linux/slub_def.h
38682 --- linux-2.6.31.1/include/linux/slub_def.h 2009-09-24 11:45:25.000000000 -0400
38683 +++ linux-2.6.31.1/include/linux/slub_def.h 2009-10-01 20:12:44.000000000 -0400
38684 @@ -86,7 +86,7 @@ struct kmem_cache {
38685 struct kmem_cache_order_objects max;
38686 struct kmem_cache_order_objects min;
38687 gfp_t allocflags; /* gfp flags to use on each alloc */
38688 - int refcount; /* Refcount for slab cache destroy */
38689 + atomic_t refcount; /* Refcount for slab cache destroy */
38690 void (*ctor)(void *);
38691 int inuse; /* Offset to metadata */
38692 int align; /* Alignment */
38693 diff -urNp linux-2.6.31.1/include/linux/sonet.h linux-2.6.31.1/include/linux/sonet.h
38694 --- linux-2.6.31.1/include/linux/sonet.h 2009-09-24 11:45:25.000000000 -0400
38695 +++ linux-2.6.31.1/include/linux/sonet.h 2009-10-01 20:12:44.000000000 -0400
38696 @@ -61,7 +61,7 @@ struct sonet_stats {
38697 #include <asm/atomic.h>
38698
38699 struct k_sonet_stats {
38700 -#define __HANDLE_ITEM(i) atomic_t i
38701 +#define __HANDLE_ITEM(i) atomic_unchecked_t i
38702 __SONET_ITEMS
38703 #undef __HANDLE_ITEM
38704 };
38705 diff -urNp linux-2.6.31.1/include/linux/sysctl.h linux-2.6.31.1/include/linux/sysctl.h
38706 --- linux-2.6.31.1/include/linux/sysctl.h 2009-09-24 11:45:25.000000000 -0400
38707 +++ linux-2.6.31.1/include/linux/sysctl.h 2009-10-01 20:12:44.000000000 -0400
38708 @@ -165,7 +165,11 @@ enum
38709 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
38710 };
38711
38712 -
38713 +#ifdef CONFIG_PAX_SOFTMODE
38714 +enum {
38715 + PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
38716 +};
38717 +#endif
38718
38719 /* CTL_VM names: */
38720 enum
38721 diff -urNp linux-2.6.31.1/include/linux/thread_info.h linux-2.6.31.1/include/linux/thread_info.h
38722 --- linux-2.6.31.1/include/linux/thread_info.h 2009-09-24 11:45:25.000000000 -0400
38723 +++ linux-2.6.31.1/include/linux/thread_info.h 2009-10-01 20:12:44.000000000 -0400
38724 @@ -23,7 +23,7 @@ struct restart_block {
38725 };
38726 /* For futex_wait and futex_wait_requeue_pi */
38727 struct {
38728 - u32 *uaddr;
38729 + u32 __user *uaddr;
38730 u32 val;
38731 u32 flags;
38732 u32 bitset;
38733 diff -urNp linux-2.6.31.1/include/linux/tty_ldisc.h linux-2.6.31.1/include/linux/tty_ldisc.h
38734 --- linux-2.6.31.1/include/linux/tty_ldisc.h 2009-09-24 11:45:25.000000000 -0400
38735 +++ linux-2.6.31.1/include/linux/tty_ldisc.h 2009-10-01 20:12:44.000000000 -0400
38736 @@ -139,7 +139,7 @@ struct tty_ldisc_ops {
38737
38738 struct module *owner;
38739
38740 - int refcount;
38741 + atomic_t refcount;
38742 };
38743
38744 struct tty_ldisc {
38745 diff -urNp linux-2.6.31.1/include/linux/types.h linux-2.6.31.1/include/linux/types.h
38746 --- linux-2.6.31.1/include/linux/types.h 2009-09-24 11:45:25.000000000 -0400
38747 +++ linux-2.6.31.1/include/linux/types.h 2009-10-01 20:12:44.000000000 -0400
38748 @@ -191,10 +191,26 @@ typedef struct {
38749 volatile int counter;
38750 } atomic_t;
38751
38752 +#ifdef CONFIG_PAX_REFCOUNT
38753 +typedef struct {
38754 + volatile int counter;
38755 +} atomic_unchecked_t;
38756 +#else
38757 +typedef atomic_t atomic_unchecked_t;
38758 +#endif
38759 +
38760 #ifdef CONFIG_64BIT
38761 typedef struct {
38762 volatile long counter;
38763 } atomic64_t;
38764 +
38765 +#ifdef CONFIG_PAX_REFCOUNT
38766 +typedef struct {
38767 + volatile long counter;
38768 +} atomic64_unchecked_t;
38769 +#else
38770 +typedef atomic64_t atomic64_unchecked_t;
38771 +#endif
38772 #endif
38773
38774 struct ustat {
38775 diff -urNp linux-2.6.31.1/include/linux/uaccess.h linux-2.6.31.1/include/linux/uaccess.h
38776 --- linux-2.6.31.1/include/linux/uaccess.h 2009-09-24 11:45:25.000000000 -0400
38777 +++ linux-2.6.31.1/include/linux/uaccess.h 2009-10-01 20:12:44.000000000 -0400
38778 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
38779 long ret; \
38780 mm_segment_t old_fs = get_fs(); \
38781 \
38782 - set_fs(KERNEL_DS); \
38783 pagefault_disable(); \
38784 + set_fs(KERNEL_DS); \
38785 ret = __copy_from_user_inatomic(&(retval), (__force typeof(retval) __user *)(addr), sizeof(retval)); \
38786 - pagefault_enable(); \
38787 set_fs(old_fs); \
38788 + pagefault_enable(); \
38789 ret; \
38790 })
38791
38792 diff -urNp linux-2.6.31.1/include/linux/vmalloc.h linux-2.6.31.1/include/linux/vmalloc.h
38793 --- linux-2.6.31.1/include/linux/vmalloc.h 2009-09-24 11:45:25.000000000 -0400
38794 +++ linux-2.6.31.1/include/linux/vmalloc.h 2009-10-01 20:12:44.000000000 -0400
38795 @@ -13,6 +13,11 @@ struct vm_area_struct; /* vma defining
38796 #define VM_MAP 0x00000004 /* vmap()ed pages */
38797 #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
38798 #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
38799 +
38800 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
38801 +#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */
38802 +#endif
38803 +
38804 /* bits [20..32] reserved for arch specific ioremap internals */
38805
38806 /*
38807 @@ -115,4 +120,81 @@ extern rwlock_t vmlist_lock;
38808 extern struct vm_struct *vmlist;
38809 extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
38810
38811 +#define vmalloc(x) \
38812 +({ \
38813 + void *___retval; \
38814 + intoverflow_t ___x = (intoverflow_t)x; \
38815 + if (WARN(___x > ULONG_MAX, "vmalloc size overflow\n")) \
38816 + ___retval = NULL; \
38817 + else \
38818 + ___retval = vmalloc((unsigned long)___x); \
38819 + ___retval; \
38820 +})
38821 +
38822 +#define __vmalloc(x, y, z) \
38823 +({ \
38824 + void *___retval; \
38825 + intoverflow_t ___x = (intoverflow_t)x; \
38826 + if (WARN(___x > ULONG_MAX, "__vmalloc size overflow\n"))\
38827 + ___retval = NULL; \
38828 + else \
38829 + ___retval = __vmalloc((unsigned long)___x, (y), (z));\
38830 + ___retval; \
38831 +})
38832 +
38833 +#define vmalloc_user(x) \
38834 +({ \
38835 + void *___retval; \
38836 + intoverflow_t ___x = (intoverflow_t)x; \
38837 + if (WARN(___x > ULONG_MAX, "vmalloc_user size overflow\n"))\
38838 + ___retval = NULL; \
38839 + else \
38840 + ___retval = vmalloc_user((unsigned long)___x); \
38841 + ___retval; \
38842 +})
38843 +
38844 +#define vmalloc_exec(x) \
38845 +({ \
38846 + void *___retval; \
38847 + intoverflow_t ___x = (intoverflow_t)x; \
38848 + if (WARN(___x > ULONG_MAX, "vmalloc_exec size overflow\n"))\
38849 + ___retval = NULL; \
38850 + else \
38851 + ___retval = vmalloc_exec((unsigned long)___x); \
38852 + ___retval; \
38853 +})
38854 +
38855 +#define vmalloc_node(x, y) \
38856 +({ \
38857 + void *___retval; \
38858 + intoverflow_t ___x = (intoverflow_t)x; \
38859 + if (WARN(___x > ULONG_MAX, "vmalloc_node size overflow\n"))\
38860 + ___retval = NULL; \
38861 + else \
38862 + ___retval = vmalloc_node((unsigned long)___x, (y));\
38863 + ___retval; \
38864 +})
38865 +
38866 +#define vmalloc_32(x) \
38867 +({ \
38868 + void *___retval; \
38869 + intoverflow_t ___x = (intoverflow_t)x; \
38870 + if (WARN(___x > ULONG_MAX, "vmalloc_32 size overflow\n"))\
38871 + ___retval = NULL; \
38872 + else \
38873 + ___retval = vmalloc_32((unsigned long)___x); \
38874 + ___retval; \
38875 +})
38876 +
38877 +#define vmalloc_32_user(x) \
38878 +({ \
38879 + void *___retval; \
38880 + intoverflow_t ___x = (intoverflow_t)x; \
38881 + if (WARN(___x > ULONG_MAX, "vmalloc_32_user size overflow\n"))\
38882 + ___retval = NULL; \
38883 + else \
38884 + ___retval = vmalloc_32_user((unsigned long)___x);\
38885 + ___retval; \
38886 +})
38887 +
38888 #endif /* _LINUX_VMALLOC_H */
38889 diff -urNp linux-2.6.31.1/include/net/irda/ircomm_tty.h linux-2.6.31.1/include/net/irda/ircomm_tty.h
38890 --- linux-2.6.31.1/include/net/irda/ircomm_tty.h 2009-09-24 11:45:25.000000000 -0400
38891 +++ linux-2.6.31.1/include/net/irda/ircomm_tty.h 2009-10-01 20:12:44.000000000 -0400
38892 @@ -105,8 +105,8 @@ struct ircomm_tty_cb {
38893 unsigned short close_delay;
38894 unsigned short closing_wait; /* time to wait before closing */
38895
38896 - int open_count;
38897 - int blocked_open; /* # of blocked opens */
38898 + atomic_t open_count;
38899 + atomic_t blocked_open; /* # of blocked opens */
38900
38901 /* Protect concurent access to :
38902 * o self->open_count
38903 diff -urNp linux-2.6.31.1/include/net/sctp/sctp.h linux-2.6.31.1/include/net/sctp/sctp.h
38904 --- linux-2.6.31.1/include/net/sctp/sctp.h 2009-09-24 11:45:25.000000000 -0400
38905 +++ linux-2.6.31.1/include/net/sctp/sctp.h 2009-10-01 20:12:44.000000000 -0400
38906 @@ -305,8 +305,8 @@ extern int sctp_debug_flag;
38907
38908 #else /* SCTP_DEBUG */
38909
38910 -#define SCTP_DEBUG_PRINTK(whatever...)
38911 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
38912 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
38913 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
38914 #define SCTP_ENABLE_DEBUG
38915 #define SCTP_DISABLE_DEBUG
38916 #define SCTP_ASSERT(expr, str, func)
38917 diff -urNp linux-2.6.31.1/include/sound/core.h linux-2.6.31.1/include/sound/core.h
38918 --- linux-2.6.31.1/include/sound/core.h 2009-09-24 11:45:25.000000000 -0400
38919 +++ linux-2.6.31.1/include/sound/core.h 2009-10-01 20:12:44.000000000 -0400
38920 @@ -430,7 +430,7 @@ static inline int __snd_bug_on(int cond)
38921 */
38922 #define snd_printdd(format, args...) snd_printk(format, ##args)
38923 #else
38924 -#define snd_printdd(format, args...) /* nothing */
38925 +#define snd_printdd(format, args...) do {} while (0)
38926 #endif
38927
38928
38929 diff -urNp linux-2.6.31.1/include/video/uvesafb.h linux-2.6.31.1/include/video/uvesafb.h
38930 --- linux-2.6.31.1/include/video/uvesafb.h 2009-09-24 11:45:25.000000000 -0400
38931 +++ linux-2.6.31.1/include/video/uvesafb.h 2009-10-01 20:12:44.000000000 -0400
38932 @@ -177,6 +177,7 @@ struct uvesafb_par {
38933 u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
38934 u8 pmi_setpal; /* PMI for palette changes */
38935 u16 *pmi_base; /* protected mode interface location */
38936 + u8 *pmi_code; /* protected mode code location */
38937 void *pmi_start;
38938 void *pmi_pal;
38939 u8 *vbe_state_orig; /*
38940 diff -urNp linux-2.6.31.1/init/do_mounts.c linux-2.6.31.1/init/do_mounts.c
38941 --- linux-2.6.31.1/init/do_mounts.c 2009-09-24 11:45:25.000000000 -0400
38942 +++ linux-2.6.31.1/init/do_mounts.c 2009-10-01 20:12:44.000000000 -0400
38943 @@ -216,11 +216,11 @@ static void __init get_fs_names(char *pa
38944
38945 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
38946 {
38947 - int err = sys_mount(name, "/root", fs, flags, data);
38948 + int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
38949 if (err)
38950 return err;
38951
38952 - sys_chdir("/root");
38953 + sys_chdir((char __user *)"/root");
38954 ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
38955 printk("VFS: Mounted root (%s filesystem)%s on device %u:%u.\n",
38956 current->fs->pwd.mnt->mnt_sb->s_type->name,
38957 @@ -311,18 +311,18 @@ void __init change_floppy(char *fmt, ...
38958 va_start(args, fmt);
38959 vsprintf(buf, fmt, args);
38960 va_end(args);
38961 - fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
38962 + fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
38963 if (fd >= 0) {
38964 sys_ioctl(fd, FDEJECT, 0);
38965 sys_close(fd);
38966 }
38967 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
38968 - fd = sys_open("/dev/console", O_RDWR, 0);
38969 + fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
38970 if (fd >= 0) {
38971 sys_ioctl(fd, TCGETS, (long)&termios);
38972 termios.c_lflag &= ~ICANON;
38973 sys_ioctl(fd, TCSETSF, (long)&termios);
38974 - sys_read(fd, &c, 1);
38975 + sys_read(fd, (char __user *)&c, 1);
38976 termios.c_lflag |= ICANON;
38977 sys_ioctl(fd, TCSETSF, (long)&termios);
38978 sys_close(fd);
38979 @@ -415,7 +415,7 @@ void __init prepare_namespace(void)
38980
38981 mount_root();
38982 out:
38983 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
38984 - sys_chroot(".");
38985 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
38986 + sys_chroot((char __user *)".");
38987 }
38988
38989 diff -urNp linux-2.6.31.1/init/do_mounts.h linux-2.6.31.1/init/do_mounts.h
38990 --- linux-2.6.31.1/init/do_mounts.h 2009-09-24 11:45:25.000000000 -0400
38991 +++ linux-2.6.31.1/init/do_mounts.h 2009-10-01 20:12:44.000000000 -0400
38992 @@ -15,15 +15,15 @@ extern int root_mountflags;
38993
38994 static inline int create_dev(char *name, dev_t dev)
38995 {
38996 - sys_unlink(name);
38997 - return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
38998 + sys_unlink((char __user *)name);
38999 + return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
39000 }
39001
39002 #if BITS_PER_LONG == 32
39003 static inline u32 bstat(char *name)
39004 {
39005 struct stat64 stat;
39006 - if (sys_stat64(name, &stat) != 0)
39007 + if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
39008 return 0;
39009 if (!S_ISBLK(stat.st_mode))
39010 return 0;
39011 diff -urNp linux-2.6.31.1/init/do_mounts_initrd.c linux-2.6.31.1/init/do_mounts_initrd.c
39012 --- linux-2.6.31.1/init/do_mounts_initrd.c 2009-09-24 11:45:25.000000000 -0400
39013 +++ linux-2.6.31.1/init/do_mounts_initrd.c 2009-10-01 20:12:44.000000000 -0400
39014 @@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
39015 sys_close(old_fd);sys_close(root_fd);
39016 sys_close(0);sys_close(1);sys_close(2);
39017 sys_setsid();
39018 - (void) sys_open("/dev/console",O_RDWR,0);
39019 + (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
39020 (void) sys_dup(0);
39021 (void) sys_dup(0);
39022 return kernel_execve(shell, argv, envp_init);
39023 @@ -47,13 +47,13 @@ static void __init handle_initrd(void)
39024 create_dev("/dev/root.old", Root_RAM0);
39025 /* mount initrd on rootfs' /root */
39026 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
39027 - sys_mkdir("/old", 0700);
39028 - root_fd = sys_open("/", 0, 0);
39029 - old_fd = sys_open("/old", 0, 0);
39030 + sys_mkdir((const char __user *)"/old", 0700);
39031 + root_fd = sys_open((const char __user *)"/", 0, 0);
39032 + old_fd = sys_open((const char __user *)"/old", 0, 0);
39033 /* move initrd over / and chdir/chroot in initrd root */
39034 - sys_chdir("/root");
39035 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
39036 - sys_chroot(".");
39037 + sys_chdir((const char __user *)"/root");
39038 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
39039 + sys_chroot((const char __user *)".");
39040
39041 /*
39042 * In case that a resume from disk is carried out by linuxrc or one of
39043 @@ -70,15 +70,15 @@ static void __init handle_initrd(void)
39044
39045 /* move initrd to rootfs' /old */
39046 sys_fchdir(old_fd);
39047 - sys_mount("/", ".", NULL, MS_MOVE, NULL);
39048 + sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
39049 /* switch root and cwd back to / of rootfs */
39050 sys_fchdir(root_fd);
39051 - sys_chroot(".");
39052 + sys_chroot((const char __user *)".");
39053 sys_close(old_fd);
39054 sys_close(root_fd);
39055
39056 if (new_decode_dev(real_root_dev) == Root_RAM0) {
39057 - sys_chdir("/old");
39058 + sys_chdir((const char __user *)"/old");
39059 return;
39060 }
39061
39062 @@ -86,17 +86,17 @@ static void __init handle_initrd(void)
39063 mount_root();
39064
39065 printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
39066 - error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
39067 + error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
39068 if (!error)
39069 printk("okay\n");
39070 else {
39071 - int fd = sys_open("/dev/root.old", O_RDWR, 0);
39072 + int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
39073 if (error == -ENOENT)
39074 printk("/initrd does not exist. Ignored.\n");
39075 else
39076 printk("failed\n");
39077 printk(KERN_NOTICE "Unmounting old root\n");
39078 - sys_umount("/old", MNT_DETACH);
39079 + sys_umount((char __user *)"/old", MNT_DETACH);
39080 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
39081 if (fd < 0) {
39082 error = fd;
39083 @@ -119,11 +119,11 @@ int __init initrd_load(void)
39084 * mounted in the normal path.
39085 */
39086 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
39087 - sys_unlink("/initrd.image");
39088 + sys_unlink((const char __user *)"/initrd.image");
39089 handle_initrd();
39090 return 1;
39091 }
39092 }
39093 - sys_unlink("/initrd.image");
39094 + sys_unlink((const char __user *)"/initrd.image");
39095 return 0;
39096 }
39097 diff -urNp linux-2.6.31.1/init/do_mounts_md.c linux-2.6.31.1/init/do_mounts_md.c
39098 --- linux-2.6.31.1/init/do_mounts_md.c 2009-09-24 11:45:25.000000000 -0400
39099 +++ linux-2.6.31.1/init/do_mounts_md.c 2009-10-01 20:12:44.000000000 -0400
39100 @@ -170,7 +170,7 @@ static void __init md_setup_drive(void)
39101 partitioned ? "_d" : "", minor,
39102 md_setup_args[ent].device_names);
39103
39104 - fd = sys_open(name, 0, 0);
39105 + fd = sys_open((char __user *)name, 0, 0);
39106 if (fd < 0) {
39107 printk(KERN_ERR "md: open failed - cannot start "
39108 "array %s\n", name);
39109 @@ -233,7 +233,7 @@ static void __init md_setup_drive(void)
39110 * array without it
39111 */
39112 sys_close(fd);
39113 - fd = sys_open(name, 0, 0);
39114 + fd = sys_open((char __user *)name, 0, 0);
39115 sys_ioctl(fd, BLKRRPART, 0);
39116 }
39117 sys_close(fd);
39118 @@ -283,7 +283,7 @@ static void __init autodetect_raid(void)
39119
39120 wait_for_device_probe();
39121
39122 - fd = sys_open("/dev/md0", 0, 0);
39123 + fd = sys_open((char __user *)"/dev/md0", 0, 0);
39124 if (fd >= 0) {
39125 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
39126 sys_close(fd);
39127 diff -urNp linux-2.6.31.1/init/initramfs.c linux-2.6.31.1/init/initramfs.c
39128 --- linux-2.6.31.1/init/initramfs.c 2009-09-24 11:45:25.000000000 -0400
39129 +++ linux-2.6.31.1/init/initramfs.c 2009-10-01 20:12:44.000000000 -0400
39130 @@ -271,7 +271,7 @@ static int __init maybe_link(void)
39131 if (nlink >= 2) {
39132 char *old = find_link(major, minor, ino, mode, collected);
39133 if (old)
39134 - return (sys_link(old, collected) < 0) ? -1 : 1;
39135 + return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
39136 }
39137 return 0;
39138 }
39139 @@ -280,11 +280,11 @@ static void __init clean_path(char *path
39140 {
39141 struct stat st;
39142
39143 - if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
39144 + if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
39145 if (S_ISDIR(st.st_mode))
39146 - sys_rmdir(path);
39147 + sys_rmdir((char __user *)path);
39148 else
39149 - sys_unlink(path);
39150 + sys_unlink((char __user *)path);
39151 }
39152 }
39153
39154 @@ -305,7 +305,7 @@ static int __init do_name(void)
39155 int openflags = O_WRONLY|O_CREAT;
39156 if (ml != 1)
39157 openflags |= O_TRUNC;
39158 - wfd = sys_open(collected, openflags, mode);
39159 + wfd = sys_open((char __user *)collected, openflags, mode);
39160
39161 if (wfd >= 0) {
39162 sys_fchown(wfd, uid, gid);
39163 @@ -317,16 +317,16 @@ static int __init do_name(void)
39164 }
39165 }
39166 } else if (S_ISDIR(mode)) {
39167 - sys_mkdir(collected, mode);
39168 - sys_chown(collected, uid, gid);
39169 - sys_chmod(collected, mode);
39170 + sys_mkdir((char __user *)collected, mode);
39171 + sys_chown((char __user *)collected, uid, gid);
39172 + sys_chmod((char __user *)collected, mode);
39173 dir_add(collected, mtime);
39174 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
39175 S_ISFIFO(mode) || S_ISSOCK(mode)) {
39176 if (maybe_link() == 0) {
39177 - sys_mknod(collected, mode, rdev);
39178 - sys_chown(collected, uid, gid);
39179 - sys_chmod(collected, mode);
39180 + sys_mknod((char __user *)collected, mode, rdev);
39181 + sys_chown((char __user *)collected, uid, gid);
39182 + sys_chmod((char __user *)collected, mode);
39183 do_utime(collected, mtime);
39184 }
39185 }
39186 @@ -336,7 +336,7 @@ static int __init do_name(void)
39187 static int __init do_copy(void)
39188 {
39189 if (count >= body_len) {
39190 - sys_write(wfd, victim, body_len);
39191 + sys_write(wfd, (char __user *)victim, body_len);
39192 sys_close(wfd);
39193 do_utime(vcollected, mtime);
39194 kfree(vcollected);
39195 @@ -344,7 +344,7 @@ static int __init do_copy(void)
39196 state = SkipIt;
39197 return 0;
39198 } else {
39199 - sys_write(wfd, victim, count);
39200 + sys_write(wfd, (char __user *)victim, count);
39201 body_len -= count;
39202 eat(count);
39203 return 1;
39204 @@ -355,8 +355,8 @@ static int __init do_symlink(void)
39205 {
39206 collected[N_ALIGN(name_len) + body_len] = '\0';
39207 clean_path(collected, 0);
39208 - sys_symlink(collected + N_ALIGN(name_len), collected);
39209 - sys_lchown(collected, uid, gid);
39210 + sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
39211 + sys_lchown((char __user *)collected, uid, gid);
39212 do_utime(collected, mtime);
39213 state = SkipIt;
39214 next_state = Reset;
39215 diff -urNp linux-2.6.31.1/init/Kconfig linux-2.6.31.1/init/Kconfig
39216 --- linux-2.6.31.1/init/Kconfig 2009-09-24 11:45:25.000000000 -0400
39217 +++ linux-2.6.31.1/init/Kconfig 2009-10-01 20:12:44.000000000 -0400
39218 @@ -1014,7 +1014,7 @@ config STRIP_ASM_SYMS
39219
39220 config COMPAT_BRK
39221 bool "Disable heap randomization"
39222 - default y
39223 + default n
39224 help
39225 Randomizing heap placement makes heap exploits harder, but it
39226 also breaks ancient binaries (including anything libc5 based).
39227 @@ -1101,9 +1101,9 @@ config HAVE_GENERIC_DMA_COHERENT
39228
39229 config SLABINFO
39230 bool
39231 - depends on PROC_FS
39232 + depends on PROC_FS && !GRKERNSEC_PROC_ADD
39233 depends on SLAB || SLUB_DEBUG
39234 - default y
39235 + default n
39236
39237 config RT_MUTEXES
39238 boolean
39239 diff -urNp linux-2.6.31.1/init/main.c linux-2.6.31.1/init/main.c
39240 --- linux-2.6.31.1/init/main.c 2009-09-24 11:45:25.000000000 -0400
39241 +++ linux-2.6.31.1/init/main.c 2009-10-01 20:12:44.000000000 -0400
39242 @@ -96,6 +96,7 @@ static inline void mark_rodata_ro(void)
39243 #ifdef CONFIG_TC
39244 extern void tc_init(void);
39245 #endif
39246 +extern void grsecurity_init(void);
39247
39248 enum system_states system_state __read_mostly;
39249 EXPORT_SYMBOL(system_state);
39250 @@ -182,6 +183,35 @@ static int __init set_reset_devices(char
39251
39252 __setup("reset_devices", set_reset_devices);
39253
39254 +#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
39255 +static int __init setup_pax_nouderef(char *str)
39256 +{
39257 + unsigned int cpu;
39258 +
39259 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
39260 + get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].type = 3;
39261 + get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].limit = 0xf;
39262 + }
39263 + asm("mov %0, %%ds" : : "r" (__KERNEL_DS) : "memory");
39264 + asm("mov %0, %%es" : : "r" (__KERNEL_DS) : "memory");
39265 + asm("mov %0, %%ss" : : "r" (__KERNEL_DS) : "memory");
39266 +
39267 + return 0;
39268 +}
39269 +early_param("pax_nouderef", setup_pax_nouderef);
39270 +#endif
39271 +
39272 +#ifdef CONFIG_PAX_SOFTMODE
39273 +unsigned int pax_softmode;
39274 +
39275 +static int __init setup_pax_softmode(char *str)
39276 +{
39277 + get_option(&str, &pax_softmode);
39278 + return 1;
39279 +}
39280 +__setup("pax_softmode=", setup_pax_softmode);
39281 +#endif
39282 +
39283 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
39284 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
39285 static const char *panic_later, *panic_param;
39286 @@ -375,7 +405,7 @@ static void __init setup_nr_cpu_ids(void
39287 }
39288
39289 #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
39290 -unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
39291 +unsigned long __per_cpu_offset[NR_CPUS] __read_only;
39292
39293 EXPORT_SYMBOL(__per_cpu_offset);
39294
39295 @@ -741,6 +771,7 @@ int do_one_initcall(initcall_t fn)
39296 {
39297 int count = preempt_count();
39298 ktime_t calltime, delta, rettime;
39299 + const char *msg1 = "", *msg2 = "";
39300
39301 if (initcall_debug) {
39302 call.caller = task_pid_nr(current);
39303 @@ -768,15 +799,15 @@ int do_one_initcall(initcall_t fn)
39304 sprintf(msgbuf, "error code %d ", ret.result);
39305
39306 if (preempt_count() != count) {
39307 - strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
39308 + msg1 = " preemption imbalance";
39309 preempt_count() = count;
39310 }
39311 if (irqs_disabled()) {
39312 - strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
39313 + msg2 = " disabled interrupts";
39314 local_irq_enable();
39315 }
39316 - if (msgbuf[0]) {
39317 - printk("initcall %pF returned with %s\n", fn, msgbuf);
39318 + if (msgbuf[0] || *msg1 || *msg2) {
39319 + printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
39320 }
39321
39322 return ret.result;
39323 @@ -923,6 +954,8 @@ static int __init kernel_init(void * unu
39324 prepare_namespace();
39325 }
39326
39327 + grsecurity_init();
39328 +
39329 /*
39330 * Ok, we have completed the initial bootup, and
39331 * we're essentially up and running. Get rid of the
39332 diff -urNp linux-2.6.31.1/init/noinitramfs.c linux-2.6.31.1/init/noinitramfs.c
39333 --- linux-2.6.31.1/init/noinitramfs.c 2009-09-24 11:45:25.000000000 -0400
39334 +++ linux-2.6.31.1/init/noinitramfs.c 2009-10-01 20:12:44.000000000 -0400
39335 @@ -29,7 +29,7 @@ static int __init default_rootfs(void)
39336 {
39337 int err;
39338
39339 - err = sys_mkdir("/dev", 0755);
39340 + err = sys_mkdir((const char __user *)"/dev", 0755);
39341 if (err < 0)
39342 goto out;
39343
39344 @@ -39,7 +39,7 @@ static int __init default_rootfs(void)
39345 if (err < 0)
39346 goto out;
39347
39348 - err = sys_mkdir("/root", 0700);
39349 + err = sys_mkdir((const char __user *)"/root", 0700);
39350 if (err < 0)
39351 goto out;
39352
39353 diff -urNp linux-2.6.31.1/ipc/ipc_sysctl.c linux-2.6.31.1/ipc/ipc_sysctl.c
39354 --- linux-2.6.31.1/ipc/ipc_sysctl.c 2009-09-24 11:45:25.000000000 -0400
39355 +++ linux-2.6.31.1/ipc/ipc_sysctl.c 2009-10-01 20:12:44.000000000 -0400
39356 @@ -267,7 +267,7 @@ static struct ctl_table ipc_kern_table[]
39357 .extra1 = &zero,
39358 .extra2 = &one,
39359 },
39360 - {}
39361 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
39362 };
39363
39364 static struct ctl_table ipc_root_table[] = {
39365 @@ -277,7 +277,7 @@ static struct ctl_table ipc_root_table[]
39366 .mode = 0555,
39367 .child = ipc_kern_table,
39368 },
39369 - {}
39370 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
39371 };
39372
39373 static int __init ipc_sysctl_init(void)
39374 diff -urNp linux-2.6.31.1/ipc/mqueue.c linux-2.6.31.1/ipc/mqueue.c
39375 --- linux-2.6.31.1/ipc/mqueue.c 2009-09-24 11:45:25.000000000 -0400
39376 +++ linux-2.6.31.1/ipc/mqueue.c 2009-10-01 20:12:44.000000000 -0400
39377 @@ -77,7 +77,7 @@ struct mqueue_inode_info {
39378
39379 static const struct inode_operations mqueue_dir_inode_operations;
39380 static const struct file_operations mqueue_file_operations;
39381 -static struct super_operations mqueue_super_ops;
39382 +static const struct super_operations mqueue_super_ops;
39383 static void remove_notification(struct mqueue_inode_info *info);
39384
39385 static struct kmem_cache *mqueue_inode_cachep;
39386 @@ -150,6 +150,7 @@ static struct inode *mqueue_get_inode(st
39387 mq_bytes = (mq_msg_tblsz +
39388 (info->attr.mq_maxmsg * info->attr.mq_msgsize));
39389
39390 + gr_learn_resource(current, RLIMIT_MSGQUEUE, u->mq_bytes + mq_bytes, 1);
39391 spin_lock(&mq_lock);
39392 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
39393 u->mq_bytes + mq_bytes >
39394 @@ -1224,7 +1225,7 @@ static const struct file_operations mque
39395 .read = mqueue_read_file,
39396 };
39397
39398 -static struct super_operations mqueue_super_ops = {
39399 +static const struct super_operations mqueue_super_ops = {
39400 .alloc_inode = mqueue_alloc_inode,
39401 .destroy_inode = mqueue_destroy_inode,
39402 .statfs = simple_statfs,
39403 diff -urNp linux-2.6.31.1/ipc/shm.c linux-2.6.31.1/ipc/shm.c
39404 --- linux-2.6.31.1/ipc/shm.c 2009-09-24 11:45:25.000000000 -0400
39405 +++ linux-2.6.31.1/ipc/shm.c 2009-10-01 20:12:44.000000000 -0400
39406 @@ -55,7 +55,7 @@ struct shm_file_data {
39407 #define shm_file_data(file) (*((struct shm_file_data **)&(file)->private_data))
39408
39409 static const struct file_operations shm_file_operations;
39410 -static struct vm_operations_struct shm_vm_ops;
39411 +static const struct vm_operations_struct shm_vm_ops;
39412
39413 #define shm_ids(ns) ((ns)->ids[IPC_SHM_IDS])
39414
39415 @@ -70,6 +70,14 @@ static void shm_destroy (struct ipc_name
39416 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
39417 #endif
39418
39419 +#ifdef CONFIG_GRKERNSEC
39420 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
39421 + const time_t shm_createtime, const uid_t cuid,
39422 + const int shmid);
39423 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
39424 + const time_t shm_createtime);
39425 +#endif
39426 +
39427 void shm_init_ns(struct ipc_namespace *ns)
39428 {
39429 ns->shm_ctlmax = SHMMAX;
39430 @@ -312,7 +320,7 @@ static const struct file_operations shm_
39431 .get_unmapped_area = shm_get_unmapped_area,
39432 };
39433
39434 -static struct vm_operations_struct shm_vm_ops = {
39435 +static const struct vm_operations_struct shm_vm_ops = {
39436 .open = shm_open, /* callback for a new vm-area open */
39437 .close = shm_close, /* callback for when the vm-area is released */
39438 .fault = shm_fault,
39439 @@ -395,6 +403,14 @@ static int newseg(struct ipc_namespace *
39440 shp->shm_lprid = 0;
39441 shp->shm_atim = shp->shm_dtim = 0;
39442 shp->shm_ctim = get_seconds();
39443 +#ifdef CONFIG_GRKERNSEC
39444 + {
39445 + struct timespec timeval;
39446 + do_posix_clock_monotonic_gettime(&timeval);
39447 +
39448 + shp->shm_createtime = timeval.tv_sec;
39449 + }
39450 +#endif
39451 shp->shm_segsz = size;
39452 shp->shm_nattch = 0;
39453 shp->shm_file = file;
39454 @@ -878,9 +894,21 @@ long do_shmat(int shmid, char __user *sh
39455 if (err)
39456 goto out_unlock;
39457
39458 +#ifdef CONFIG_GRKERNSEC
39459 + if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
39460 + shp->shm_perm.cuid, shmid) ||
39461 + !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
39462 + err = -EACCES;
39463 + goto out_unlock;
39464 + }
39465 +#endif
39466 +
39467 path.dentry = dget(shp->shm_file->f_path.dentry);
39468 path.mnt = shp->shm_file->f_path.mnt;
39469 shp->shm_nattch++;
39470 +#ifdef CONFIG_GRKERNSEC
39471 + shp->shm_lapid = current->pid;
39472 +#endif
39473 size = i_size_read(path.dentry->d_inode);
39474 shm_unlock(shp);
39475
39476 diff -urNp linux-2.6.31.1/ipc/util.c linux-2.6.31.1/ipc/util.c
39477 --- linux-2.6.31.1/ipc/util.c 2009-09-24 11:45:25.000000000 -0400
39478 +++ linux-2.6.31.1/ipc/util.c 2009-10-01 20:12:44.000000000 -0400
39479 @@ -942,7 +942,7 @@ static int sysvipc_proc_show(struct seq_
39480 return iface->show(s, it);
39481 }
39482
39483 -static struct seq_operations sysvipc_proc_seqops = {
39484 +static const struct seq_operations sysvipc_proc_seqops = {
39485 .start = sysvipc_proc_start,
39486 .stop = sysvipc_proc_stop,
39487 .next = sysvipc_proc_next,
39488 diff -urNp linux-2.6.31.1/kernel/acct.c linux-2.6.31.1/kernel/acct.c
39489 --- linux-2.6.31.1/kernel/acct.c 2009-09-24 11:45:25.000000000 -0400
39490 +++ linux-2.6.31.1/kernel/acct.c 2009-10-01 20:12:44.000000000 -0400
39491 @@ -574,7 +574,7 @@ static void do_acct_process(struct bsd_a
39492 */
39493 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
39494 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
39495 - file->f_op->write(file, (char *)&ac,
39496 + file->f_op->write(file, (char __user *)&ac,
39497 sizeof(acct_t), &file->f_pos);
39498 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
39499 set_fs(fs);
39500 diff -urNp linux-2.6.31.1/kernel/capability.c linux-2.6.31.1/kernel/capability.c
39501 --- linux-2.6.31.1/kernel/capability.c 2009-09-24 11:45:25.000000000 -0400
39502 +++ linux-2.6.31.1/kernel/capability.c 2009-10-01 20:12:44.000000000 -0400
39503 @@ -306,10 +306,21 @@ int capable(int cap)
39504 BUG();
39505 }
39506
39507 - if (security_capable(cap) == 0) {
39508 + if (security_capable(cap) == 0 && gr_is_capable(cap)) {
39509 current->flags |= PF_SUPERPRIV;
39510 return 1;
39511 }
39512 return 0;
39513 }
39514 +
39515 +int capable_nolog(int cap)
39516 +{
39517 + if (security_capable(cap) == 0 && gr_is_capable_nolog(cap)) {
39518 + current->flags |= PF_SUPERPRIV;
39519 + return 1;
39520 + }
39521 + return 0;
39522 +}
39523 +
39524 EXPORT_SYMBOL(capable);
39525 +EXPORT_SYMBOL(capable_nolog);
39526 diff -urNp linux-2.6.31.1/kernel/cgroup.c linux-2.6.31.1/kernel/cgroup.c
39527 --- linux-2.6.31.1/kernel/cgroup.c 2009-09-24 11:45:25.000000000 -0400
39528 +++ linux-2.6.31.1/kernel/cgroup.c 2009-10-01 20:12:44.000000000 -0400
39529 @@ -596,8 +596,8 @@ void cgroup_unlock(void)
39530 static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
39531 static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
39532 static int cgroup_populate_dir(struct cgroup *cgrp);
39533 -static struct inode_operations cgroup_dir_inode_operations;
39534 -static struct file_operations proc_cgroupstats_operations;
39535 +static const struct inode_operations cgroup_dir_inode_operations;
39536 +static const struct file_operations proc_cgroupstats_operations;
39537
39538 static struct backing_dev_info cgroup_backing_dev_info = {
39539 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
39540 @@ -960,7 +960,7 @@ static int cgroup_remount(struct super_b
39541 return ret;
39542 }
39543
39544 -static struct super_operations cgroup_ops = {
39545 +static const struct super_operations cgroup_ops = {
39546 .statfs = simple_statfs,
39547 .drop_inode = generic_delete_inode,
39548 .show_options = cgroup_show_options,
39549 @@ -1643,7 +1643,7 @@ static int cgroup_seqfile_release(struct
39550 return single_release(inode, file);
39551 }
39552
39553 -static struct file_operations cgroup_seqfile_operations = {
39554 +static const struct file_operations cgroup_seqfile_operations = {
39555 .read = seq_read,
39556 .write = cgroup_file_write,
39557 .llseek = seq_lseek,
39558 @@ -1702,7 +1702,7 @@ static int cgroup_rename(struct inode *o
39559 return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
39560 }
39561
39562 -static struct file_operations cgroup_file_operations = {
39563 +static const struct file_operations cgroup_file_operations = {
39564 .read = cgroup_file_read,
39565 .write = cgroup_file_write,
39566 .llseek = generic_file_llseek,
39567 @@ -1710,7 +1710,7 @@ static struct file_operations cgroup_fil
39568 .release = cgroup_file_release,
39569 };
39570
39571 -static struct inode_operations cgroup_dir_inode_operations = {
39572 +static const struct inode_operations cgroup_dir_inode_operations = {
39573 .lookup = simple_lookup,
39574 .mkdir = cgroup_mkdir,
39575 .rmdir = cgroup_rmdir,
39576 @@ -2313,7 +2313,7 @@ static int cgroup_tasks_show(struct seq_
39577 return seq_printf(s, "%d\n", *(int *)v);
39578 }
39579
39580 -static struct seq_operations cgroup_tasks_seq_operations = {
39581 +static const struct seq_operations cgroup_tasks_seq_operations = {
39582 .start = cgroup_tasks_start,
39583 .stop = cgroup_tasks_stop,
39584 .next = cgroup_tasks_next,
39585 @@ -2350,7 +2350,7 @@ static int cgroup_tasks_release(struct i
39586 return seq_release(inode, file);
39587 }
39588
39589 -static struct file_operations cgroup_tasks_operations = {
39590 +static const struct file_operations cgroup_tasks_operations = {
39591 .read = seq_read,
39592 .llseek = seq_lseek,
39593 .write = cgroup_file_write,
39594 @@ -3016,7 +3016,7 @@ static int cgroup_open(struct inode *ino
39595 return single_open(file, proc_cgroup_show, pid);
39596 }
39597
39598 -struct file_operations proc_cgroup_operations = {
39599 +const struct file_operations proc_cgroup_operations = {
39600 .open = cgroup_open,
39601 .read = seq_read,
39602 .llseek = seq_lseek,
39603 @@ -3045,7 +3045,7 @@ static int cgroupstats_open(struct inode
39604 return single_open(file, proc_cgroupstats_show, NULL);
39605 }
39606
39607 -static struct file_operations proc_cgroupstats_operations = {
39608 +static const struct file_operations proc_cgroupstats_operations = {
39609 .open = cgroupstats_open,
39610 .read = seq_read,
39611 .llseek = seq_lseek,
39612 diff -urNp linux-2.6.31.1/kernel/configs.c linux-2.6.31.1/kernel/configs.c
39613 --- linux-2.6.31.1/kernel/configs.c 2009-09-24 11:45:25.000000000 -0400
39614 +++ linux-2.6.31.1/kernel/configs.c 2009-10-01 20:12:44.000000000 -0400
39615 @@ -73,8 +73,19 @@ static int __init ikconfig_init(void)
39616 struct proc_dir_entry *entry;
39617
39618 /* create the current config file */
39619 +#if defined(CONFIG_GRKERNSEC_PROC_ADD) || defined(CONFIG_GRKERNSEC_HIDESYM)
39620 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_HIDESYM)
39621 + entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
39622 + &ikconfig_file_ops);
39623 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
39624 + entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
39625 + &ikconfig_file_ops);
39626 +#endif
39627 +#else
39628 entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
39629 &ikconfig_file_ops);
39630 +#endif
39631 +
39632 if (!entry)
39633 return -ENOMEM;
39634
39635 diff -urNp linux-2.6.31.1/kernel/cpu.c linux-2.6.31.1/kernel/cpu.c
39636 --- linux-2.6.31.1/kernel/cpu.c 2009-09-24 11:45:25.000000000 -0400
39637 +++ linux-2.6.31.1/kernel/cpu.c 2009-10-01 20:12:44.000000000 -0400
39638 @@ -19,7 +19,7 @@
39639 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
39640 static DEFINE_MUTEX(cpu_add_remove_lock);
39641
39642 -static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
39643 +static RAW_NOTIFIER_HEAD(cpu_chain);
39644
39645 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
39646 * Should always be manipulated under cpu_add_remove_lock
39647 diff -urNp linux-2.6.31.1/kernel/cred.c linux-2.6.31.1/kernel/cred.c
39648 --- linux-2.6.31.1/kernel/cred.c 2009-09-24 11:45:25.000000000 -0400
39649 +++ linux-2.6.31.1/kernel/cred.c 2009-10-01 20:12:44.000000000 -0400
39650 @@ -366,6 +366,8 @@ int commit_creds(struct cred *new)
39651
39652 get_cred(new); /* we will require a ref for the subj creds too */
39653
39654 + gr_set_role_label(task, new->uid, new->gid);
39655 +
39656 /* dumpability changes */
39657 if (old->euid != new->euid ||
39658 old->egid != new->egid ||
39659 diff -urNp linux-2.6.31.1/kernel/exit.c linux-2.6.31.1/kernel/exit.c
39660 --- linux-2.6.31.1/kernel/exit.c 2009-09-24 11:45:25.000000000 -0400
39661 +++ linux-2.6.31.1/kernel/exit.c 2009-10-01 20:12:44.000000000 -0400
39662 @@ -56,6 +56,10 @@
39663 #include <asm/mmu_context.h>
39664 #include "cred-internals.h"
39665
39666 +#ifdef CONFIG_GRKERNSEC
39667 +extern rwlock_t grsec_exec_file_lock;
39668 +#endif
39669 +
39670 static void exit_mm(struct task_struct * tsk);
39671
39672 static void __unhash_process(struct task_struct *p)
39673 @@ -167,6 +171,8 @@ void release_task(struct task_struct * p
39674 struct task_struct *leader;
39675 int zap_leader;
39676 repeat:
39677 + gr_del_task_from_ip_table(p);
39678 +
39679 tracehook_prepare_release_task(p);
39680 /* don't need to get the RCU readlock here - the process is dead and
39681 * can't be modifying its own credentials */
39682 @@ -334,11 +340,22 @@ static void reparent_to_kthreadd(void)
39683 {
39684 write_lock_irq(&tasklist_lock);
39685
39686 +#ifdef CONFIG_GRKERNSEC
39687 + write_lock(&grsec_exec_file_lock);
39688 + if (current->exec_file) {
39689 + fput(current->exec_file);
39690 + current->exec_file = NULL;
39691 + }
39692 + write_unlock(&grsec_exec_file_lock);
39693 +#endif
39694 +
39695 ptrace_unlink(current);
39696 /* Reparent to init */
39697 current->real_parent = current->parent = kthreadd_task;
39698 list_move_tail(&current->sibling, &current->real_parent->children);
39699
39700 + gr_set_kernel_label(current);
39701 +
39702 /* Set the exit signal to SIGCHLD so we signal init on exit */
39703 current->exit_signal = SIGCHLD;
39704
39705 @@ -426,6 +443,17 @@ void daemonize(const char *name, ...)
39706 vsnprintf(current->comm, sizeof(current->comm), name, args);
39707 va_end(args);
39708
39709 +#ifdef CONFIG_GRKERNSEC
39710 + write_lock(&grsec_exec_file_lock);
39711 + if (current->exec_file) {
39712 + fput(current->exec_file);
39713 + current->exec_file = NULL;
39714 + }
39715 + write_unlock(&grsec_exec_file_lock);
39716 +#endif
39717 +
39718 + gr_set_kernel_label(current);
39719 +
39720 /*
39721 * If we were started as result of loading a module, close all of the
39722 * user space pages. We don't need them, and if we didn't close them
39723 @@ -953,6 +981,9 @@ NORET_TYPE void do_exit(long code)
39724 tsk->exit_code = code;
39725 taskstats_exit(tsk, group_dead);
39726
39727 + gr_acl_handle_psacct(tsk, code);
39728 + gr_acl_handle_exit();
39729 +
39730 exit_mm(tsk);
39731
39732 if (group_dead)
39733 @@ -1171,7 +1202,7 @@ static int wait_task_zombie(struct wait_
39734
39735 if (unlikely(wo->wo_flags & WNOWAIT)) {
39736 int exit_code = p->exit_code;
39737 - int why, status;
39738 + int why;
39739
39740 get_task_struct(p);
39741 read_unlock(&tasklist_lock);
39742 diff -urNp linux-2.6.31.1/kernel/fork.c linux-2.6.31.1/kernel/fork.c
39743 --- linux-2.6.31.1/kernel/fork.c 2009-09-24 11:45:25.000000000 -0400
39744 +++ linux-2.6.31.1/kernel/fork.c 2009-10-01 20:12:45.000000000 -0400
39745 @@ -244,7 +244,7 @@ static struct task_struct *dup_task_stru
39746 *stackend = STACK_END_MAGIC; /* for overflow detection */
39747
39748 #ifdef CONFIG_CC_STACKPROTECTOR
39749 - tsk->stack_canary = get_random_int();
39750 + tsk->stack_canary = pax_get_random_long();
39751 #endif
39752
39753 /* One for us, one for whoever does the "release_task()" (usually parent) */
39754 @@ -281,8 +281,8 @@ static int dup_mmap(struct mm_struct *mm
39755 mm->locked_vm = 0;
39756 mm->mmap = NULL;
39757 mm->mmap_cache = NULL;
39758 - mm->free_area_cache = oldmm->mmap_base;
39759 - mm->cached_hole_size = ~0UL;
39760 + mm->free_area_cache = oldmm->free_area_cache;
39761 + mm->cached_hole_size = oldmm->cached_hole_size;
39762 mm->map_count = 0;
39763 cpumask_clear(mm_cpumask(mm));
39764 mm->mm_rb = RB_ROOT;
39765 @@ -319,6 +319,7 @@ static int dup_mmap(struct mm_struct *mm
39766 tmp->vm_flags &= ~VM_LOCKED;
39767 tmp->vm_mm = mm;
39768 tmp->vm_next = NULL;
39769 + tmp->vm_mirror = NULL;
39770 anon_vma_link(tmp);
39771 file = tmp->vm_file;
39772 if (file) {
39773 @@ -366,6 +367,31 @@ static int dup_mmap(struct mm_struct *mm
39774 if (retval)
39775 goto out;
39776 }
39777 +
39778 +#ifdef CONFIG_PAX_SEGMEXEC
39779 + if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
39780 + struct vm_area_struct *mpnt_m;
39781 +
39782 + for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
39783 + BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
39784 +
39785 + if (!mpnt->vm_mirror)
39786 + continue;
39787 +
39788 + if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
39789 + BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
39790 + mpnt->vm_mirror = mpnt_m;
39791 + } else {
39792 + BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
39793 + mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
39794 + mpnt_m->vm_mirror->vm_mirror = mpnt_m;
39795 + mpnt->vm_mirror->vm_mirror = mpnt;
39796 + }
39797 + }
39798 + BUG_ON(mpnt_m);
39799 + }
39800 +#endif
39801 +
39802 /* a new mm has just been created */
39803 arch_dup_mmap(oldmm, mm);
39804 retval = 0;
39805 @@ -546,9 +572,11 @@ void mm_release(struct task_struct *tsk,
39806 #ifdef CONFIG_FUTEX
39807 if (unlikely(tsk->robust_list))
39808 exit_robust_list(tsk);
39809 + tsk->robust_list = NULL;
39810 #ifdef CONFIG_COMPAT
39811 if (unlikely(tsk->compat_robust_list))
39812 compat_exit_robust_list(tsk);
39813 + tsk->compat_robust_list = NULL;
39814 #endif
39815 #endif
39816
39817 @@ -567,6 +595,7 @@ void mm_release(struct task_struct *tsk,
39818 * the value intact in a core dump, and to save the unnecessary
39819 * trouble otherwise. Userland only wants this done for a sys_exit.
39820 */
39821 +
39822 if (tsk->clear_child_tid) {
39823 if (!(tsk->flags & PF_SIGNALED) &&
39824 atomic_read(&mm->mm_users) > 1) {
39825 @@ -576,7 +605,7 @@ void mm_release(struct task_struct *tsk,
39826 */
39827 put_user(0, tsk->clear_child_tid);
39828 sys_futex(tsk->clear_child_tid, FUTEX_WAKE,
39829 - 1, NULL, NULL, 0);
39830 + 1, NULL, NULL, 0);
39831 }
39832 tsk->clear_child_tid = NULL;
39833 }
39834 @@ -694,7 +723,7 @@ static int copy_fs(unsigned long clone_f
39835 write_unlock(&fs->lock);
39836 return -EAGAIN;
39837 }
39838 - fs->users++;
39839 + atomic_inc(&fs->users);
39840 write_unlock(&fs->lock);
39841 return 0;
39842 }
39843 @@ -977,6 +1006,9 @@ static struct task_struct *copy_process(
39844 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
39845 #endif
39846 retval = -EAGAIN;
39847 +
39848 + gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->real_cred->user->processes), 0);
39849 +
39850 if (atomic_read(&p->real_cred->user->processes) >=
39851 p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
39852 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
39853 @@ -1133,6 +1165,8 @@ static struct task_struct *copy_process(
39854 goto bad_fork_free_pid;
39855 }
39856
39857 + gr_copy_label(p);
39858 +
39859 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
39860 /*
39861 * Clear TID on mm_release()?
39862 @@ -1302,6 +1336,8 @@ bad_fork_cleanup_count:
39863 bad_fork_free:
39864 free_task(p);
39865 fork_out:
39866 + gr_log_forkfail(retval);
39867 +
39868 return ERR_PTR(retval);
39869 }
39870
39871 @@ -1395,6 +1431,8 @@ long do_fork(unsigned long clone_flags,
39872 if (clone_flags & CLONE_PARENT_SETTID)
39873 put_user(nr, parent_tidptr);
39874
39875 + gr_handle_brute_check();
39876 +
39877 if (clone_flags & CLONE_VFORK) {
39878 p->vfork_done = &vfork;
39879 init_completion(&vfork);
39880 @@ -1527,7 +1565,7 @@ static int unshare_fs(unsigned long unsh
39881 return 0;
39882
39883 /* don't need lock here; in the worst case we'll do useless copy */
39884 - if (fs->users == 1)
39885 + if (atomic_read(&fs->users) == 1)
39886 return 0;
39887
39888 *new_fsp = copy_fs_struct(fs);
39889 @@ -1650,7 +1688,7 @@ SYSCALL_DEFINE1(unshare, unsigned long,
39890 fs = current->fs;
39891 write_lock(&fs->lock);
39892 current->fs = new_fs;
39893 - if (--fs->users)
39894 + if (atomic_dec_return(&fs->users))
39895 new_fs = NULL;
39896 else
39897 new_fs = fs;
39898 diff -urNp linux-2.6.31.1/kernel/futex.c linux-2.6.31.1/kernel/futex.c
39899 --- linux-2.6.31.1/kernel/futex.c 2009-09-24 11:45:25.000000000 -0400
39900 +++ linux-2.6.31.1/kernel/futex.c 2009-10-01 20:12:45.000000000 -0400
39901 @@ -218,6 +218,11 @@ get_futex_key(u32 __user *uaddr, int fsh
39902 struct page *page;
39903 int err;
39904
39905 +#ifdef CONFIG_PAX_SEGMEXEC
39906 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
39907 + return -EFAULT;
39908 +#endif
39909 +
39910 /*
39911 * The futex address must be "naturally" aligned.
39912 */
39913 @@ -1788,7 +1793,7 @@ static int futex_wait(u32 __user *uaddr,
39914
39915 restart = &current_thread_info()->restart_block;
39916 restart->fn = futex_wait_restart;
39917 - restart->futex.uaddr = (u32 *)uaddr;
39918 + restart->futex.uaddr = uaddr;
39919 restart->futex.val = val;
39920 restart->futex.time = abs_time->tv64;
39921 restart->futex.bitset = bitset;
39922 @@ -2403,7 +2408,7 @@ retry:
39923 */
39924 static inline int fetch_robust_entry(struct robust_list __user **entry,
39925 struct robust_list __user * __user *head,
39926 - int *pi)
39927 + unsigned int *pi)
39928 {
39929 unsigned long uentry;
39930
39931 diff -urNp linux-2.6.31.1/kernel/gcov/base.c linux-2.6.31.1/kernel/gcov/base.c
39932 --- linux-2.6.31.1/kernel/gcov/base.c 2009-09-24 11:45:25.000000000 -0400
39933 +++ linux-2.6.31.1/kernel/gcov/base.c 2009-10-01 20:12:45.000000000 -0400
39934 @@ -102,11 +102,6 @@ void gcov_enable_events(void)
39935 }
39936
39937 #ifdef CONFIG_MODULES
39938 -static inline int within(void *addr, void *start, unsigned long size)
39939 -{
39940 - return ((addr >= start) && (addr < start + size));
39941 -}
39942 -
39943 /* Update list and generate events when modules are unloaded. */
39944 static int gcov_module_notifier(struct notifier_block *nb, unsigned long event,
39945 void *data)
39946 @@ -121,7 +116,7 @@ static int gcov_module_notifier(struct n
39947 prev = NULL;
39948 /* Remove entries located in module from linked list. */
39949 for (info = gcov_info_head; info; info = info->next) {
39950 - if (within(info, mod->module_core, mod->core_size)) {
39951 + if (within_module_core_rw((unsigned long)info, mod)) {
39952 if (prev)
39953 prev->next = info->next;
39954 else
39955 diff -urNp linux-2.6.31.1/kernel/kallsyms.c linux-2.6.31.1/kernel/kallsyms.c
39956 --- linux-2.6.31.1/kernel/kallsyms.c 2009-09-24 11:45:25.000000000 -0400
39957 +++ linux-2.6.31.1/kernel/kallsyms.c 2009-10-01 20:12:45.000000000 -0400
39958 @@ -11,6 +11,9 @@
39959 * Changed the compression method from stem compression to "table lookup"
39960 * compression (see scripts/kallsyms.c for a more complete description)
39961 */
39962 +#ifdef CONFIG_GRKERNSEC_HIDESYM
39963 +#define __INCLUDED_BY_HIDESYM 1
39964 +#endif
39965 #include <linux/kallsyms.h>
39966 #include <linux/module.h>
39967 #include <linux/init.h>
39968 @@ -51,6 +54,9 @@ extern const unsigned long kallsyms_mark
39969
39970 static inline int is_kernel_inittext(unsigned long addr)
39971 {
39972 + if (system_state != SYSTEM_BOOTING)
39973 + return 0;
39974 +
39975 if (addr >= (unsigned long)_sinittext
39976 && addr <= (unsigned long)_einittext)
39977 return 1;
39978 @@ -66,6 +72,16 @@ static inline int is_kernel_text(unsigne
39979
39980 static inline int is_kernel(unsigned long addr)
39981 {
39982 +
39983 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
39984 + if ((unsigned long)&MODULES_EXEC_VADDR <= ktla_ktva(addr) &&
39985 + ktla_ktva(addr) < (unsigned long)&MODULES_EXEC_END)
39986 + return 0;
39987 +#endif
39988 +
39989 + if (is_kernel_inittext(addr))
39990 + return 1;
39991 +
39992 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
39993 return 1;
39994 return in_gate_area_no_task(addr);
39995 @@ -412,7 +428,6 @@ static unsigned long get_ksymbol_core(st
39996
39997 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
39998 {
39999 - iter->name[0] = '\0';
40000 iter->nameoff = get_symbol_offset(new_pos);
40001 iter->pos = new_pos;
40002 }
40003 @@ -500,7 +515,7 @@ static int kallsyms_open(struct inode *i
40004 struct kallsym_iter *iter;
40005 int ret;
40006
40007 - iter = kmalloc(sizeof(*iter), GFP_KERNEL);
40008 + iter = kzalloc(sizeof(*iter), GFP_KERNEL);
40009 if (!iter)
40010 return -ENOMEM;
40011 reset_iter(iter, 0);
40012 @@ -522,7 +537,15 @@ static const struct file_operations kall
40013
40014 static int __init kallsyms_init(void)
40015 {
40016 +#if defined(CONFIG_GRKERNSEC_PROC_ADD) || defined(CONFIG_GRKERNSEC_HIDESYM)
40017 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_HIDESYM)
40018 + proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
40019 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
40020 + proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
40021 +#endif
40022 +#else
40023 proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
40024 +#endif
40025 return 0;
40026 }
40027 device_initcall(kallsyms_init);
40028 diff -urNp linux-2.6.31.1/kernel/kmod.c linux-2.6.31.1/kernel/kmod.c
40029 --- linux-2.6.31.1/kernel/kmod.c 2009-09-24 11:45:25.000000000 -0400
40030 +++ linux-2.6.31.1/kernel/kmod.c 2009-10-01 20:12:45.000000000 -0400
40031 @@ -84,6 +84,18 @@ int __request_module(bool wait, const ch
40032 if (ret >= MODULE_NAME_LEN)
40033 return -ENAMETOOLONG;
40034
40035 +#ifdef CONFIG_GRKERNSEC_MODHARDEN
40036 + /* we could do a tighter check here, but some distros
40037 + are taking it upon themselves to remove CAP_SYS_MODULE
40038 + from even root-running apps which cause modules to be
40039 + auto-loaded
40040 + */
40041 + if (current_uid()) {
40042 + gr_log_nonroot_mod_load(module_name);
40043 + return -EPERM;
40044 + }
40045 +#endif
40046 +
40047 /* If modprobe needs a service that is in a module, we get a recursive
40048 * loop. Limit the number of running kmod threads to max_threads/2 or
40049 * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method
40050 diff -urNp linux-2.6.31.1/kernel/kprobes.c linux-2.6.31.1/kernel/kprobes.c
40051 --- linux-2.6.31.1/kernel/kprobes.c 2009-09-24 11:45:25.000000000 -0400
40052 +++ linux-2.6.31.1/kernel/kprobes.c 2009-10-01 20:12:45.000000000 -0400
40053 @@ -184,7 +184,7 @@ static kprobe_opcode_t __kprobes *__get_
40054 * kernel image and loaded module images reside. This is required
40055 * so x86_64 can correctly handle the %rip-relative fixups.
40056 */
40057 - kip->insns = module_alloc(PAGE_SIZE);
40058 + kip->insns = module_alloc_exec(PAGE_SIZE);
40059 if (!kip->insns) {
40060 kfree(kip);
40061 return NULL;
40062 @@ -225,7 +225,7 @@ static int __kprobes collect_one_slot(st
40063 hlist_add_head(&kip->hlist,
40064 &kprobe_insn_pages);
40065 } else {
40066 - module_free(NULL, kip->insns);
40067 + module_free_exec(NULL, kip->insns);
40068 kfree(kip);
40069 }
40070 return 1;
40071 @@ -1329,7 +1329,7 @@ static int __kprobes show_kprobe_addr(st
40072 return 0;
40073 }
40074
40075 -static struct seq_operations kprobes_seq_ops = {
40076 +static const struct seq_operations kprobes_seq_ops = {
40077 .start = kprobe_seq_start,
40078 .next = kprobe_seq_next,
40079 .stop = kprobe_seq_stop,
40080 @@ -1341,7 +1341,7 @@ static int __kprobes kprobes_open(struct
40081 return seq_open(filp, &kprobes_seq_ops);
40082 }
40083
40084 -static struct file_operations debugfs_kprobes_operations = {
40085 +static const struct file_operations debugfs_kprobes_operations = {
40086 .open = kprobes_open,
40087 .read = seq_read,
40088 .llseek = seq_lseek,
40089 @@ -1523,7 +1523,7 @@ static ssize_t write_enabled_file_bool(s
40090 return count;
40091 }
40092
40093 -static struct file_operations fops_kp = {
40094 +static const struct file_operations fops_kp = {
40095 .read = read_enabled_file_bool,
40096 .write = write_enabled_file_bool,
40097 };
40098 diff -urNp linux-2.6.31.1/kernel/lockdep.c linux-2.6.31.1/kernel/lockdep.c
40099 --- linux-2.6.31.1/kernel/lockdep.c 2009-09-24 11:45:25.000000000 -0400
40100 +++ linux-2.6.31.1/kernel/lockdep.c 2009-10-01 20:12:45.000000000 -0400
40101 @@ -630,6 +630,10 @@ static int static_obj(void *obj)
40102 int i;
40103 #endif
40104
40105 +#ifdef CONFIG_PAX_KERNEXEC
40106 + start = (unsigned long )&_sdata;
40107 +#endif
40108 +
40109 /*
40110 * static variable?
40111 */
40112 @@ -641,9 +645,12 @@ static int static_obj(void *obj)
40113 * percpu var?
40114 */
40115 for_each_possible_cpu(i) {
40116 +#ifdef CONFIG_X86_32
40117 + start = per_cpu_offset(i);
40118 +#else
40119 start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
40120 - end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
40121 - + per_cpu_offset(i);
40122 +#endif
40123 + end = start + PERCPU_ENOUGH_ROOM;
40124
40125 if ((addr >= start) && (addr < end))
40126 return 1;
40127 diff -urNp linux-2.6.31.1/kernel/lockdep_proc.c linux-2.6.31.1/kernel/lockdep_proc.c
40128 --- linux-2.6.31.1/kernel/lockdep_proc.c 2009-09-24 11:45:25.000000000 -0400
40129 +++ linux-2.6.31.1/kernel/lockdep_proc.c 2009-10-01 20:12:45.000000000 -0400
40130 @@ -670,7 +670,7 @@ static int ls_show(struct seq_file *m, v
40131 return 0;
40132 }
40133
40134 -static struct seq_operations lockstat_ops = {
40135 +static const struct seq_operations lockstat_ops = {
40136 .start = ls_start,
40137 .next = ls_next,
40138 .stop = ls_stop,
40139 diff -urNp linux-2.6.31.1/kernel/module.c linux-2.6.31.1/kernel/module.c
40140 --- linux-2.6.31.1/kernel/module.c 2009-09-24 11:45:25.000000000 -0400
40141 +++ linux-2.6.31.1/kernel/module.c 2009-10-01 20:12:45.000000000 -0400
40142 @@ -47,6 +47,11 @@
40143 #include <linux/rculist.h>
40144 #include <asm/uaccess.h>
40145 #include <asm/cacheflush.h>
40146 +
40147 +#ifdef CONFIG_PAX_KERNEXEC
40148 +#include <asm/desc.h>
40149 +#endif
40150 +
40151 #include <linux/license.h>
40152 #include <asm/sections.h>
40153 #include <linux/tracepoint.h>
40154 @@ -83,7 +88,8 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
40155 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
40156
40157 /* Bounds of module allocation, for speeding __module_address */
40158 -static unsigned long module_addr_min = -1UL, module_addr_max = 0;
40159 +static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
40160 +static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
40161
40162 int register_module_notifier(struct notifier_block * nb)
40163 {
40164 @@ -239,7 +245,7 @@ bool each_symbol(bool (*fn)(const struct
40165 return true;
40166
40167 list_for_each_entry_rcu(mod, &modules, list) {
40168 - struct symsearch arr[] = {
40169 + struct symsearch modarr[] = {
40170 { mod->syms, mod->syms + mod->num_syms, mod->crcs,
40171 NOT_GPL_ONLY, false },
40172 { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
40173 @@ -261,7 +267,7 @@ bool each_symbol(bool (*fn)(const struct
40174 #endif
40175 };
40176
40177 - if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
40178 + if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
40179 return true;
40180 }
40181 return false;
40182 @@ -436,7 +442,7 @@ static void *percpu_modalloc(unsigned lo
40183 void *ptr;
40184 int cpu;
40185
40186 - if (align > PAGE_SIZE) {
40187 + if (align-1 >= PAGE_SIZE) {
40188 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
40189 name, align, PAGE_SIZE);
40190 align = PAGE_SIZE;
40191 @@ -549,7 +555,11 @@ static void percpu_modcopy(void *pcpudes
40192 int cpu;
40193
40194 for_each_possible_cpu(cpu)
40195 +#ifdef CONFIG_X86_32
40196 + memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
40197 +#else
40198 memcpy(pcpudest + per_cpu_offset(cpu), from, size);
40199 +#endif
40200 }
40201
40202 #else /* ... !CONFIG_SMP */
40203 @@ -1513,7 +1523,8 @@ static void free_module(struct module *m
40204 destroy_params(mod->kp, mod->num_kp);
40205
40206 /* This may be NULL, but that's OK */
40207 - module_free(mod, mod->module_init);
40208 + module_free(mod, mod->module_init_rw);
40209 + module_free_exec(mod, mod->module_init_rx);
40210 kfree(mod->args);
40211 if (mod->percpu)
40212 percpu_modfree(mod->percpu);
40213 @@ -1522,10 +1533,12 @@ static void free_module(struct module *m
40214 percpu_modfree(mod->refptr);
40215 #endif
40216 /* Free lock-classes: */
40217 - lockdep_free_key_range(mod->module_core, mod->core_size);
40218 + lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
40219 + lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
40220
40221 /* Finally, free the core (containing the module structure) */
40222 - module_free(mod, mod->module_core);
40223 + module_free_exec(mod, mod->module_core_rx);
40224 + module_free(mod, mod->module_core_rw);
40225 }
40226
40227 void *__symbol_get(const char *symbol)
40228 @@ -1593,6 +1606,10 @@ static int simplify_symbols(Elf_Shdr *se
40229 int ret = 0;
40230 const struct kernel_symbol *ksym;
40231
40232 +#ifdef CONFIG_PAX_KERNEXEC
40233 + unsigned long cr0;
40234 +#endif
40235 +
40236 for (i = 1; i < n; i++) {
40237 switch (sym[i].st_shndx) {
40238 case SHN_COMMON:
40239 @@ -1615,7 +1632,17 @@ static int simplify_symbols(Elf_Shdr *se
40240 strtab + sym[i].st_name, mod);
40241 /* Ok if resolved. */
40242 if (ksym) {
40243 +
40244 +#ifdef CONFIG_PAX_KERNEXEC
40245 + pax_open_kernel(cr0);
40246 +#endif
40247 +
40248 sym[i].st_value = ksym->value;
40249 +
40250 +#ifdef CONFIG_PAX_KERNEXEC
40251 + pax_close_kernel(cr0);
40252 +#endif
40253 +
40254 break;
40255 }
40256
40257 @@ -1634,7 +1661,17 @@ static int simplify_symbols(Elf_Shdr *se
40258 secbase = (unsigned long)mod->percpu;
40259 else
40260 secbase = sechdrs[sym[i].st_shndx].sh_addr;
40261 +
40262 +#ifdef CONFIG_PAX_KERNEXEC
40263 + pax_open_kernel(cr0);
40264 +#endif
40265 +
40266 sym[i].st_value += secbase;
40267 +
40268 +#ifdef CONFIG_PAX_KERNEXEC
40269 + pax_close_kernel(cr0);
40270 +#endif
40271 +
40272 break;
40273 }
40274 }
40275 @@ -1695,11 +1732,12 @@ static void layout_sections(struct modul
40276 || s->sh_entsize != ~0UL
40277 || strstarts(secstrings + s->sh_name, ".init"))
40278 continue;
40279 - s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
40280 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
40281 + s->sh_entsize = get_offset(mod, &mod->core_size_rw, s, i);
40282 + else
40283 + s->sh_entsize = get_offset(mod, &mod->core_size_rx, s, i);
40284 DEBUGP("\t%s\n", secstrings + s->sh_name);
40285 }
40286 - if (m == 0)
40287 - mod->core_text_size = mod->core_size;
40288 }
40289
40290 DEBUGP("Init section allocation order:\n");
40291 @@ -1712,12 +1750,13 @@ static void layout_sections(struct modul
40292 || s->sh_entsize != ~0UL
40293 || !strstarts(secstrings + s->sh_name, ".init"))
40294 continue;
40295 - s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
40296 - | INIT_OFFSET_MASK);
40297 + if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
40298 + s->sh_entsize = get_offset(mod, &mod->init_size_rw, s, i);
40299 + else
40300 + s->sh_entsize = get_offset(mod, &mod->init_size_rx, s, i);
40301 + s->sh_entsize |= INIT_OFFSET_MASK;
40302 DEBUGP("\t%s\n", secstrings + s->sh_name);
40303 }
40304 - if (m == 0)
40305 - mod->init_text_size = mod->init_size;
40306 }
40307 }
40308
40309 @@ -1856,14 +1895,31 @@ static void add_kallsyms(struct module *
40310 {
40311 unsigned int i;
40312
40313 +#ifdef CONFIG_PAX_KERNEXEC
40314 + unsigned long cr0;
40315 +#endif
40316 +
40317 mod->symtab = (void *)sechdrs[symindex].sh_addr;
40318 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
40319 mod->strtab = (void *)sechdrs[strindex].sh_addr;
40320
40321 /* Set types up while we still have access to sections. */
40322 - for (i = 0; i < mod->num_symtab; i++)
40323 - mod->symtab[i].st_info
40324 - = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
40325 +
40326 + for (i = 0; i < mod->num_symtab; i++) {
40327 + char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
40328 +
40329 +#ifdef CONFIG_PAX_KERNEXEC
40330 + pax_open_kernel(cr0);
40331 +#endif
40332 +
40333 + mod->symtab[i].st_info = type;
40334 +
40335 +#ifdef CONFIG_PAX_KERNEXEC
40336 + pax_close_kernel(cr0);
40337 +#endif
40338 +
40339 + }
40340 +
40341 }
40342 #else
40343 static inline void add_kallsyms(struct module *mod,
40344 @@ -1884,16 +1940,30 @@ static void dynamic_debug_setup(struct _
40345 #endif
40346 }
40347
40348 -static void *module_alloc_update_bounds(unsigned long size)
40349 +static void *module_alloc_update_bounds_rw(unsigned long size)
40350 {
40351 void *ret = module_alloc(size);
40352
40353 if (ret) {
40354 /* Update module bounds. */
40355 - if ((unsigned long)ret < module_addr_min)
40356 - module_addr_min = (unsigned long)ret;
40357 - if ((unsigned long)ret + size > module_addr_max)
40358 - module_addr_max = (unsigned long)ret + size;
40359 + if ((unsigned long)ret < module_addr_min_rw)
40360 + module_addr_min_rw = (unsigned long)ret;
40361 + if ((unsigned long)ret + size > module_addr_max_rw)
40362 + module_addr_max_rw = (unsigned long)ret + size;
40363 + }
40364 + return ret;
40365 +}
40366 +
40367 +static void *module_alloc_update_bounds_rx(unsigned long size)
40368 +{
40369 + void *ret = module_alloc_exec(size);
40370 +
40371 + if (ret) {
40372 + /* Update module bounds. */
40373 + if ((unsigned long)ret < module_addr_min_rx)
40374 + module_addr_min_rx = (unsigned long)ret;
40375 + if ((unsigned long)ret + size > module_addr_max_rx)
40376 + module_addr_max_rx = (unsigned long)ret + size;
40377 }
40378 return ret;
40379 }
40380 @@ -1905,8 +1975,8 @@ static void kmemleak_load_module(struct
40381 unsigned int i;
40382
40383 /* only scan the sections containing data */
40384 - kmemleak_scan_area(mod->module_core, (unsigned long)mod -
40385 - (unsigned long)mod->module_core,
40386 + kmemleak_scan_area(mod->module_core_rw, (unsigned long)mod -
40387 + (unsigned long)mod->module_core_rw,
40388 sizeof(struct module), GFP_KERNEL);
40389
40390 for (i = 1; i < hdr->e_shnum; i++) {
40391 @@ -1916,8 +1986,8 @@ static void kmemleak_load_module(struct
40392 && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0)
40393 continue;
40394
40395 - kmemleak_scan_area(mod->module_core, sechdrs[i].sh_addr -
40396 - (unsigned long)mod->module_core,
40397 + kmemleak_scan_area(mod->module_core_rw, sechdrs[i].sh_addr -
40398 + (unsigned long)mod->module_core_rw,
40399 sechdrs[i].sh_size, GFP_KERNEL);
40400 }
40401 }
40402 @@ -1947,6 +2017,10 @@ static noinline struct module *load_modu
40403 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
40404 mm_segment_t old_fs;
40405
40406 +#ifdef CONFIG_PAX_KERNEXEC
40407 + unsigned long cr0;
40408 +#endif
40409 +
40410 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
40411 umod, len, uargs);
40412 if (len < sizeof(*hdr))
40413 @@ -2097,7 +2171,7 @@ static noinline struct module *load_modu
40414 layout_sections(mod, hdr, sechdrs, secstrings);
40415
40416 /* Do the allocs. */
40417 - ptr = module_alloc_update_bounds(mod->core_size);
40418 + ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
40419 /*
40420 * The pointer to this block is stored in the module structure
40421 * which is inside the block. Just mark it as not being a
40422 @@ -2108,23 +2182,61 @@ static noinline struct module *load_modu
40423 err = -ENOMEM;
40424 goto free_percpu;
40425 }
40426 - memset(ptr, 0, mod->core_size);
40427 - mod->module_core = ptr;
40428 + memset(ptr, 0, mod->core_size_rw);
40429 + mod->module_core_rw = ptr;
40430
40431 - ptr = module_alloc_update_bounds(mod->init_size);
40432 + ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
40433 /*
40434 * The pointer to this block is stored in the module structure
40435 * which is inside the block. This block doesn't need to be
40436 * scanned as it contains data and code that will be freed
40437 * after the module is initialized.
40438 */
40439 - kmemleak_ignore(ptr);
40440 - if (!ptr && mod->init_size) {
40441 + kmemleak_not_leak(ptr);
40442 + if (!ptr && mod->init_size_rw) {
40443 err = -ENOMEM;
40444 - goto free_core;
40445 + goto free_core_rw;
40446 }
40447 - memset(ptr, 0, mod->init_size);
40448 - mod->module_init = ptr;
40449 + memset(ptr, 0, mod->init_size_rw);
40450 + mod->module_init_rw = ptr;
40451 +
40452 + ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
40453 + kmemleak_not_leak(ptr);
40454 + if (!ptr) {
40455 + err = -ENOMEM;
40456 + goto free_init_rw;
40457 + }
40458 +
40459 +#ifdef CONFIG_PAX_KERNEXEC
40460 + pax_open_kernel(cr0);
40461 +#endif
40462 +
40463 + memset(ptr, 0, mod->core_size_rx);
40464 +
40465 +#ifdef CONFIG_PAX_KERNEXEC
40466 + pax_close_kernel(cr0);
40467 +#endif
40468 +
40469 + mod->module_core_rx = ptr;
40470 +
40471 + ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
40472 + kmemleak_not_leak(ptr);
40473 + if (!ptr && mod->init_size_rx) {
40474 + err = -ENOMEM;
40475 + goto free_core_rx;
40476 + }
40477 +
40478 +#ifdef CONFIG_PAX_KERNEXEC
40479 + pax_open_kernel(cr0);
40480 +#endif
40481 +
40482 + memset(ptr, 0, mod->init_size_rx);
40483 +
40484 +#ifdef CONFIG_PAX_KERNEXEC
40485 + pax_close_kernel(cr0);
40486 +#endif
40487 +
40488 + mod->module_init_rx = ptr;
40489
40490 /* Transfer each section which specifies SHF_ALLOC */
40491 DEBUGP("final section addresses:\n");
40492 @@ -2134,17 +2246,41 @@ static noinline struct module *load_modu
40493 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
40494 continue;
40495
40496 - if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
40497 - dest = mod->module_init
40498 - + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
40499 - else
40500 - dest = mod->module_core + sechdrs[i].sh_entsize;
40501 + if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
40502 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
40503 + dest = mod->module_init_rw
40504 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
40505 + else
40506 + dest = mod->module_init_rx
40507 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
40508 + } else {
40509 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
40510 + dest = mod->module_core_rw + sechdrs[i].sh_entsize;
40511 + else
40512 + dest = mod->module_core_rx + sechdrs[i].sh_entsize;
40513 + }
40514 +
40515 + if (sechdrs[i].sh_type != SHT_NOBITS) {
40516
40517 - if (sechdrs[i].sh_type != SHT_NOBITS)
40518 - memcpy(dest, (void *)sechdrs[i].sh_addr,
40519 - sechdrs[i].sh_size);
40520 +#ifdef CONFIG_PAX_KERNEXEC
40521 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
40522 + pax_open_kernel(cr0);
40523 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
40524 + pax_close_kernel(cr0);
40525 + } else
40526 +#endif
40527 +
40528 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
40529 + }
40530 /* Update sh_addr to point to copy in image. */
40531 - sechdrs[i].sh_addr = (unsigned long)dest;
40532 +
40533 +#ifdef CONFIG_PAX_KERNEXEC
40534 + if (sechdrs[i].sh_flags & SHF_EXECINSTR)
40535 + sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
40536 + else
40537 +#endif
40538 +
40539 + sechdrs[i].sh_addr = (unsigned long)dest;
40540 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
40541 }
40542 /* Module has been moved. */
40543 @@ -2156,7 +2292,7 @@ static noinline struct module *load_modu
40544 mod->name);
40545 if (!mod->refptr) {
40546 err = -ENOMEM;
40547 - goto free_init;
40548 + goto free_init_rx;
40549 }
40550 #endif
40551 /* Now we've moved module, initialize linked lists, etc. */
40552 @@ -2269,8 +2405,8 @@ static noinline struct module *load_modu
40553
40554 /* Now do relocations. */
40555 for (i = 1; i < hdr->e_shnum; i++) {
40556 - const char *strtab = (char *)sechdrs[strindex].sh_addr;
40557 unsigned int info = sechdrs[i].sh_info;
40558 + strtab = (char *)sechdrs[strindex].sh_addr;
40559
40560 /* Not a valid relocation section? */
40561 if (info >= hdr->e_shnum)
40562 @@ -2328,12 +2464,12 @@ static noinline struct module *load_modu
40563 * Do it before processing of module parameters, so the module
40564 * can provide parameter accessor functions of its own.
40565 */
40566 - if (mod->module_init)
40567 - flush_icache_range((unsigned long)mod->module_init,
40568 - (unsigned long)mod->module_init
40569 - + mod->init_size);
40570 - flush_icache_range((unsigned long)mod->module_core,
40571 - (unsigned long)mod->module_core + mod->core_size);
40572 + if (mod->module_init_rx)
40573 + flush_icache_range((unsigned long)mod->module_init_rx,
40574 + (unsigned long)mod->module_init_rx
40575 + + mod->init_size_rx);
40576 + flush_icache_range((unsigned long)mod->module_core_rx,
40577 + (unsigned long)mod->module_core_rx + mod->core_size_rx);
40578
40579 set_fs(old_fs);
40580
40581 @@ -2378,12 +2514,16 @@ static noinline struct module *load_modu
40582 free_unload:
40583 module_unload_free(mod);
40584 #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
40585 - free_init:
40586 + free_init_rx:
40587 percpu_modfree(mod->refptr);
40588 #endif
40589 - module_free(mod, mod->module_init);
40590 - free_core:
40591 - module_free(mod, mod->module_core);
40592 + module_free_exec(mod, mod->module_init_rx);
40593 + free_core_rx:
40594 + module_free_exec(mod, mod->module_core_rx);
40595 + free_init_rw:
40596 + module_free(mod, mod->module_init_rw);
40597 + free_core_rw:
40598 + module_free(mod, mod->module_core_rw);
40599 /* mod will be freed with core. Don't access it beyond this line! */
40600 free_percpu:
40601 if (percpu)
40602 @@ -2479,10 +2619,12 @@ SYSCALL_DEFINE3(init_module, void __user
40603 /* Drop initial reference. */
40604 module_put(mod);
40605 trim_init_extable(mod);
40606 - module_free(mod, mod->module_init);
40607 - mod->module_init = NULL;
40608 - mod->init_size = 0;
40609 - mod->init_text_size = 0;
40610 + module_free(mod, mod->module_init_rw);
40611 + module_free_exec(mod, mod->module_init_rx);
40612 + mod->module_init_rw = NULL;
40613 + mod->module_init_rx = NULL;
40614 + mod->init_size_rw = 0;
40615 + mod->init_size_rx = 0;
40616 mutex_unlock(&module_mutex);
40617
40618 return 0;
40619 @@ -2513,10 +2655,16 @@ static const char *get_ksymbol(struct mo
40620 unsigned long nextval;
40621
40622 /* At worse, next value is at end of module */
40623 - if (within_module_init(addr, mod))
40624 - nextval = (unsigned long)mod->module_init+mod->init_text_size;
40625 + if (within_module_init_rx(addr, mod))
40626 + nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
40627 + else if (within_module_init_rw(addr, mod))
40628 + nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
40629 + else if (within_module_core_rx(addr, mod))
40630 + nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
40631 + else if (within_module_core_rw(addr, mod))
40632 + nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
40633 else
40634 - nextval = (unsigned long)mod->module_core+mod->core_text_size;
40635 + return NULL;
40636
40637 /* Scan for closest preceeding symbol, and next symbol. (ELF
40638 starts real symbols at 1). */
40639 @@ -2762,7 +2910,7 @@ static int m_show(struct seq_file *m, vo
40640 char buf[8];
40641
40642 seq_printf(m, "%s %u",
40643 - mod->name, mod->init_size + mod->core_size);
40644 + mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
40645 print_unload_info(m, mod);
40646
40647 /* Informative for users. */
40648 @@ -2771,7 +2919,7 @@ static int m_show(struct seq_file *m, vo
40649 mod->state == MODULE_STATE_COMING ? "Loading":
40650 "Live");
40651 /* Used by oprofile and other similar tools. */
40652 - seq_printf(m, " 0x%p", mod->module_core);
40653 + seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
40654
40655 /* Taints info */
40656 if (mod->taints)
40657 @@ -2807,7 +2955,17 @@ static const struct file_operations proc
40658
40659 static int __init proc_modules_init(void)
40660 {
40661 +#ifndef CONFIG_GRKERNSEC_HIDESYM
40662 +#ifdef CONFIG_GRKERNSEC_PROC_USER
40663 + proc_create("modules", S_IRUSR, NULL, &proc_modules_operations);
40664 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
40665 + proc_create("modules", S_IRUSR | S_IRGRP, NULL, &proc_modules_operations);
40666 +#else
40667 proc_create("modules", 0, NULL, &proc_modules_operations);
40668 +#endif
40669 +#else
40670 + proc_create("modules", S_IRUSR, NULL, &proc_modules_operations);
40671 +#endif
40672 return 0;
40673 }
40674 module_init(proc_modules_init);
40675 @@ -2866,12 +3024,12 @@ struct module *__module_address(unsigned
40676 {
40677 struct module *mod;
40678
40679 - if (addr < module_addr_min || addr > module_addr_max)
40680 + if ((addr < module_addr_min_rx || addr > module_addr_max_rx) &&
40681 + (addr < module_addr_min_rw || addr > module_addr_max_rw))
40682 return NULL;
40683
40684 list_for_each_entry_rcu(mod, &modules, list)
40685 - if (within_module_core(addr, mod)
40686 - || within_module_init(addr, mod))
40687 + if (within_module_init(addr, mod) || within_module_core(addr, mod))
40688 return mod;
40689 return NULL;
40690 }
40691 @@ -2905,11 +3063,20 @@ bool is_module_text_address(unsigned lon
40692 */
40693 struct module *__module_text_address(unsigned long addr)
40694 {
40695 - struct module *mod = __module_address(addr);
40696 + struct module *mod;
40697 +
40698 +#ifdef CONFIG_X86_32
40699 + addr = ktla_ktva(addr);
40700 +#endif
40701 +
40702 + if (addr < module_addr_min_rx || addr > module_addr_max_rx)
40703 + return NULL;
40704 +
40705 + mod = __module_address(addr);
40706 +
40707 if (mod) {
40708 /* Make sure it's within the text section. */
40709 - if (!within(addr, mod->module_init, mod->init_text_size)
40710 - && !within(addr, mod->module_core, mod->core_text_size))
40711 + if (!within_module_init_rx(addr, mod) && !within_module_core_rx(addr, mod))
40712 mod = NULL;
40713 }
40714 return mod;
40715 diff -urNp linux-2.6.31.1/kernel/panic.c linux-2.6.31.1/kernel/panic.c
40716 --- linux-2.6.31.1/kernel/panic.c 2009-09-24 11:45:25.000000000 -0400
40717 +++ linux-2.6.31.1/kernel/panic.c 2009-10-01 20:12:45.000000000 -0400
40718 @@ -391,7 +391,8 @@ EXPORT_SYMBOL(warn_slowpath_null);
40719 */
40720 void __stack_chk_fail(void)
40721 {
40722 - panic("stack-protector: Kernel stack is corrupted in: %p\n",
40723 + dump_stack();
40724 + panic("stack-protector: Kernel stack is corrupted in: %pS\n",
40725 __builtin_return_address(0));
40726 }
40727 EXPORT_SYMBOL(__stack_chk_fail);
40728 diff -urNp linux-2.6.31.1/kernel/params.c linux-2.6.31.1/kernel/params.c
40729 --- linux-2.6.31.1/kernel/params.c 2009-09-24 11:45:25.000000000 -0400
40730 +++ linux-2.6.31.1/kernel/params.c 2009-10-01 20:12:45.000000000 -0400
40731 @@ -217,13 +217,9 @@ int param_set_charp(const char *val, str
40732 return -ENOSPC;
40733 }
40734
40735 - if (kp->flags & KPARAM_KMALLOCED)
40736 - kfree(*(char **)kp->arg);
40737 -
40738 /* This is a hack. We can't need to strdup in early boot, and we
40739 * don't need to; this mangled commandline is preserved. */
40740 if (slab_is_available()) {
40741 - kp->flags |= KPARAM_KMALLOCED;
40742 *(char **)kp->arg = kstrdup(val, GFP_KERNEL);
40743 if (!kp->arg)
40744 return -ENOMEM;
40745 @@ -607,7 +603,7 @@ void destroy_params(const struct kernel_
40746 unsigned int i;
40747
40748 for (i = 0; i < num; i++)
40749 - if (params[i].flags & KPARAM_KMALLOCED)
40750 + if (params[i].set == param_set_charp)
40751 kfree(*(char **)params[i].arg);
40752 }
40753
40754 diff -urNp linux-2.6.31.1/kernel/perf_counter.c linux-2.6.31.1/kernel/perf_counter.c
40755 --- linux-2.6.31.1/kernel/perf_counter.c 2009-09-24 11:45:25.000000000 -0400
40756 +++ linux-2.6.31.1/kernel/perf_counter.c 2009-10-01 20:12:45.000000000 -0400
40757 @@ -2231,7 +2231,7 @@ static void perf_mmap_close(struct vm_ar
40758 }
40759 }
40760
40761 -static struct vm_operations_struct perf_mmap_vmops = {
40762 +static const struct vm_operations_struct perf_mmap_vmops = {
40763 .open = perf_mmap_open,
40764 .close = perf_mmap_close,
40765 .fault = perf_mmap_fault,
40766 @@ -4181,7 +4181,7 @@ static int perf_copy_attr(struct perf_co
40767 end = PTR_ALIGN((void __user *)uattr + size,
40768 sizeof(unsigned long));
40769
40770 - for (; addr < end; addr += sizeof(unsigned long)) {
40771 + for (; addr < end; addr++) {
40772 ret = get_user(val, addr);
40773 if (ret)
40774 return ret;
40775 diff -urNp linux-2.6.31.1/kernel/pid.c linux-2.6.31.1/kernel/pid.c
40776 --- linux-2.6.31.1/kernel/pid.c 2009-09-24 11:45:25.000000000 -0400
40777 +++ linux-2.6.31.1/kernel/pid.c 2009-10-01 20:12:45.000000000 -0400
40778 @@ -33,6 +33,7 @@
40779 #include <linux/rculist.h>
40780 #include <linux/bootmem.h>
40781 #include <linux/hash.h>
40782 +#include <linux/security.h>
40783 #include <linux/pid_namespace.h>
40784 #include <linux/init_task.h>
40785 #include <linux/syscalls.h>
40786 @@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
40787
40788 int pid_max = PID_MAX_DEFAULT;
40789
40790 -#define RESERVED_PIDS 300
40791 +#define RESERVED_PIDS 500
40792
40793 int pid_max_min = RESERVED_PIDS + 1;
40794 int pid_max_max = PID_MAX_LIMIT;
40795 @@ -380,7 +381,14 @@ EXPORT_SYMBOL(pid_task);
40796 */
40797 struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
40798 {
40799 - return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
40800 + struct task_struct *task;
40801 +
40802 + task = pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
40803 +
40804 + if (gr_pid_is_chrooted(task))
40805 + return NULL;
40806 +
40807 + return task;
40808 }
40809
40810 struct task_struct *find_task_by_vpid(pid_t vnr)
40811 diff -urNp linux-2.6.31.1/kernel/posix-cpu-timers.c linux-2.6.31.1/kernel/posix-cpu-timers.c
40812 --- linux-2.6.31.1/kernel/posix-cpu-timers.c 2009-09-24 11:45:25.000000000 -0400
40813 +++ linux-2.6.31.1/kernel/posix-cpu-timers.c 2009-10-01 20:12:45.000000000 -0400
40814 @@ -6,6 +6,7 @@
40815 #include <linux/posix-timers.h>
40816 #include <linux/errno.h>
40817 #include <linux/math64.h>
40818 +#include <linux/security.h>
40819 #include <asm/uaccess.h>
40820 #include <linux/kernel_stat.h>
40821
40822 @@ -1041,6 +1042,7 @@ static void check_thread_timers(struct t
40823 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
40824 return;
40825 }
40826 + gr_learn_resource(tsk, RLIMIT_RTTIME, tsk->rt.timeout, 1);
40827 if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) {
40828 /*
40829 * At the soft limit, send a SIGXCPU every second.
40830 @@ -1196,6 +1198,7 @@ static void check_process_timers(struct
40831 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
40832 return;
40833 }
40834 + gr_learn_resource(tsk, RLIMIT_CPU, psecs, 0);
40835 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
40836 /*
40837 * At the soft limit, send a SIGXCPU every second.
40838 diff -urNp linux-2.6.31.1/kernel/power/poweroff.c linux-2.6.31.1/kernel/power/poweroff.c
40839 --- linux-2.6.31.1/kernel/power/poweroff.c 2009-09-24 11:45:25.000000000 -0400
40840 +++ linux-2.6.31.1/kernel/power/poweroff.c 2009-10-01 20:12:45.000000000 -0400
40841 @@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof
40842 .enable_mask = SYSRQ_ENABLE_BOOT,
40843 };
40844
40845 -static int pm_sysrq_init(void)
40846 +static int __init pm_sysrq_init(void)
40847 {
40848 register_sysrq_key('o', &sysrq_poweroff_op);
40849 return 0;
40850 diff -urNp linux-2.6.31.1/kernel/power/process.c linux-2.6.31.1/kernel/power/process.c
40851 --- linux-2.6.31.1/kernel/power/process.c 2009-09-24 11:45:25.000000000 -0400
40852 +++ linux-2.6.31.1/kernel/power/process.c 2009-10-01 20:12:45.000000000 -0400
40853 @@ -36,12 +36,15 @@ static int try_to_freeze_tasks(bool sig_
40854 struct timeval start, end;
40855 u64 elapsed_csecs64;
40856 unsigned int elapsed_csecs;
40857 + bool timedout = false;
40858
40859 do_gettimeofday(&start);
40860
40861 end_time = jiffies + TIMEOUT;
40862 do {
40863 todo = 0;
40864 + if (time_after(jiffies, end_time))
40865 + timedout = true;
40866 read_lock(&tasklist_lock);
40867 do_each_thread(g, p) {
40868 if (frozen(p) || !freezeable(p))
40869 @@ -56,15 +59,17 @@ static int try_to_freeze_tasks(bool sig_
40870 * It is "frozen enough". If the task does wake
40871 * up, it will immediately call try_to_freeze.
40872 */
40873 - if (!task_is_stopped_or_traced(p) &&
40874 - !freezer_should_skip(p))
40875 + if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) {
40876 todo++;
40877 + if (timedout) {
40878 + printk(KERN_ERR "Task refusing to freeze:\n");
40879 + sched_show_task(p);
40880 + }
40881 + }
40882 } while_each_thread(g, p);
40883 read_unlock(&tasklist_lock);
40884 yield(); /* Yield is okay here */
40885 - if (time_after(jiffies, end_time))
40886 - break;
40887 - } while (todo);
40888 + } while (todo && !timedout);
40889
40890 do_gettimeofday(&end);
40891 elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
40892 diff -urNp linux-2.6.31.1/kernel/printk.c linux-2.6.31.1/kernel/printk.c
40893 --- linux-2.6.31.1/kernel/printk.c 2009-09-24 11:45:25.000000000 -0400
40894 +++ linux-2.6.31.1/kernel/printk.c 2009-10-01 20:12:45.000000000 -0400
40895 @@ -272,6 +272,11 @@ int do_syslog(int type, char __user *buf
40896 char c;
40897 int error = 0;
40898
40899 +#ifdef CONFIG_GRKERNSEC_DMESG
40900 + if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
40901 + return -EPERM;
40902 +#endif
40903 +
40904 error = security_syslog(type);
40905 if (error)
40906 return error;
40907 diff -urNp linux-2.6.31.1/kernel/ptrace.c linux-2.6.31.1/kernel/ptrace.c
40908 --- linux-2.6.31.1/kernel/ptrace.c 2009-09-24 11:45:25.000000000 -0400
40909 +++ linux-2.6.31.1/kernel/ptrace.c 2009-10-01 20:12:45.000000000 -0400
40910 @@ -141,7 +141,7 @@ int __ptrace_may_access(struct task_stru
40911 cred->gid != tcred->egid ||
40912 cred->gid != tcred->sgid ||
40913 cred->gid != tcred->gid) &&
40914 - !capable(CAP_SYS_PTRACE)) {
40915 + !capable_nolog(CAP_SYS_PTRACE)) {
40916 rcu_read_unlock();
40917 return -EPERM;
40918 }
40919 @@ -149,7 +149,7 @@ int __ptrace_may_access(struct task_stru
40920 smp_rmb();
40921 if (task->mm)
40922 dumpable = get_dumpable(task->mm);
40923 - if (!dumpable && !capable(CAP_SYS_PTRACE))
40924 + if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
40925 return -EPERM;
40926
40927 return security_ptrace_may_access(task, mode);
40928 @@ -199,7 +199,7 @@ int ptrace_attach(struct task_struct *ta
40929 goto unlock_tasklist;
40930
40931 task->ptrace = PT_PTRACED;
40932 - if (capable(CAP_SYS_PTRACE))
40933 + if (capable_nolog(CAP_SYS_PTRACE))
40934 task->ptrace |= PT_PTRACE_CAP;
40935
40936 __ptrace_link(task, current);
40937 @@ -633,6 +633,11 @@ SYSCALL_DEFINE4(ptrace, long, request, l
40938 if (ret < 0)
40939 goto out_put_task_struct;
40940
40941 + if (gr_handle_ptrace(child, request)) {
40942 + ret = -EPERM;
40943 + goto out_put_task_struct;
40944 + }
40945 +
40946 ret = arch_ptrace(child, request, addr, data);
40947
40948 out_put_task_struct:
40949 diff -urNp linux-2.6.31.1/kernel/rcupreempt_trace.c linux-2.6.31.1/kernel/rcupreempt_trace.c
40950 --- linux-2.6.31.1/kernel/rcupreempt_trace.c 2009-09-24 11:45:25.000000000 -0400
40951 +++ linux-2.6.31.1/kernel/rcupreempt_trace.c 2009-10-01 20:12:45.000000000 -0400
40952 @@ -261,17 +261,17 @@ static ssize_t rcuctrs_read(struct file
40953 return bcount;
40954 }
40955
40956 -static struct file_operations rcustats_fops = {
40957 +static const struct file_operations rcustats_fops = {
40958 .owner = THIS_MODULE,
40959 .read = rcustats_read,
40960 };
40961
40962 -static struct file_operations rcugp_fops = {
40963 +static const struct file_operations rcugp_fops = {
40964 .owner = THIS_MODULE,
40965 .read = rcugp_read,
40966 };
40967
40968 -static struct file_operations rcuctrs_fops = {
40969 +static const struct file_operations rcuctrs_fops = {
40970 .owner = THIS_MODULE,
40971 .read = rcuctrs_read,
40972 };
40973 diff -urNp linux-2.6.31.1/kernel/rcutree_trace.c linux-2.6.31.1/kernel/rcutree_trace.c
40974 --- linux-2.6.31.1/kernel/rcutree_trace.c 2009-09-24 11:45:25.000000000 -0400
40975 +++ linux-2.6.31.1/kernel/rcutree_trace.c 2009-10-01 20:12:45.000000000 -0400
40976 @@ -88,7 +88,7 @@ static int rcudata_open(struct inode *in
40977 return single_open(file, show_rcudata, NULL);
40978 }
40979
40980 -static struct file_operations rcudata_fops = {
40981 +static const struct file_operations rcudata_fops = {
40982 .owner = THIS_MODULE,
40983 .open = rcudata_open,
40984 .read = seq_read,
40985 @@ -136,7 +136,7 @@ static int rcudata_csv_open(struct inode
40986 return single_open(file, show_rcudata_csv, NULL);
40987 }
40988
40989 -static struct file_operations rcudata_csv_fops = {
40990 +static const struct file_operations rcudata_csv_fops = {
40991 .owner = THIS_MODULE,
40992 .open = rcudata_csv_open,
40993 .read = seq_read,
40994 @@ -183,7 +183,7 @@ static int rcuhier_open(struct inode *in
40995 return single_open(file, show_rcuhier, NULL);
40996 }
40997
40998 -static struct file_operations rcuhier_fops = {
40999 +static const struct file_operations rcuhier_fops = {
41000 .owner = THIS_MODULE,
41001 .open = rcuhier_open,
41002 .read = seq_read,
41003 @@ -205,7 +205,7 @@ static int rcugp_open(struct inode *inod
41004 return single_open(file, show_rcugp, NULL);
41005 }
41006
41007 -static struct file_operations rcugp_fops = {
41008 +static const struct file_operations rcugp_fops = {
41009 .owner = THIS_MODULE,
41010 .open = rcugp_open,
41011 .read = seq_read,
41012 @@ -255,7 +255,7 @@ static int rcu_pending_open(struct inode
41013 return single_open(file, show_rcu_pending, NULL);
41014 }
41015
41016 -static struct file_operations rcu_pending_fops = {
41017 +static const struct file_operations rcu_pending_fops = {
41018 .owner = THIS_MODULE,
41019 .open = rcu_pending_open,
41020 .read = seq_read,
41021 diff -urNp linux-2.6.31.1/kernel/relay.c linux-2.6.31.1/kernel/relay.c
41022 --- linux-2.6.31.1/kernel/relay.c 2009-09-24 11:45:25.000000000 -0400
41023 +++ linux-2.6.31.1/kernel/relay.c 2009-10-01 20:12:45.000000000 -0400
41024 @@ -60,7 +60,7 @@ static int relay_buf_fault(struct vm_are
41025 /*
41026 * vm_ops for relay file mappings.
41027 */
41028 -static struct vm_operations_struct relay_file_mmap_ops = {
41029 +static const struct vm_operations_struct relay_file_mmap_ops = {
41030 .fault = relay_buf_fault,
41031 .close = relay_file_mmap_close,
41032 };
41033 @@ -1292,7 +1292,7 @@ static int subbuf_splice_actor(struct fi
41034 return 0;
41035
41036 ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
41037 - if (ret < 0 || ret < total_len)
41038 + if ((int)ret < 0 || ret < total_len)
41039 return ret;
41040
41041 if (read_start + ret == nonpad_end)
41042 diff -urNp linux-2.6.31.1/kernel/resource.c linux-2.6.31.1/kernel/resource.c
41043 --- linux-2.6.31.1/kernel/resource.c 2009-09-24 11:45:25.000000000 -0400
41044 +++ linux-2.6.31.1/kernel/resource.c 2009-10-01 20:12:45.000000000 -0400
41045 @@ -132,8 +132,18 @@ static const struct file_operations proc
41046
41047 static int __init ioresources_init(void)
41048 {
41049 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
41050 +#ifdef CONFIG_GRKERNSEC_PROC_USER
41051 + proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
41052 + proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
41053 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
41054 + proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
41055 + proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
41056 +#endif
41057 +#else
41058 proc_create("ioports", 0, NULL, &proc_ioports_operations);
41059 proc_create("iomem", 0, NULL, &proc_iomem_operations);
41060 +#endif
41061 return 0;
41062 }
41063 __initcall(ioresources_init);
41064 diff -urNp linux-2.6.31.1/kernel/sched.c linux-2.6.31.1/kernel/sched.c
41065 --- linux-2.6.31.1/kernel/sched.c 2009-09-24 11:45:25.000000000 -0400
41066 +++ linux-2.6.31.1/kernel/sched.c 2009-10-01 20:12:45.000000000 -0400
41067 @@ -820,7 +820,7 @@ static int sched_feat_open(struct inode
41068 return single_open(filp, sched_feat_show, NULL);
41069 }
41070
41071 -static struct file_operations sched_feat_fops = {
41072 +static const struct file_operations sched_feat_fops = {
41073 .open = sched_feat_open,
41074 .write = sched_feat_write,
41075 .read = seq_read,
41076 @@ -5978,6 +5978,8 @@ int can_nice(const struct task_struct *p
41077 /* convert nice value [19,-20] to rlimit style value [1,40] */
41078 int nice_rlim = 20 - nice;
41079
41080 + gr_learn_resource(p, RLIMIT_NICE, nice_rlim, 1);
41081 +
41082 return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur ||
41083 capable(CAP_SYS_NICE));
41084 }
41085 @@ -6011,7 +6013,8 @@ SYSCALL_DEFINE1(nice, int, increment)
41086 if (nice > 19)
41087 nice = 19;
41088
41089 - if (increment < 0 && !can_nice(current, nice))
41090 + if (increment < 0 && (!can_nice(current, nice) ||
41091 + gr_handle_chroot_nice()))
41092 return -EPERM;
41093
41094 retval = security_task_setnice(current, nice);
41095 @@ -6153,6 +6156,8 @@ recheck:
41096 if (rt_policy(policy)) {
41097 unsigned long rlim_rtprio;
41098
41099 + gr_learn_resource(p, RLIMIT_RTPRIO, param->sched_priority, 1);
41100 +
41101 if (!lock_task_sighand(p, &flags))
41102 return -ESRCH;
41103 rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur;
41104 @@ -7300,7 +7305,7 @@ static struct ctl_table sd_ctl_dir[] = {
41105 .procname = "sched_domain",
41106 .mode = 0555,
41107 },
41108 - {0, },
41109 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
41110 };
41111
41112 static struct ctl_table sd_ctl_root[] = {
41113 @@ -7310,7 +7315,7 @@ static struct ctl_table sd_ctl_root[] =
41114 .mode = 0555,
41115 .child = sd_ctl_dir,
41116 },
41117 - {0, },
41118 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
41119 };
41120
41121 static struct ctl_table *sd_alloc_ctl_entry(int n)
41122 diff -urNp linux-2.6.31.1/kernel/signal.c linux-2.6.31.1/kernel/signal.c
41123 --- linux-2.6.31.1/kernel/signal.c 2009-09-24 11:45:25.000000000 -0400
41124 +++ linux-2.6.31.1/kernel/signal.c 2009-10-01 20:12:45.000000000 -0400
41125 @@ -207,6 +207,9 @@ static struct sigqueue *__sigqueue_alloc
41126 */
41127 user = get_uid(__task_cred(t)->user);
41128 atomic_inc(&user->sigpending);
41129 +
41130 + if (!override_rlimit)
41131 + gr_learn_resource(t, RLIMIT_SIGPENDING, atomic_read(&user->sigpending), 1);
41132 if (override_rlimit ||
41133 atomic_read(&user->sigpending) <=
41134 t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
41135 @@ -625,6 +628,9 @@ static int check_kill_permission(int sig
41136 }
41137 }
41138
41139 + if (gr_handle_signal(t, sig))
41140 + return -EPERM;
41141 +
41142 return security_task_kill(t, info, sig, 0);
41143 }
41144
41145 @@ -939,8 +945,8 @@ static void print_fatal_signal(struct pt
41146 for (i = 0; i < 16; i++) {
41147 unsigned char insn;
41148
41149 - __get_user(insn, (unsigned char *)(regs->ip + i));
41150 - printk("%02x ", insn);
41151 + if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
41152 + printk("%02x ", insn);
41153 }
41154 }
41155 #endif
41156 @@ -965,7 +971,7 @@ __group_send_sig_info(int sig, struct si
41157 return send_signal(sig, info, p, 1);
41158 }
41159
41160 -static int
41161 +int
41162 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
41163 {
41164 return send_signal(sig, info, t, 0);
41165 @@ -1005,6 +1011,9 @@ force_sig_info(int sig, struct siginfo *
41166 ret = specific_send_sig_info(sig, info, t);
41167 spin_unlock_irqrestore(&t->sighand->siglock, flags);
41168
41169 + gr_log_signal(sig, !is_si_special(info) ? info->si_addr : NULL, t);
41170 + gr_handle_crash(t, sig);
41171 +
41172 return ret;
41173 }
41174
41175 @@ -1079,6 +1088,8 @@ int group_send_sig_info(int sig, struct
41176 ret = __group_send_sig_info(sig, info, p);
41177 unlock_task_sighand(p, &flags);
41178 }
41179 + if (!ret)
41180 + gr_log_signal(sig, !is_si_special(info) ? info->si_addr : NULL, p);
41181 }
41182
41183 return ret;
41184 diff -urNp linux-2.6.31.1/kernel/sys.c linux-2.6.31.1/kernel/sys.c
41185 --- linux-2.6.31.1/kernel/sys.c 2009-09-24 11:45:25.000000000 -0400
41186 +++ linux-2.6.31.1/kernel/sys.c 2009-10-01 20:12:45.000000000 -0400
41187 @@ -133,6 +133,12 @@ static int set_one_prio(struct task_stru
41188 error = -EACCES;
41189 goto out;
41190 }
41191 +
41192 + if (gr_handle_chroot_setpriority(p, niceval)) {
41193 + error = -EACCES;
41194 + goto out;
41195 + }
41196 +
41197 no_nice = security_task_setnice(p, niceval);
41198 if (no_nice) {
41199 error = no_nice;
41200 @@ -509,6 +515,9 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, g
41201 goto error;
41202 }
41203
41204 + if (gr_check_group_change(new->gid, new->egid, -1))
41205 + goto error;
41206 +
41207 if (rgid != (gid_t) -1 ||
41208 (egid != (gid_t) -1 && egid != old->gid))
41209 new->sgid = new->egid;
41210 @@ -542,6 +551,10 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
41211 goto error;
41212
41213 retval = -EPERM;
41214 +
41215 + if (gr_check_group_change(gid, gid, gid))
41216 + goto error;
41217 +
41218 if (capable(CAP_SETGID))
41219 new->gid = new->egid = new->sgid = new->fsgid = gid;
41220 else if (gid == old->gid || gid == old->sgid)
41221 @@ -632,6 +645,9 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, u
41222 goto error;
41223 }
41224
41225 + if (gr_check_user_change(new->uid, new->euid, -1))
41226 + goto error;
41227 +
41228 if (new->uid != old->uid) {
41229 retval = set_user(new);
41230 if (retval < 0)
41231 @@ -680,6 +696,12 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
41232 goto error;
41233
41234 retval = -EPERM;
41235 +
41236 + if (gr_check_crash_uid(uid))
41237 + goto error;
41238 + if (gr_check_user_change(uid, uid, uid))
41239 + goto error;
41240 +
41241 if (capable(CAP_SETUID)) {
41242 new->suid = new->uid = uid;
41243 if (uid != old->uid) {
41244 @@ -737,6 +759,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid,
41245 goto error;
41246 }
41247
41248 + if (gr_check_user_change(ruid, euid, -1))
41249 + goto error;
41250 +
41251 if (ruid != (uid_t) -1) {
41252 new->uid = ruid;
41253 if (ruid != old->uid) {
41254 @@ -805,6 +830,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid,
41255 goto error;
41256 }
41257
41258 + if (gr_check_group_change(rgid, egid, -1))
41259 + goto error;
41260 +
41261 if (rgid != (gid_t) -1)
41262 new->gid = rgid;
41263 if (egid != (gid_t) -1)
41264 @@ -854,6 +882,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
41265 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS) < 0)
41266 goto error;
41267
41268 + if (gr_check_user_change(-1, -1, uid))
41269 + goto error;
41270 +
41271 if (uid == old->uid || uid == old->euid ||
41272 uid == old->suid || uid == old->fsuid ||
41273 capable(CAP_SETUID)) {
41274 @@ -894,6 +925,9 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
41275 if (gid == old->gid || gid == old->egid ||
41276 gid == old->sgid || gid == old->fsgid ||
41277 capable(CAP_SETGID)) {
41278 + if (gr_check_group_change(-1, -1, gid))
41279 + goto error;
41280 +
41281 if (gid != old_fsgid) {
41282 new->fsgid = gid;
41283 goto change_okay;
41284 @@ -1443,7 +1477,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
41285 error = get_dumpable(me->mm);
41286 break;
41287 case PR_SET_DUMPABLE:
41288 - if (arg2 < 0 || arg2 > 1) {
41289 + if (arg2 > 1) {
41290 error = -EINVAL;
41291 break;
41292 }
41293 diff -urNp linux-2.6.31.1/kernel/sysctl.c linux-2.6.31.1/kernel/sysctl.c
41294 --- linux-2.6.31.1/kernel/sysctl.c 2009-09-24 11:45:25.000000000 -0400
41295 +++ linux-2.6.31.1/kernel/sysctl.c 2009-10-01 20:12:45.000000000 -0400
41296 @@ -65,6 +65,13 @@
41297 static int deprecated_sysctl_warning(struct __sysctl_args *args);
41298
41299 #if defined(CONFIG_SYSCTL)
41300 +#include <linux/grsecurity.h>
41301 +#include <linux/grinternal.h>
41302 +
41303 +extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
41304 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
41305 + const int op);
41306 +extern int gr_handle_chroot_sysctl(const int op);
41307
41308 /* External variables not in a header file. */
41309 extern int C_A_D;
41310 @@ -163,6 +170,7 @@ static int proc_do_cad_pid(struct ctl_ta
41311 static int proc_taint(struct ctl_table *table, int write, struct file *filp,
41312 void __user *buffer, size_t *lenp, loff_t *ppos);
41313 #endif
41314 +extern ctl_table grsecurity_table[];
41315
41316 static struct ctl_table root_table[];
41317 static struct ctl_table_root sysctl_table_root;
41318 @@ -195,6 +203,21 @@ extern struct ctl_table epoll_table[];
41319 int sysctl_legacy_va_layout;
41320 #endif
41321
41322 +#ifdef CONFIG_PAX_SOFTMODE
41323 +static ctl_table pax_table[] = {
41324 + {
41325 + .ctl_name = CTL_UNNUMBERED,
41326 + .procname = "softmode",
41327 + .data = &pax_softmode,
41328 + .maxlen = sizeof(unsigned int),
41329 + .mode = 0600,
41330 + .proc_handler = &proc_dointvec,
41331 + },
41332 +
41333 + { .ctl_name = 0 }
41334 +};
41335 +#endif
41336 +
41337 extern int prove_locking;
41338 extern int lock_stat;
41339
41340 @@ -246,6 +269,24 @@ static int max_wakeup_granularity_ns = N
41341 #endif
41342
41343 static struct ctl_table kern_table[] = {
41344 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
41345 + {
41346 + .ctl_name = CTL_UNNUMBERED,
41347 + .procname = "grsecurity",
41348 + .mode = 0500,
41349 + .child = grsecurity_table,
41350 + },
41351 +#endif
41352 +
41353 +#ifdef CONFIG_PAX_SOFTMODE
41354 + {
41355 + .ctl_name = CTL_UNNUMBERED,
41356 + .procname = "pax",
41357 + .mode = 0500,
41358 + .child = pax_table,
41359 + },
41360 +#endif
41361 +
41362 #ifdef CONFIG_SCHED_DEBUG
41363 {
41364 .ctl_name = CTL_UNNUMBERED,
41365 @@ -1734,6 +1775,8 @@ static int do_sysctl_strategy(struct ctl
41366 return 0;
41367 }
41368
41369 +static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
41370 +
41371 static int parse_table(int __user *name, int nlen,
41372 void __user *oldval, size_t __user *oldlenp,
41373 void __user *newval, size_t newlen,
41374 @@ -1752,7 +1795,7 @@ repeat:
41375 if (n == table->ctl_name) {
41376 int error;
41377 if (table->child) {
41378 - if (sysctl_perm(root, table, MAY_EXEC))
41379 + if (sysctl_perm_nochk(root, table, MAY_EXEC))
41380 return -EPERM;
41381 name++;
41382 nlen--;
41383 @@ -1837,6 +1880,33 @@ int sysctl_perm(struct ctl_table_root *r
41384 int error;
41385 int mode;
41386
41387 + if (table->parent != NULL && table->parent->procname != NULL &&
41388 + table->procname != NULL &&
41389 + gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
41390 + return -EACCES;
41391 + if (gr_handle_chroot_sysctl(op))
41392 + return -EACCES;
41393 + error = gr_handle_sysctl(table, op);
41394 + if (error)
41395 + return error;
41396 +
41397 + error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
41398 + if (error)
41399 + return error;
41400 +
41401 + if (root->permissions)
41402 + mode = root->permissions(root, current->nsproxy, table);
41403 + else
41404 + mode = table->mode;
41405 +
41406 + return test_perm(mode, op);
41407 +}
41408 +
41409 +int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
41410 +{
41411 + int error;
41412 + int mode;
41413 +
41414 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
41415 if (error)
41416 return error;
41417 diff -urNp linux-2.6.31.1/kernel/taskstats.c linux-2.6.31.1/kernel/taskstats.c
41418 --- linux-2.6.31.1/kernel/taskstats.c 2009-09-24 11:45:25.000000000 -0400
41419 +++ linux-2.6.31.1/kernel/taskstats.c 2009-10-01 20:12:45.000000000 -0400
41420 @@ -26,9 +26,12 @@
41421 #include <linux/cgroup.h>
41422 #include <linux/fs.h>
41423 #include <linux/file.h>
41424 +#include <linux/grsecurity.h>
41425 #include <net/genetlink.h>
41426 #include <asm/atomic.h>
41427
41428 +extern int gr_is_taskstats_denied(int pid);
41429 +
41430 /*
41431 * Maximum length of a cpumask that can be specified in
41432 * the TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK attribute
41433 @@ -433,6 +436,9 @@ static int taskstats_user_cmd(struct sk_
41434 size_t size;
41435 cpumask_var_t mask;
41436
41437 + if (gr_is_taskstats_denied(current->pid))
41438 + return -EACCES;
41439 +
41440 if (!alloc_cpumask_var(&mask, GFP_KERNEL))
41441 return -ENOMEM;
41442
41443 diff -urNp linux-2.6.31.1/kernel/time/tick-broadcast.c linux-2.6.31.1/kernel/time/tick-broadcast.c
41444 --- linux-2.6.31.1/kernel/time/tick-broadcast.c 2009-09-24 11:45:25.000000000 -0400
41445 +++ linux-2.6.31.1/kernel/time/tick-broadcast.c 2009-10-01 20:12:45.000000000 -0400
41446 @@ -116,7 +116,7 @@ int tick_device_uses_broadcast(struct cl
41447 * then clear the broadcast bit.
41448 */
41449 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
41450 - int cpu = smp_processor_id();
41451 + cpu = smp_processor_id();
41452
41453 cpumask_clear_cpu(cpu, tick_get_broadcast_mask());
41454 tick_broadcast_clear_oneshot(cpu);
41455 diff -urNp linux-2.6.31.1/kernel/time/timer_list.c linux-2.6.31.1/kernel/time/timer_list.c
41456 --- linux-2.6.31.1/kernel/time/timer_list.c 2009-09-24 11:45:25.000000000 -0400
41457 +++ linux-2.6.31.1/kernel/time/timer_list.c 2009-10-01 20:12:45.000000000 -0400
41458 @@ -275,7 +275,7 @@ static int timer_list_open(struct inode
41459 return single_open(filp, timer_list_show, NULL);
41460 }
41461
41462 -static struct file_operations timer_list_fops = {
41463 +static const struct file_operations timer_list_fops = {
41464 .open = timer_list_open,
41465 .read = seq_read,
41466 .llseek = seq_lseek,
41467 diff -urNp linux-2.6.31.1/kernel/time/timer_stats.c linux-2.6.31.1/kernel/time/timer_stats.c
41468 --- linux-2.6.31.1/kernel/time/timer_stats.c 2009-09-24 11:45:25.000000000 -0400
41469 +++ linux-2.6.31.1/kernel/time/timer_stats.c 2009-10-01 20:12:45.000000000 -0400
41470 @@ -395,7 +395,7 @@ static int tstats_open(struct inode *ino
41471 return single_open(filp, tstats_show, NULL);
41472 }
41473
41474 -static struct file_operations tstats_fops = {
41475 +static const struct file_operations tstats_fops = {
41476 .open = tstats_open,
41477 .read = seq_read,
41478 .write = tstats_write,
41479 diff -urNp linux-2.6.31.1/kernel/time.c linux-2.6.31.1/kernel/time.c
41480 --- linux-2.6.31.1/kernel/time.c 2009-09-24 11:45:25.000000000 -0400
41481 +++ linux-2.6.31.1/kernel/time.c 2009-10-01 20:12:45.000000000 -0400
41482 @@ -94,6 +94,9 @@ SYSCALL_DEFINE1(stime, time_t __user *,
41483 return err;
41484
41485 do_settimeofday(&tv);
41486 +
41487 + gr_log_timechange();
41488 +
41489 return 0;
41490 }
41491
41492 @@ -202,6 +205,8 @@ SYSCALL_DEFINE2(settimeofday, struct tim
41493 return -EFAULT;
41494 }
41495
41496 + gr_log_timechange();
41497 +
41498 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
41499 }
41500
41501 @@ -240,7 +245,7 @@ EXPORT_SYMBOL(current_fs_time);
41502 * Avoid unnecessary multiplications/divisions in the
41503 * two most common HZ cases:
41504 */
41505 -unsigned int inline jiffies_to_msecs(const unsigned long j)
41506 +inline unsigned int jiffies_to_msecs(const unsigned long j)
41507 {
41508 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
41509 return (MSEC_PER_SEC / HZ) * j;
41510 @@ -256,7 +261,7 @@ unsigned int inline jiffies_to_msecs(con
41511 }
41512 EXPORT_SYMBOL(jiffies_to_msecs);
41513
41514 -unsigned int inline jiffies_to_usecs(const unsigned long j)
41515 +inline unsigned int jiffies_to_usecs(const unsigned long j)
41516 {
41517 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
41518 return (USEC_PER_SEC / HZ) * j;
41519 diff -urNp linux-2.6.31.1/kernel/trace/ftrace.c linux-2.6.31.1/kernel/trace/ftrace.c
41520 --- linux-2.6.31.1/kernel/trace/ftrace.c 2009-09-24 11:45:25.000000000 -0400
41521 +++ linux-2.6.31.1/kernel/trace/ftrace.c 2009-10-01 20:12:45.000000000 -0400
41522 @@ -1567,7 +1567,7 @@ static int t_show(struct seq_file *m, vo
41523 return 0;
41524 }
41525
41526 -static struct seq_operations show_ftrace_seq_ops = {
41527 +static const struct seq_operations show_ftrace_seq_ops = {
41528 .start = t_start,
41529 .next = t_next,
41530 .stop = t_stop,
41531 @@ -2565,7 +2565,7 @@ static int g_show(struct seq_file *m, vo
41532 return 0;
41533 }
41534
41535 -static struct seq_operations ftrace_graph_seq_ops = {
41536 +static const struct seq_operations ftrace_graph_seq_ops = {
41537 .start = g_start,
41538 .next = g_next,
41539 .stop = g_stop,
41540 diff -urNp linux-2.6.31.1/kernel/trace/Kconfig linux-2.6.31.1/kernel/trace/Kconfig
41541 --- linux-2.6.31.1/kernel/trace/Kconfig 2009-09-24 11:45:25.000000000 -0400
41542 +++ linux-2.6.31.1/kernel/trace/Kconfig 2009-10-01 20:12:45.000000000 -0400
41543 @@ -111,6 +111,7 @@ if FTRACE
41544 config FUNCTION_TRACER
41545 bool "Kernel Function Tracer"
41546 depends on HAVE_FUNCTION_TRACER
41547 + depends on !PAX_KERNEXEC
41548 select FRAME_POINTER
41549 select KALLSYMS
41550 select GENERIC_TRACER
41551 @@ -326,6 +327,7 @@ config POWER_TRACER
41552 config STACK_TRACER
41553 bool "Trace max stack"
41554 depends on HAVE_FUNCTION_TRACER
41555 + depends on !PAX_KERNEXEC
41556 select FUNCTION_TRACER
41557 select STACKTRACE
41558 select KALLSYMS
41559 diff -urNp linux-2.6.31.1/kernel/trace/trace.c linux-2.6.31.1/kernel/trace/trace.c
41560 --- linux-2.6.31.1/kernel/trace/trace.c 2009-09-24 11:45:25.000000000 -0400
41561 +++ linux-2.6.31.1/kernel/trace/trace.c 2009-10-01 20:12:45.000000000 -0400
41562 @@ -1885,7 +1885,7 @@ static int s_show(struct seq_file *m, vo
41563 return 0;
41564 }
41565
41566 -static struct seq_operations tracer_seq_ops = {
41567 +static const struct seq_operations tracer_seq_ops = {
41568 .start = s_start,
41569 .next = s_next,
41570 .stop = s_stop,
41571 @@ -2097,7 +2097,7 @@ static int t_show(struct seq_file *m, vo
41572 return 0;
41573 }
41574
41575 -static struct seq_operations show_traces_seq_ops = {
41576 +static const struct seq_operations show_traces_seq_ops = {
41577 .start = t_start,
41578 .next = t_next,
41579 .stop = t_stop,
41580 diff -urNp linux-2.6.31.1/kernel/trace/trace_output.c linux-2.6.31.1/kernel/trace/trace_output.c
41581 --- linux-2.6.31.1/kernel/trace/trace_output.c 2009-09-24 11:45:25.000000000 -0400
41582 +++ linux-2.6.31.1/kernel/trace/trace_output.c 2009-10-01 20:12:45.000000000 -0400
41583 @@ -234,7 +234,7 @@ int trace_seq_path(struct trace_seq *s,
41584 return 0;
41585 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
41586 if (!IS_ERR(p)) {
41587 - p = mangle_path(s->buffer + s->len, p, "\n");
41588 + p = mangle_path(s->buffer + s->len, p, "\n\\");
41589 if (p) {
41590 s->len = p - s->buffer;
41591 return 1;
41592 diff -urNp linux-2.6.31.1/kernel/utsname_sysctl.c linux-2.6.31.1/kernel/utsname_sysctl.c
41593 --- linux-2.6.31.1/kernel/utsname_sysctl.c 2009-09-24 11:45:25.000000000 -0400
41594 +++ linux-2.6.31.1/kernel/utsname_sysctl.c 2009-10-01 20:12:45.000000000 -0400
41595 @@ -123,7 +123,7 @@ static struct ctl_table uts_kern_table[]
41596 .proc_handler = proc_do_uts_string,
41597 .strategy = sysctl_uts_string,
41598 },
41599 - {}
41600 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
41601 };
41602
41603 static struct ctl_table uts_root_table[] = {
41604 @@ -133,7 +133,7 @@ static struct ctl_table uts_root_table[]
41605 .mode = 0555,
41606 .child = uts_kern_table,
41607 },
41608 - {}
41609 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
41610 };
41611
41612 static int __init utsname_sysctl_init(void)
41613 diff -urNp linux-2.6.31.1/lib/inflate.c linux-2.6.31.1/lib/inflate.c
41614 --- linux-2.6.31.1/lib/inflate.c 2009-09-24 11:45:25.000000000 -0400
41615 +++ linux-2.6.31.1/lib/inflate.c 2009-10-01 20:12:45.000000000 -0400
41616 @@ -266,7 +266,7 @@ static void free(void *where)
41617 malloc_ptr = free_mem_ptr;
41618 }
41619 #else
41620 -#define malloc(a) kmalloc(a, GFP_KERNEL)
41621 +#define malloc(a) kmalloc((a), GFP_KERNEL)
41622 #define free(a) kfree(a)
41623 #endif
41624
41625 diff -urNp linux-2.6.31.1/lib/Kconfig.debug linux-2.6.31.1/lib/Kconfig.debug
41626 --- linux-2.6.31.1/lib/Kconfig.debug 2009-09-24 11:45:25.000000000 -0400
41627 +++ linux-2.6.31.1/lib/Kconfig.debug 2009-10-01 20:12:45.000000000 -0400
41628 @@ -866,7 +866,7 @@ config LATENCYTOP
41629 select STACKTRACE
41630 select SCHEDSTATS
41631 select SCHED_DEBUG
41632 - depends on HAVE_LATENCYTOP_SUPPORT
41633 + depends on HAVE_LATENCYTOP_SUPPORT && !GRKERNSEC_HIDESYM
41634 help
41635 Enable this option if you want to use the LatencyTOP tool
41636 to find out which userspace is blocking on what kernel operations.
41637 diff -urNp linux-2.6.31.1/lib/parser.c linux-2.6.31.1/lib/parser.c
41638 --- linux-2.6.31.1/lib/parser.c 2009-09-24 11:45:25.000000000 -0400
41639 +++ linux-2.6.31.1/lib/parser.c 2009-10-01 20:12:45.000000000 -0400
41640 @@ -126,7 +126,7 @@ static int match_number(substring_t *s,
41641 char *buf;
41642 int ret;
41643
41644 - buf = kmalloc(s->to - s->from + 1, GFP_KERNEL);
41645 + buf = kmalloc((s->to - s->from) + 1, GFP_KERNEL);
41646 if (!buf)
41647 return -ENOMEM;
41648 memcpy(buf, s->from, s->to - s->from);
41649 diff -urNp linux-2.6.31.1/lib/radix-tree.c linux-2.6.31.1/lib/radix-tree.c
41650 --- linux-2.6.31.1/lib/radix-tree.c 2009-09-24 11:45:25.000000000 -0400
41651 +++ linux-2.6.31.1/lib/radix-tree.c 2009-10-01 20:12:45.000000000 -0400
41652 @@ -81,7 +81,7 @@ struct radix_tree_preload {
41653 int nr;
41654 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
41655 };
41656 -static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
41657 +static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
41658
41659 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
41660 {
41661 diff -urNp linux-2.6.31.1/lib/random32.c linux-2.6.31.1/lib/random32.c
41662 --- linux-2.6.31.1/lib/random32.c 2009-09-24 11:45:25.000000000 -0400
41663 +++ linux-2.6.31.1/lib/random32.c 2009-10-01 20:12:45.000000000 -0400
41664 @@ -61,7 +61,7 @@ static u32 __random32(struct rnd_state *
41665 */
41666 static inline u32 __seed(u32 x, u32 m)
41667 {
41668 - return (x < m) ? x + m : x;
41669 + return (x <= m) ? x + m + 1 : x;
41670 }
41671
41672 /**
41673 diff -urNp linux-2.6.31.1/localversion-grsec linux-2.6.31.1/localversion-grsec
41674 --- linux-2.6.31.1/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
41675 +++ linux-2.6.31.1/localversion-grsec 2009-10-01 20:12:45.000000000 -0400
41676 @@ -0,0 +1 @@
41677 +-grsec
41678 diff -urNp linux-2.6.31.1/Makefile linux-2.6.31.1/Makefile
41679 --- linux-2.6.31.1/Makefile 2009-09-24 11:45:25.000000000 -0400
41680 +++ linux-2.6.31.1/Makefile 2009-10-01 20:12:45.000000000 -0400
41681 @@ -221,8 +221,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
41682
41683 HOSTCC = gcc
41684 HOSTCXX = g++
41685 -HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
41686 -HOSTCXXFLAGS = -O2
41687 +HOSTCFLAGS = -Wall -W -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-delete-null-pointer-checks
41688 +HOSTCXXFLAGS = -O2 -fno-delete-null-pointer-checks
41689
41690 # Decide whether to build built-in, modular, or both.
41691 # Normally, just do built-in.
41692 @@ -639,7 +639,7 @@ export mod_strip_cmd
41693
41694
41695 ifeq ($(KBUILD_EXTMOD),)
41696 -core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
41697 +core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
41698
41699 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
41700 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
41701 diff -urNp linux-2.6.31.1/mm/filemap.c linux-2.6.31.1/mm/filemap.c
41702 --- linux-2.6.31.1/mm/filemap.c 2009-09-24 11:45:25.000000000 -0400
41703 +++ linux-2.6.31.1/mm/filemap.c 2009-10-01 20:12:45.000000000 -0400
41704 @@ -1648,7 +1648,7 @@ page_not_uptodate:
41705 }
41706 EXPORT_SYMBOL(filemap_fault);
41707
41708 -struct vm_operations_struct generic_file_vm_ops = {
41709 +const struct vm_operations_struct generic_file_vm_ops = {
41710 .fault = filemap_fault,
41711 };
41712
41713 @@ -1659,7 +1659,7 @@ int generic_file_mmap(struct file * file
41714 struct address_space *mapping = file->f_mapping;
41715
41716 if (!mapping->a_ops->readpage)
41717 - return -ENOEXEC;
41718 + return -ENODEV;
41719 file_accessed(file);
41720 vma->vm_ops = &generic_file_vm_ops;
41721 vma->vm_flags |= VM_CAN_NONLINEAR;
41722 @@ -2019,6 +2019,7 @@ inline int generic_write_checks(struct f
41723 *pos = i_size_read(inode);
41724
41725 if (limit != RLIM_INFINITY) {
41726 + gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
41727 if (*pos >= limit) {
41728 send_sig(SIGXFSZ, current, 0);
41729 return -EFBIG;
41730 diff -urNp linux-2.6.31.1/mm/filemap_xip.c linux-2.6.31.1/mm/filemap_xip.c
41731 --- linux-2.6.31.1/mm/filemap_xip.c 2009-09-24 11:45:25.000000000 -0400
41732 +++ linux-2.6.31.1/mm/filemap_xip.c 2009-10-01 20:12:45.000000000 -0400
41733 @@ -296,7 +296,7 @@ out:
41734 }
41735 }
41736
41737 -static struct vm_operations_struct xip_file_vm_ops = {
41738 +static const struct vm_operations_struct xip_file_vm_ops = {
41739 .fault = xip_file_fault,
41740 };
41741
41742 diff -urNp linux-2.6.31.1/mm/fremap.c linux-2.6.31.1/mm/fremap.c
41743 --- linux-2.6.31.1/mm/fremap.c 2009-09-24 11:45:25.000000000 -0400
41744 +++ linux-2.6.31.1/mm/fremap.c 2009-10-01 20:12:45.000000000 -0400
41745 @@ -153,6 +153,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
41746 retry:
41747 vma = find_vma(mm, start);
41748
41749 +#ifdef CONFIG_PAX_SEGMEXEC
41750 + if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC))
41751 + goto out;
41752 +#endif
41753 +
41754 /*
41755 * Make sure the vma is shared, that it supports prefaulting,
41756 * and that the remapped range is valid and fully within
41757 diff -urNp linux-2.6.31.1/mm/highmem.c linux-2.6.31.1/mm/highmem.c
41758 --- linux-2.6.31.1/mm/highmem.c 2009-09-24 11:45:25.000000000 -0400
41759 +++ linux-2.6.31.1/mm/highmem.c 2009-10-01 20:12:45.000000000 -0400
41760 @@ -94,6 +94,9 @@ static void flush_all_zero_pkmaps(void)
41761
41762 for (i = 0; i < LAST_PKMAP; i++) {
41763 struct page *page;
41764 +#ifdef CONFIG_PAX_KERNEXEC
41765 + unsigned long cr0;
41766 +#endif
41767
41768 /*
41769 * zero means we don't have anything to do,
41770 @@ -116,9 +119,18 @@ static void flush_all_zero_pkmaps(void)
41771 * So no dangers, even with speculative execution.
41772 */
41773 page = pte_page(pkmap_page_table[i]);
41774 +
41775 +#ifdef CONFIG_PAX_KERNEXEC
41776 + pax_open_kernel(cr0);
41777 +#endif
41778 +
41779 pte_clear(&init_mm, (unsigned long)page_address(page),
41780 &pkmap_page_table[i]);
41781
41782 +#ifdef CONFIG_PAX_KERNEXEC
41783 + pax_close_kernel(cr0);
41784 +#endif
41785 +
41786 set_page_address(page, NULL);
41787 need_flush = 1;
41788 }
41789 @@ -140,6 +152,9 @@ static inline unsigned long map_new_virt
41790 {
41791 unsigned long vaddr;
41792 int count;
41793 +#ifdef CONFIG_PAX_KERNEXEC
41794 + unsigned long cr0;
41795 +#endif
41796
41797 start:
41798 count = LAST_PKMAP;
41799 @@ -177,8 +192,14 @@ start:
41800 }
41801 }
41802 vaddr = PKMAP_ADDR(last_pkmap_nr);
41803 +#ifdef CONFIG_PAX_KERNEXEC
41804 + pax_open_kernel(cr0);
41805 +#endif
41806 set_pte_at(&init_mm, vaddr,
41807 &(pkmap_page_table[last_pkmap_nr]), mk_pte(page, kmap_prot));
41808 +#ifdef CONFIG_PAX_KERNEXEC
41809 + pax_close_kernel(cr0);
41810 +#endif
41811
41812 pkmap_count[last_pkmap_nr] = 1;
41813 set_page_address(page, (void *)vaddr);
41814 diff -urNp linux-2.6.31.1/mm/hugetlb.c linux-2.6.31.1/mm/hugetlb.c
41815 --- linux-2.6.31.1/mm/hugetlb.c 2009-09-24 11:45:25.000000000 -0400
41816 +++ linux-2.6.31.1/mm/hugetlb.c 2009-10-01 20:12:45.000000000 -0400
41817 @@ -1689,7 +1689,7 @@ static int hugetlb_vm_op_fault(struct vm
41818 return 0;
41819 }
41820
41821 -struct vm_operations_struct hugetlb_vm_ops = {
41822 +const struct vm_operations_struct hugetlb_vm_ops = {
41823 .fault = hugetlb_vm_op_fault,
41824 .open = hugetlb_vm_op_open,
41825 .close = hugetlb_vm_op_close,
41826 @@ -1892,6 +1892,26 @@ static int unmap_ref_private(struct mm_s
41827 return 1;
41828 }
41829
41830 +#ifdef CONFIG_PAX_SEGMEXEC
41831 +static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
41832 +{
41833 + struct mm_struct *mm = vma->vm_mm;
41834 + struct vm_area_struct *vma_m;
41835 + unsigned long address_m;
41836 + pte_t *ptep_m;
41837 +
41838 + vma_m = pax_find_mirror_vma(vma);
41839 + if (!vma_m)
41840 + return;
41841 +
41842 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
41843 + address_m = address + SEGMEXEC_TASK_SIZE;
41844 + ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
41845 + get_page(page_m);
41846 + set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
41847 +}
41848 +#endif
41849 +
41850 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
41851 unsigned long address, pte_t *ptep, pte_t pte,
41852 struct page *pagecache_page)
41853 @@ -1963,6 +1983,11 @@ retry_avoidcopy:
41854 huge_ptep_clear_flush(vma, address, ptep);
41855 set_huge_pte_at(mm, address, ptep,
41856 make_huge_pte(vma, new_page, 1));
41857 +
41858 +#ifdef CONFIG_PAX_SEGMEXEC
41859 + pax_mirror_huge_pte(vma, address, new_page);
41860 +#endif
41861 +
41862 /* Make the old page be freed below */
41863 new_page = old_page;
41864 }
41865 @@ -2072,6 +2097,10 @@ retry:
41866 && (vma->vm_flags & VM_SHARED)));
41867 set_huge_pte_at(mm, address, ptep, new_pte);
41868
41869 +#ifdef CONFIG_PAX_SEGMEXEC
41870 + pax_mirror_huge_pte(vma, address, page);
41871 +#endif
41872 +
41873 if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
41874 /* Optimization, do the COW without a second fault */
41875 ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
41876 @@ -2100,6 +2129,28 @@ int hugetlb_fault(struct mm_struct *mm,
41877 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
41878 struct hstate *h = hstate_vma(vma);
41879
41880 +#ifdef CONFIG_PAX_SEGMEXEC
41881 + struct vm_area_struct *vma_m;
41882 +
41883 + vma_m = pax_find_mirror_vma(vma);
41884 + if (vma_m) {
41885 + unsigned long address_m;
41886 +
41887 + if (vma->vm_start > vma_m->vm_start) {
41888 + address_m = address;
41889 + address -= SEGMEXEC_TASK_SIZE;
41890 + vma = vma_m;
41891 + h = hstate_vma(vma);
41892 + } else
41893 + address_m = address + SEGMEXEC_TASK_SIZE;
41894 +
41895 + if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
41896 + return VM_FAULT_OOM;
41897 + address_m &= HPAGE_MASK;
41898 + unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
41899 + }
41900 +#endif
41901 +
41902 ptep = huge_pte_alloc(mm, address, huge_page_size(h));
41903 if (!ptep)
41904 return VM_FAULT_OOM;
41905 diff -urNp linux-2.6.31.1/mm/Kconfig linux-2.6.31.1/mm/Kconfig
41906 --- linux-2.6.31.1/mm/Kconfig 2009-09-24 11:45:25.000000000 -0400
41907 +++ linux-2.6.31.1/mm/Kconfig 2009-10-01 20:12:45.000000000 -0400
41908 @@ -216,7 +216,7 @@ config MMU_NOTIFIER
41909
41910 config DEFAULT_MMAP_MIN_ADDR
41911 int "Low address space to protect from user allocation"
41912 - default 4096
41913 + default 65536
41914 help
41915 This is the portion of low virtual memory which should be protected
41916 from userspace allocation. Keeping a user from writing to low pages
41917 diff -urNp linux-2.6.31.1/mm/madvise.c linux-2.6.31.1/mm/madvise.c
41918 --- linux-2.6.31.1/mm/madvise.c 2009-09-24 11:45:25.000000000 -0400
41919 +++ linux-2.6.31.1/mm/madvise.c 2009-10-01 20:12:45.000000000 -0400
41920 @@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
41921 pgoff_t pgoff;
41922 int new_flags = vma->vm_flags;
41923
41924 +#ifdef CONFIG_PAX_SEGMEXEC
41925 + struct vm_area_struct *vma_m;
41926 +#endif
41927 +
41928 switch (behavior) {
41929 case MADV_NORMAL:
41930 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
41931 @@ -92,6 +96,13 @@ success:
41932 /*
41933 * vm_flags is protected by the mmap_sem held in write mode.
41934 */
41935 +
41936 +#ifdef CONFIG_PAX_SEGMEXEC
41937 + vma_m = pax_find_mirror_vma(vma);
41938 + if (vma_m)
41939 + vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
41940 +#endif
41941 +
41942 vma->vm_flags = new_flags;
41943
41944 out:
41945 @@ -235,6 +246,17 @@ madvise_vma(struct vm_area_struct *vma,
41946
41947 case MADV_DONTNEED:
41948 error = madvise_dontneed(vma, prev, start, end);
41949 +
41950 +#ifdef CONFIG_PAX_SEGMEXEC
41951 + if (!error) {
41952 + struct vm_area_struct *vma_m, *prev_m;
41953 +
41954 + vma_m = pax_find_mirror_vma(vma);
41955 + if (vma_m)
41956 + error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
41957 + }
41958 +#endif
41959 +
41960 break;
41961
41962 default:
41963 @@ -328,6 +350,16 @@ SYSCALL_DEFINE3(madvise, unsigned long,
41964 if (end < start)
41965 goto out;
41966
41967 +#ifdef CONFIG_PAX_SEGMEXEC
41968 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
41969 + if (end > SEGMEXEC_TASK_SIZE)
41970 + goto out;
41971 + } else
41972 +#endif
41973 +
41974 + if (end > TASK_SIZE)
41975 + goto out;
41976 +
41977 error = 0;
41978 if (end == start)
41979 goto out;
41980 diff -urNp linux-2.6.31.1/mm/memory.c linux-2.6.31.1/mm/memory.c
41981 --- linux-2.6.31.1/mm/memory.c 2009-09-24 11:45:25.000000000 -0400
41982 +++ linux-2.6.31.1/mm/memory.c 2009-10-01 20:12:45.000000000 -0400
41983 @@ -47,6 +47,7 @@
41984 #include <linux/pagemap.h>
41985 #include <linux/rmap.h>
41986 #include <linux/module.h>
41987 +#include <linux/security.h>
41988 #include <linux/delayacct.h>
41989 #include <linux/init.h>
41990 #include <linux/writeback.h>
41991 @@ -1228,11 +1229,11 @@ int __get_user_pages(struct task_struct
41992 vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
41993 i = 0;
41994
41995 - do {
41996 + while (nr_pages) {
41997 struct vm_area_struct *vma;
41998 unsigned int foll_flags;
41999
42000 - vma = find_extend_vma(mm, start);
42001 + vma = find_vma(mm, start);
42002 if (!vma && in_gate_area(tsk, start)) {
42003 unsigned long pg = start & PAGE_MASK;
42004 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
42005 @@ -1274,7 +1275,7 @@ int __get_user_pages(struct task_struct
42006 continue;
42007 }
42008
42009 - if (!vma ||
42010 + if (!vma || start < vma->vm_start ||
42011 (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
42012 (!ignore && !(vm_flags & vma->vm_flags)))
42013 return i ? : -EFAULT;
42014 @@ -1360,7 +1361,7 @@ int __get_user_pages(struct task_struct
42015 start += PAGE_SIZE;
42016 nr_pages--;
42017 } while (nr_pages && start < vma->vm_end);
42018 - } while (nr_pages);
42019 + }
42020 return i;
42021 }
42022
42023 @@ -1926,6 +1927,186 @@ static inline void cow_user_page(struct
42024 copy_user_highpage(dst, src, va, vma);
42025 }
42026
42027 +#ifdef CONFIG_PAX_SEGMEXEC
42028 +static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
42029 +{
42030 + struct mm_struct *mm = vma->vm_mm;
42031 + spinlock_t *ptl;
42032 + pte_t *pte, entry;
42033 +
42034 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
42035 + entry = *pte;
42036 + if (!pte_present(entry)) {
42037 + if (!pte_none(entry)) {
42038 + BUG_ON(pte_file(entry));
42039 + free_swap_and_cache(pte_to_swp_entry(entry));
42040 + pte_clear_not_present_full(mm, address, pte, 0);
42041 + }
42042 + } else {
42043 + struct page *page;
42044 +
42045 + flush_cache_page(vma, address, pte_pfn(entry));
42046 + entry = ptep_clear_flush(vma, address, pte);
42047 + BUG_ON(pte_dirty(entry));
42048 + page = vm_normal_page(vma, address, entry);
42049 + if (page) {
42050 + update_hiwater_rss(mm);
42051 + if (PageAnon(page))
42052 + dec_mm_counter(mm, anon_rss);
42053 + else
42054 + dec_mm_counter(mm, file_rss);
42055 + page_remove_rmap(page);
42056 + page_cache_release(page);
42057 + }
42058 + }
42059 + pte_unmap_unlock(pte, ptl);
42060 +}
42061 +
42062 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
42063 + *
42064 + * the ptl of the lower mapped page is held on entry and is not released on exit
42065 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
42066 + */
42067 +static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
42068 +{
42069 + struct mm_struct *mm = vma->vm_mm;
42070 + unsigned long address_m;
42071 + spinlock_t *ptl_m;
42072 + struct vm_area_struct *vma_m;
42073 + pmd_t *pmd_m;
42074 + pte_t *pte_m, entry_m;
42075 +
42076 + BUG_ON(!page_m || !PageAnon(page_m));
42077 +
42078 + vma_m = pax_find_mirror_vma(vma);
42079 + if (!vma_m)
42080 + return;
42081 +
42082 + BUG_ON(!PageLocked(page_m));
42083 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
42084 + address_m = address + SEGMEXEC_TASK_SIZE;
42085 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
42086 + pte_m = pte_offset_map_nested(pmd_m, address_m);
42087 + ptl_m = pte_lockptr(mm, pmd_m);
42088 + if (ptl != ptl_m) {
42089 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
42090 + if (!pte_none(*pte_m))
42091 + goto out;
42092 + }
42093 +
42094 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
42095 + page_cache_get(page_m);
42096 + page_add_anon_rmap(page_m, vma_m, address_m);
42097 + inc_mm_counter(mm, anon_rss);
42098 + set_pte_at(mm, address_m, pte_m, entry_m);
42099 + update_mmu_cache(vma_m, address_m, entry_m);
42100 +out:
42101 + if (ptl != ptl_m)
42102 + spin_unlock(ptl_m);
42103 + pte_unmap_nested(pte_m);
42104 + unlock_page(page_m);
42105 +}
42106 +
42107 +void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
42108 +{
42109 + struct mm_struct *mm = vma->vm_mm;
42110 + unsigned long address_m;
42111 + spinlock_t *ptl_m;
42112 + struct vm_area_struct *vma_m;
42113 + pmd_t *pmd_m;
42114 + pte_t *pte_m, entry_m;
42115 +
42116 + BUG_ON(!page_m || PageAnon(page_m));
42117 +
42118 + vma_m = pax_find_mirror_vma(vma);
42119 + if (!vma_m)
42120 + return;
42121 +
42122 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
42123 + address_m = address + SEGMEXEC_TASK_SIZE;
42124 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
42125 + pte_m = pte_offset_map_nested(pmd_m, address_m);
42126 + ptl_m = pte_lockptr(mm, pmd_m);
42127 + if (ptl != ptl_m) {
42128 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
42129 + if (!pte_none(*pte_m))
42130 + goto out;
42131 + }
42132 +
42133 + entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
42134 + page_cache_get(page_m);
42135 + page_add_file_rmap(page_m);
42136 + inc_mm_counter(mm, file_rss);
42137 + set_pte_at(mm, address_m, pte_m, entry_m);
42138 + update_mmu_cache(vma_m, address_m, entry_m);
42139 +out:
42140 + if (ptl != ptl_m)
42141 + spin_unlock(ptl_m);
42142 + pte_unmap_nested(pte_m);
42143 +}
42144 +
42145 +static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
42146 +{
42147 + struct mm_struct *mm = vma->vm_mm;
42148 + unsigned long address_m;
42149 + spinlock_t *ptl_m;
42150 + struct vm_area_struct *vma_m;
42151 + pmd_t *pmd_m;
42152 + pte_t *pte_m, entry_m;
42153 +
42154 + vma_m = pax_find_mirror_vma(vma);
42155 + if (!vma_m)
42156 + return;
42157 +
42158 + BUG_ON(address >= SEGMEXEC_TASK_SIZE);
42159 + address_m = address + SEGMEXEC_TASK_SIZE;
42160 + pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
42161 + pte_m = pte_offset_map_nested(pmd_m, address_m);
42162 + ptl_m = pte_lockptr(mm, pmd_m);
42163 + if (ptl != ptl_m) {
42164 + spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
42165 + if (!pte_none(*pte_m))
42166 + goto out;
42167 + }
42168 +
42169 + entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
42170 + set_pte_at(mm, address_m, pte_m, entry_m);
42171 +out:
42172 + if (ptl != ptl_m)
42173 + spin_unlock(ptl_m);
42174 + pte_unmap_nested(pte_m);
42175 +}
42176 +
42177 +static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
42178 +{
42179 + struct page *page_m;
42180 + pte_t entry;
42181 +
42182 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
42183 + goto out;
42184 +
42185 + entry = *pte;
42186 + page_m = vm_normal_page(vma, address, entry);
42187 + if (!page_m)
42188 + pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
42189 + else if (PageAnon(page_m)) {
42190 + if (pax_find_mirror_vma(vma)) {
42191 + pte_unmap_unlock(pte, ptl);
42192 + lock_page(page_m);
42193 + pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
42194 + if (pte_same(entry, *pte))
42195 + pax_mirror_anon_pte(vma, address, page_m, ptl);
42196 + else
42197 + unlock_page(page_m);
42198 + }
42199 + } else
42200 + pax_mirror_file_pte(vma, address, page_m, ptl);
42201 +
42202 +out:
42203 + pte_unmap_unlock(pte, ptl);
42204 +}
42205 +#endif
42206 +
42207 /*
42208 * This routine handles present pages, when users try to write
42209 * to a shared page. It is done by copying the page to a new address
42210 @@ -2098,6 +2279,12 @@ gotten:
42211 */
42212 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
42213 if (likely(pte_same(*page_table, orig_pte))) {
42214 +
42215 +#ifdef CONFIG_PAX_SEGMEXEC
42216 + if (pax_find_mirror_vma(vma))
42217 + BUG_ON(!trylock_page(new_page));
42218 +#endif
42219 +
42220 if (old_page) {
42221 if (!PageAnon(old_page)) {
42222 dec_mm_counter(mm, file_rss);
42223 @@ -2144,6 +2331,10 @@ gotten:
42224 page_remove_rmap(old_page);
42225 }
42226
42227 +#ifdef CONFIG_PAX_SEGMEXEC
42228 + pax_mirror_anon_pte(vma, address, new_page, ptl);
42229 +#endif
42230 +
42231 /* Free the old page.. */
42232 new_page = old_page;
42233 ret |= VM_FAULT_WRITE;
42234 @@ -2425,6 +2616,7 @@ int vmtruncate(struct inode * inode, lof
42235 unsigned long limit;
42236
42237 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
42238 + gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
42239 if (limit != RLIM_INFINITY && offset > limit)
42240 goto out_sig;
42241 if (offset > inode->i_sb->s_maxbytes)
42242 @@ -2587,6 +2779,11 @@ static int do_swap_page(struct mm_struct
42243 swap_free(entry);
42244 if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
42245 try_to_free_swap(page);
42246 +
42247 +#ifdef CONFIG_PAX_SEGMEXEC
42248 + if ((flags & FAULT_FLAG_WRITE) || !pax_find_mirror_vma(vma))
42249 +#endif
42250 +
42251 unlock_page(page);
42252
42253 if (flags & FAULT_FLAG_WRITE) {
42254 @@ -2598,6 +2795,11 @@ static int do_swap_page(struct mm_struct
42255
42256 /* No need to invalidate - it was non-present before */
42257 update_mmu_cache(vma, address, pte);
42258 +
42259 +#ifdef CONFIG_PAX_SEGMEXEC
42260 + pax_mirror_anon_pte(vma, address, page, ptl);
42261 +#endif
42262 +
42263 unlock:
42264 pte_unmap_unlock(page_table, ptl);
42265 out:
42266 @@ -2643,12 +2845,23 @@ static int do_anonymous_page(struct mm_s
42267 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
42268 if (!pte_none(*page_table))
42269 goto release;
42270 +
42271 +#ifdef CONFIG_PAX_SEGMEXEC
42272 + if (pax_find_mirror_vma(vma))
42273 + BUG_ON(!trylock_page(page));
42274 +#endif
42275 +
42276 inc_mm_counter(mm, anon_rss);
42277 page_add_new_anon_rmap(page, vma, address);
42278 set_pte_at(mm, address, page_table, entry);
42279
42280 /* No need to invalidate - it was non-present before */
42281 update_mmu_cache(vma, address, entry);
42282 +
42283 +#ifdef CONFIG_PAX_SEGMEXEC
42284 + pax_mirror_anon_pte(vma, address, page, ptl);
42285 +#endif
42286 +
42287 unlock:
42288 pte_unmap_unlock(page_table, ptl);
42289 return 0;
42290 @@ -2785,6 +2998,12 @@ static int __do_fault(struct mm_struct *
42291 */
42292 /* Only go through if we didn't race with anybody else... */
42293 if (likely(pte_same(*page_table, orig_pte))) {
42294 +
42295 +#ifdef CONFIG_PAX_SEGMEXEC
42296 + if (anon && pax_find_mirror_vma(vma))
42297 + BUG_ON(!trylock_page(page));
42298 +#endif
42299 +
42300 flush_icache_page(vma, page);
42301 entry = mk_pte(page, vma->vm_page_prot);
42302 if (flags & FAULT_FLAG_WRITE)
42303 @@ -2804,6 +3023,14 @@ static int __do_fault(struct mm_struct *
42304
42305 /* no need to invalidate: a not-present page won't be cached */
42306 update_mmu_cache(vma, address, entry);
42307 +
42308 +#ifdef CONFIG_PAX_SEGMEXEC
42309 + if (anon)
42310 + pax_mirror_anon_pte(vma, address, page, ptl);
42311 + else
42312 + pax_mirror_file_pte(vma, address, page, ptl);
42313 +#endif
42314 +
42315 } else {
42316 if (charged)
42317 mem_cgroup_uncharge_page(page);
42318 @@ -2951,6 +3178,12 @@ static inline int handle_pte_fault(struc
42319 if (flags & FAULT_FLAG_WRITE)
42320 flush_tlb_page(vma, address);
42321 }
42322 +
42323 +#ifdef CONFIG_PAX_SEGMEXEC
42324 + pax_mirror_pte(vma, address, pte, pmd, ptl);
42325 + return 0;
42326 +#endif
42327 +
42328 unlock:
42329 pte_unmap_unlock(pte, ptl);
42330 return 0;
42331 @@ -2967,6 +3200,10 @@ int handle_mm_fault(struct mm_struct *mm
42332 pmd_t *pmd;
42333 pte_t *pte;
42334
42335 +#ifdef CONFIG_PAX_SEGMEXEC
42336 + struct vm_area_struct *vma_m;
42337 +#endif
42338 +
42339 __set_current_state(TASK_RUNNING);
42340
42341 count_vm_event(PGFAULT);
42342 @@ -2974,6 +3211,34 @@ int handle_mm_fault(struct mm_struct *mm
42343 if (unlikely(is_vm_hugetlb_page(vma)))
42344 return hugetlb_fault(mm, vma, address, flags);
42345
42346 +#ifdef CONFIG_PAX_SEGMEXEC
42347 + vma_m = pax_find_mirror_vma(vma);
42348 + if (vma_m) {
42349 + unsigned long address_m;
42350 + pgd_t *pgd_m;
42351 + pud_t *pud_m;
42352 + pmd_t *pmd_m;
42353 +
42354 + if (vma->vm_start > vma_m->vm_start) {
42355 + address_m = address;
42356 + address -= SEGMEXEC_TASK_SIZE;
42357 + vma = vma_m;
42358 + } else
42359 + address_m = address + SEGMEXEC_TASK_SIZE;
42360 +
42361 + pgd_m = pgd_offset(mm, address_m);
42362 + pud_m = pud_alloc(mm, pgd_m, address_m);
42363 + if (!pud_m)
42364 + return VM_FAULT_OOM;
42365 + pmd_m = pmd_alloc(mm, pud_m, address_m);
42366 + if (!pmd_m)
42367 + return VM_FAULT_OOM;
42368 + if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
42369 + return VM_FAULT_OOM;
42370 + pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
42371 + }
42372 +#endif
42373 +
42374 pgd = pgd_offset(mm, address);
42375 pud = pud_alloc(mm, pgd, address);
42376 if (!pud)
42377 @@ -3071,7 +3336,7 @@ static int __init gate_vma_init(void)
42378 gate_vma.vm_start = FIXADDR_USER_START;
42379 gate_vma.vm_end = FIXADDR_USER_END;
42380 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
42381 - gate_vma.vm_page_prot = __P101;
42382 + gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
42383 /*
42384 * Make sure the vDSO gets into every core dump.
42385 * Dumping its contents makes post-mortem fully interpretable later
42386 diff -urNp linux-2.6.31.1/mm/mempolicy.c linux-2.6.31.1/mm/mempolicy.c
42387 --- linux-2.6.31.1/mm/mempolicy.c 2009-09-24 11:45:25.000000000 -0400
42388 +++ linux-2.6.31.1/mm/mempolicy.c 2009-10-01 20:12:45.000000000 -0400
42389 @@ -573,6 +573,10 @@ static int mbind_range(struct vm_area_st
42390 struct vm_area_struct *next;
42391 int err;
42392
42393 +#ifdef CONFIG_PAX_SEGMEXEC
42394 + struct vm_area_struct *vma_m;
42395 +#endif
42396 +
42397 err = 0;
42398 for (; vma && vma->vm_start < end; vma = next) {
42399 next = vma->vm_next;
42400 @@ -584,6 +588,16 @@ static int mbind_range(struct vm_area_st
42401 err = policy_vma(vma, new);
42402 if (err)
42403 break;
42404 +
42405 +#ifdef CONFIG_PAX_SEGMEXEC
42406 + vma_m = pax_find_mirror_vma(vma);
42407 + if (vma_m) {
42408 + err = policy_vma(vma_m, new);
42409 + if (err)
42410 + break;
42411 + }
42412 +#endif
42413 +
42414 }
42415 return err;
42416 }
42417 @@ -1002,6 +1016,17 @@ static long do_mbind(unsigned long start
42418
42419 if (end < start)
42420 return -EINVAL;
42421 +
42422 +#ifdef CONFIG_PAX_SEGMEXEC
42423 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
42424 + if (end > SEGMEXEC_TASK_SIZE)
42425 + return -EINVAL;
42426 + } else
42427 +#endif
42428 +
42429 + if (end > TASK_SIZE)
42430 + return -EINVAL;
42431 +
42432 if (end == start)
42433 return 0;
42434
42435 @@ -1206,6 +1231,14 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pi
42436 if (!mm)
42437 return -EINVAL;
42438
42439 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
42440 + if (mm != current->mm &&
42441 + (mm->pax_flags & MF_PAX_RANDMMAP || mm->pax_flags & MF_PAX_SEGMEXEC)) {
42442 + err = -EPERM;
42443 + goto out;
42444 + }
42445 +#endif
42446 +
42447 /*
42448 * Check if this process has the right to modify the specified
42449 * process. The right exists if the process has administrative
42450 @@ -1215,8 +1248,7 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pi
42451 rcu_read_lock();
42452 tcred = __task_cred(task);
42453 if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
42454 - cred->uid != tcred->suid && cred->uid != tcred->uid &&
42455 - !capable(CAP_SYS_NICE)) {
42456 + cred->uid != tcred->suid && !capable(CAP_SYS_NICE)) {
42457 rcu_read_unlock();
42458 err = -EPERM;
42459 goto out;
42460 @@ -2385,7 +2417,7 @@ int show_numa_map(struct seq_file *m, vo
42461
42462 if (file) {
42463 seq_printf(m, " file=");
42464 - seq_path(m, &file->f_path, "\n\t= ");
42465 + seq_path(m, &file->f_path, "\n\t\\= ");
42466 } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
42467 seq_printf(m, " heap");
42468 } else if (vma->vm_start <= mm->start_stack &&
42469 diff -urNp linux-2.6.31.1/mm/migrate.c linux-2.6.31.1/mm/migrate.c
42470 --- linux-2.6.31.1/mm/migrate.c 2009-09-24 11:45:25.000000000 -0400
42471 +++ linux-2.6.31.1/mm/migrate.c 2009-10-01 20:12:45.000000000 -0400
42472 @@ -1087,6 +1087,14 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid,
42473 if (!mm)
42474 return -EINVAL;
42475
42476 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
42477 + if (mm != current->mm &&
42478 + (mm->pax_flags & MF_PAX_RANDMMAP || mm->pax_flags & MF_PAX_SEGMEXEC)) {
42479 + err = -EPERM;
42480 + goto out;
42481 + }
42482 +#endif
42483 +
42484 /*
42485 * Check if this process has the right to modify the specified
42486 * process. The right exists if the process has administrative
42487 @@ -1096,8 +1104,7 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid,
42488 rcu_read_lock();
42489 tcred = __task_cred(task);
42490 if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
42491 - cred->uid != tcred->suid && cred->uid != tcred->uid &&
42492 - !capable(CAP_SYS_NICE)) {
42493 + cred->uid != tcred->suid && !capable(CAP_SYS_NICE)) {
42494 rcu_read_unlock();
42495 err = -EPERM;
42496 goto out;
42497 diff -urNp linux-2.6.31.1/mm/mlock.c linux-2.6.31.1/mm/mlock.c
42498 --- linux-2.6.31.1/mm/mlock.c 2009-09-24 11:45:25.000000000 -0400
42499 +++ linux-2.6.31.1/mm/mlock.c 2009-10-01 20:12:45.000000000 -0400
42500 @@ -13,6 +13,7 @@
42501 #include <linux/pagemap.h>
42502 #include <linux/mempolicy.h>
42503 #include <linux/syscalls.h>
42504 +#include <linux/security.h>
42505 #include <linux/sched.h>
42506 #include <linux/module.h>
42507 #include <linux/rmap.h>
42508 @@ -431,6 +432,17 @@ static int do_mlock(unsigned long start,
42509 return -EINVAL;
42510 if (end == start)
42511 return 0;
42512 +
42513 +#ifdef CONFIG_PAX_SEGMEXEC
42514 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
42515 + if (end > SEGMEXEC_TASK_SIZE)
42516 + return -EINVAL;
42517 + } else
42518 +#endif
42519 +
42520 + if (end > TASK_SIZE)
42521 + return -EINVAL;
42522 +
42523 vma = find_vma_prev(current->mm, start, &prev);
42524 if (!vma || vma->vm_start > start)
42525 return -ENOMEM;
42526 @@ -490,6 +502,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
42527 lock_limit >>= PAGE_SHIFT;
42528
42529 /* check against resource limits */
42530 + gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
42531 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
42532 error = do_mlock(start, len, 1);
42533 up_write(&current->mm->mmap_sem);
42534 @@ -511,10 +524,10 @@ SYSCALL_DEFINE2(munlock, unsigned long,
42535 static int do_mlockall(int flags)
42536 {
42537 struct vm_area_struct * vma, * prev = NULL;
42538 - unsigned int def_flags = 0;
42539 + unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
42540
42541 if (flags & MCL_FUTURE)
42542 - def_flags = VM_LOCKED;
42543 + def_flags |= VM_LOCKED;
42544 current->mm->def_flags = def_flags;
42545 if (flags == MCL_FUTURE)
42546 goto out;
42547 @@ -522,6 +535,12 @@ static int do_mlockall(int flags)
42548 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
42549 unsigned int newflags;
42550
42551 +#ifdef CONFIG_PAX_SEGMEXEC
42552 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
42553 + break;
42554 +#endif
42555 +
42556 + BUG_ON(vma->vm_end > TASK_SIZE);
42557 newflags = vma->vm_flags | VM_LOCKED;
42558 if (!(flags & MCL_CURRENT))
42559 newflags &= ~VM_LOCKED;
42560 @@ -553,6 +572,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
42561 lock_limit >>= PAGE_SHIFT;
42562
42563 ret = -ENOMEM;
42564 + gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
42565 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
42566 capable(CAP_IPC_LOCK))
42567 ret = do_mlockall(flags);
42568 diff -urNp linux-2.6.31.1/mm/mmap.c linux-2.6.31.1/mm/mmap.c
42569 --- linux-2.6.31.1/mm/mmap.c 2009-09-24 11:45:25.000000000 -0400
42570 +++ linux-2.6.31.1/mm/mmap.c 2009-10-01 20:12:45.000000000 -0400
42571 @@ -45,6 +45,16 @@
42572 #define arch_rebalance_pgtables(addr, len) (addr)
42573 #endif
42574
42575 +static inline void verify_mm_writelocked(struct mm_struct *mm)
42576 +{
42577 +#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
42578 + if (unlikely(down_read_trylock(&mm->mmap_sem))) {
42579 + up_read(&mm->mmap_sem);
42580 + BUG();
42581 + }
42582 +#endif
42583 +}
42584 +
42585 static void unmap_region(struct mm_struct *mm,
42586 struct vm_area_struct *vma, struct vm_area_struct *prev,
42587 unsigned long start, unsigned long end);
42588 @@ -70,16 +80,25 @@ static void unmap_region(struct mm_struc
42589 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
42590 *
42591 */
42592 -pgprot_t protection_map[16] = {
42593 +pgprot_t protection_map[16] __read_only = {
42594 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
42595 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
42596 };
42597
42598 pgprot_t vm_get_page_prot(unsigned long vm_flags)
42599 {
42600 - return __pgprot(pgprot_val(protection_map[vm_flags &
42601 + pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
42602 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
42603 pgprot_val(arch_vm_get_page_prot(vm_flags)));
42604 +
42605 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
42606 + if (!nx_enabled &&
42607 + (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
42608 + (vm_flags & (VM_READ | VM_WRITE)))
42609 + prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
42610 +#endif
42611 +
42612 + return prot;
42613 }
42614 EXPORT_SYMBOL(vm_get_page_prot);
42615
42616 @@ -231,6 +250,7 @@ static struct vm_area_struct *remove_vma
42617 struct vm_area_struct *next = vma->vm_next;
42618
42619 might_sleep();
42620 + BUG_ON(vma->vm_mirror);
42621 if (vma->vm_ops && vma->vm_ops->close)
42622 vma->vm_ops->close(vma);
42623 if (vma->vm_file) {
42624 @@ -267,6 +287,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
42625 * not page aligned -Ram Gupta
42626 */
42627 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
42628 + gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
42629 if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
42630 (mm->end_data - mm->start_data) > rlim)
42631 goto out;
42632 @@ -696,6 +717,12 @@ static int
42633 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
42634 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
42635 {
42636 +
42637 +#ifdef CONFIG_PAX_SEGMEXEC
42638 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
42639 + return 0;
42640 +#endif
42641 +
42642 if (is_mergeable_vma(vma, file, vm_flags) &&
42643 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
42644 if (vma->vm_pgoff == vm_pgoff)
42645 @@ -715,6 +742,12 @@ static int
42646 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
42647 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
42648 {
42649 +
42650 +#ifdef CONFIG_PAX_SEGMEXEC
42651 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
42652 + return 0;
42653 +#endif
42654 +
42655 if (is_mergeable_vma(vma, file, vm_flags) &&
42656 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
42657 pgoff_t vm_pglen;
42658 @@ -757,12 +790,19 @@ can_vma_merge_after(struct vm_area_struc
42659 struct vm_area_struct *vma_merge(struct mm_struct *mm,
42660 struct vm_area_struct *prev, unsigned long addr,
42661 unsigned long end, unsigned long vm_flags,
42662 - struct anon_vma *anon_vma, struct file *file,
42663 + struct anon_vma *anon_vma, struct file *file,
42664 pgoff_t pgoff, struct mempolicy *policy)
42665 {
42666 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
42667 struct vm_area_struct *area, *next;
42668
42669 +#ifdef CONFIG_PAX_SEGMEXEC
42670 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
42671 + struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
42672 +
42673 + BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
42674 +#endif
42675 +
42676 /*
42677 * We later require that vma->vm_flags == vm_flags,
42678 * so this tests vma->vm_flags & VM_SPECIAL, too.
42679 @@ -778,6 +818,15 @@ struct vm_area_struct *vma_merge(struct
42680 if (next && next->vm_end == end) /* cases 6, 7, 8 */
42681 next = next->vm_next;
42682
42683 +#ifdef CONFIG_PAX_SEGMEXEC
42684 + if (prev)
42685 + prev_m = pax_find_mirror_vma(prev);
42686 + if (area)
42687 + area_m = pax_find_mirror_vma(area);
42688 + if (next)
42689 + next_m = pax_find_mirror_vma(next);
42690 +#endif
42691 +
42692 /*
42693 * Can it merge with the predecessor?
42694 */
42695 @@ -797,9 +846,24 @@ struct vm_area_struct *vma_merge(struct
42696 /* cases 1, 6 */
42697 vma_adjust(prev, prev->vm_start,
42698 next->vm_end, prev->vm_pgoff, NULL);
42699 - } else /* cases 2, 5, 7 */
42700 +
42701 +#ifdef CONFIG_PAX_SEGMEXEC
42702 + if (prev_m)
42703 + vma_adjust(prev_m, prev_m->vm_start,
42704 + next_m->vm_end, prev_m->vm_pgoff, NULL);
42705 +#endif
42706 +
42707 + } else { /* cases 2, 5, 7 */
42708 vma_adjust(prev, prev->vm_start,
42709 end, prev->vm_pgoff, NULL);
42710 +
42711 +#ifdef CONFIG_PAX_SEGMEXEC
42712 + if (prev_m)
42713 + vma_adjust(prev_m, prev_m->vm_start,
42714 + end_m, prev_m->vm_pgoff, NULL);
42715 +#endif
42716 +
42717 + }
42718 return prev;
42719 }
42720
42721 @@ -810,12 +874,27 @@ struct vm_area_struct *vma_merge(struct
42722 mpol_equal(policy, vma_policy(next)) &&
42723 can_vma_merge_before(next, vm_flags,
42724 anon_vma, file, pgoff+pglen)) {
42725 - if (prev && addr < prev->vm_end) /* case 4 */
42726 + if (prev && addr < prev->vm_end) { /* case 4 */
42727 vma_adjust(prev, prev->vm_start,
42728 addr, prev->vm_pgoff, NULL);
42729 - else /* cases 3, 8 */
42730 +
42731 +#ifdef CONFIG_PAX_SEGMEXEC
42732 + if (prev_m)
42733 + vma_adjust(prev_m, prev_m->vm_start,
42734 + addr_m, prev_m->vm_pgoff, NULL);
42735 +#endif
42736 +
42737 + } else { /* cases 3, 8 */
42738 vma_adjust(area, addr, next->vm_end,
42739 next->vm_pgoff - pglen, NULL);
42740 +
42741 +#ifdef CONFIG_PAX_SEGMEXEC
42742 + if (area_m)
42743 + vma_adjust(area_m, addr_m, next_m->vm_end,
42744 + next_m->vm_pgoff - pglen, NULL);
42745 +#endif
42746 +
42747 + }
42748 return area;
42749 }
42750
42751 @@ -890,14 +969,11 @@ none:
42752 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
42753 struct file *file, long pages)
42754 {
42755 - const unsigned long stack_flags
42756 - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
42757 -
42758 if (file) {
42759 mm->shared_vm += pages;
42760 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
42761 mm->exec_vm += pages;
42762 - } else if (flags & stack_flags)
42763 + } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
42764 mm->stack_vm += pages;
42765 if (flags & (VM_RESERVED|VM_IO))
42766 mm->reserved_vm += pages;
42767 @@ -924,7 +1000,7 @@ unsigned long do_mmap_pgoff(struct file
42768 * (the exception is when the underlying filesystem is noexec
42769 * mounted, in which case we dont add PROT_EXEC.)
42770 */
42771 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
42772 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
42773 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
42774 prot |= PROT_EXEC;
42775
42776 @@ -934,15 +1010,15 @@ unsigned long do_mmap_pgoff(struct file
42777 if (!(flags & MAP_FIXED))
42778 addr = round_hint_to_min(addr);
42779
42780 - error = arch_mmap_check(addr, len, flags);
42781 - if (error)
42782 - return error;
42783 -
42784 /* Careful about overflows.. */
42785 len = PAGE_ALIGN(len);
42786 if (!len || len > TASK_SIZE)
42787 return -ENOMEM;
42788
42789 + error = arch_mmap_check(addr, len, flags);
42790 + if (error)
42791 + return error;
42792 +
42793 /* offset overflow? */
42794 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
42795 return -EOVERFLOW;
42796 @@ -954,7 +1030,7 @@ unsigned long do_mmap_pgoff(struct file
42797 /* Obtain the address to map to. we verify (or select) it and ensure
42798 * that it represents a valid section of the address space.
42799 */
42800 - addr = get_unmapped_area(file, addr, len, pgoff, flags);
42801 + addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
42802 if (addr & ~PAGE_MASK)
42803 return addr;
42804
42805 @@ -965,6 +1041,26 @@ unsigned long do_mmap_pgoff(struct file
42806 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
42807 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
42808
42809 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
42810 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
42811 +
42812 +#ifdef CONFIG_PAX_MPROTECT
42813 + if (mm->pax_flags & MF_PAX_MPROTECT) {
42814 + if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
42815 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
42816 + else
42817 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
42818 + }
42819 +#endif
42820 +
42821 + }
42822 +#endif
42823 +
42824 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
42825 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
42826 + vm_flags &= ~VM_PAGEEXEC;
42827 +#endif
42828 +
42829 if (flags & MAP_LOCKED) {
42830 if (!can_do_mlock())
42831 return -EPERM;
42832 @@ -978,6 +1074,7 @@ unsigned long do_mmap_pgoff(struct file
42833 locked += mm->locked_vm;
42834 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
42835 lock_limit >>= PAGE_SHIFT;
42836 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
42837 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
42838 return -EAGAIN;
42839 }
42840 @@ -1051,6 +1148,9 @@ unsigned long do_mmap_pgoff(struct file
42841 if (error)
42842 return error;
42843
42844 + if (!gr_acl_handle_mmap(file, prot))
42845 + return -EACCES;
42846 +
42847 return mmap_region(file, addr, len, flags, vm_flags, pgoff);
42848 }
42849 EXPORT_SYMBOL(do_mmap_pgoff);
42850 @@ -1063,10 +1163,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
42851 */
42852 int vma_wants_writenotify(struct vm_area_struct *vma)
42853 {
42854 - unsigned int vm_flags = vma->vm_flags;
42855 + unsigned long vm_flags = vma->vm_flags;
42856
42857 /* If it was private or non-writable, the write bit is already clear */
42858 - if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
42859 + if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
42860 return 0;
42861
42862 /* The backer wishes to know when pages are first written to? */
42863 @@ -1115,14 +1215,24 @@ unsigned long mmap_region(struct file *f
42864 unsigned long charged = 0;
42865 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
42866
42867 +#ifdef CONFIG_PAX_SEGMEXEC
42868 + struct vm_area_struct *vma_m = NULL;
42869 +#endif
42870 +
42871 + /*
42872 + * mm->mmap_sem is required to protect against another thread
42873 + * changing the mappings in case we sleep.
42874 + */
42875 + verify_mm_writelocked(mm);
42876 +
42877 /* Clear old maps */
42878 error = -ENOMEM;
42879 -munmap_back:
42880 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
42881 if (vma && vma->vm_start < addr + len) {
42882 if (do_munmap(mm, addr, len))
42883 return -ENOMEM;
42884 - goto munmap_back;
42885 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
42886 + BUG_ON(vma && vma->vm_start < addr + len);
42887 }
42888
42889 /* Check against address space limit. */
42890 @@ -1171,6 +1281,16 @@ munmap_back:
42891 goto unacct_error;
42892 }
42893
42894 +#ifdef CONFIG_PAX_SEGMEXEC
42895 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
42896 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
42897 + if (!vma_m) {
42898 + error = -ENOMEM;
42899 + goto free_vma;
42900 + }
42901 + }
42902 +#endif
42903 +
42904 vma->vm_mm = mm;
42905 vma->vm_start = addr;
42906 vma->vm_end = addr + len;
42907 @@ -1193,6 +1313,19 @@ munmap_back:
42908 error = file->f_op->mmap(file, vma);
42909 if (error)
42910 goto unmap_and_free_vma;
42911 +
42912 +#ifdef CONFIG_PAX_SEGMEXEC
42913 + if (vma_m && (vm_flags & VM_EXECUTABLE))
42914 + added_exe_file_vma(mm);
42915 +#endif
42916 +
42917 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
42918 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
42919 + vma->vm_flags |= VM_PAGEEXEC;
42920 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
42921 + }
42922 +#endif
42923 +
42924 if (vm_flags & VM_EXECUTABLE)
42925 added_exe_file_vma(mm);
42926 } else if (vm_flags & VM_SHARED) {
42927 @@ -1216,6 +1349,11 @@ munmap_back:
42928 vma_link(mm, vma, prev, rb_link, rb_parent);
42929 file = vma->vm_file;
42930
42931 +#ifdef CONFIG_PAX_SEGMEXEC
42932 + if (vma_m)
42933 + pax_mirror_vma(vma_m, vma);
42934 +#endif
42935 +
42936 /* Once vma denies write, undo our temporary denial count */
42937 if (correct_wcount)
42938 atomic_inc(&inode->i_writecount);
42939 @@ -1224,6 +1362,7 @@ out:
42940
42941 mm->total_vm += len >> PAGE_SHIFT;
42942 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
42943 + track_exec_limit(mm, addr, addr + len, vm_flags);
42944 if (vm_flags & VM_LOCKED) {
42945 /*
42946 * makes pages present; downgrades, drops, reacquires mmap_sem
42947 @@ -1246,6 +1385,12 @@ unmap_and_free_vma:
42948 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
42949 charged = 0;
42950 free_vma:
42951 +
42952 +#ifdef CONFIG_PAX_SEGMEXEC
42953 + if (vma_m)
42954 + kmem_cache_free(vm_area_cachep, vma_m);
42955 +#endif
42956 +
42957 kmem_cache_free(vm_area_cachep, vma);
42958 unacct_error:
42959 if (charged)
42960 @@ -1279,6 +1424,10 @@ arch_get_unmapped_area(struct file *filp
42961 if (flags & MAP_FIXED)
42962 return addr;
42963
42964 +#ifdef CONFIG_PAX_RANDMMAP
42965 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
42966 +#endif
42967 +
42968 if (addr) {
42969 addr = PAGE_ALIGN(addr);
42970 vma = find_vma(mm, addr);
42971 @@ -1287,10 +1436,10 @@ arch_get_unmapped_area(struct file *filp
42972 return addr;
42973 }
42974 if (len > mm->cached_hole_size) {
42975 - start_addr = addr = mm->free_area_cache;
42976 + start_addr = addr = mm->free_area_cache;
42977 } else {
42978 - start_addr = addr = TASK_UNMAPPED_BASE;
42979 - mm->cached_hole_size = 0;
42980 + start_addr = addr = mm->mmap_base;
42981 + mm->cached_hole_size = 0;
42982 }
42983
42984 full_search:
42985 @@ -1301,9 +1450,8 @@ full_search:
42986 * Start a new search - just in case we missed
42987 * some holes.
42988 */
42989 - if (start_addr != TASK_UNMAPPED_BASE) {
42990 - addr = TASK_UNMAPPED_BASE;
42991 - start_addr = addr;
42992 + if (start_addr != mm->mmap_base) {
42993 + start_addr = addr = mm->mmap_base;
42994 mm->cached_hole_size = 0;
42995 goto full_search;
42996 }
42997 @@ -1325,10 +1473,16 @@ full_search:
42998
42999 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
43000 {
43001 +
43002 +#ifdef CONFIG_PAX_SEGMEXEC
43003 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
43004 + return;
43005 +#endif
43006 +
43007 /*
43008 * Is this a new hole at the lowest possible address?
43009 */
43010 - if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
43011 + if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
43012 mm->free_area_cache = addr;
43013 mm->cached_hole_size = ~0UL;
43014 }
43015 @@ -1346,7 +1500,7 @@ arch_get_unmapped_area_topdown(struct fi
43016 {
43017 struct vm_area_struct *vma;
43018 struct mm_struct *mm = current->mm;
43019 - unsigned long addr = addr0;
43020 + unsigned long base = mm->mmap_base, addr = addr0;
43021
43022 /* requested length too big for entire address space */
43023 if (len > TASK_SIZE)
43024 @@ -1355,6 +1509,10 @@ arch_get_unmapped_area_topdown(struct fi
43025 if (flags & MAP_FIXED)
43026 return addr;
43027
43028 +#ifdef CONFIG_PAX_RANDMMAP
43029 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
43030 +#endif
43031 +
43032 /* requesting a specific address */
43033 if (addr) {
43034 addr = PAGE_ALIGN(addr);
43035 @@ -1412,13 +1570,21 @@ bottomup:
43036 * can happen with large stack limits and large mmap()
43037 * allocations.
43038 */
43039 + mm->mmap_base = TASK_UNMAPPED_BASE;
43040 +
43041 +#ifdef CONFIG_PAX_RANDMMAP
43042 + if (mm->pax_flags & MF_PAX_RANDMMAP)
43043 + mm->mmap_base += mm->delta_mmap;
43044 +#endif
43045 +
43046 + mm->free_area_cache = mm->mmap_base;
43047 mm->cached_hole_size = ~0UL;
43048 - mm->free_area_cache = TASK_UNMAPPED_BASE;
43049 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
43050 /*
43051 * Restore the topdown base:
43052 */
43053 - mm->free_area_cache = mm->mmap_base;
43054 + mm->mmap_base = base;
43055 + mm->free_area_cache = base;
43056 mm->cached_hole_size = ~0UL;
43057
43058 return addr;
43059 @@ -1427,6 +1593,12 @@ bottomup:
43060
43061 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
43062 {
43063 +
43064 +#ifdef CONFIG_PAX_SEGMEXEC
43065 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
43066 + return;
43067 +#endif
43068 +
43069 /*
43070 * Is this a new hole at the highest possible address?
43071 */
43072 @@ -1434,8 +1606,10 @@ void arch_unmap_area_topdown(struct mm_s
43073 mm->free_area_cache = addr;
43074
43075 /* dont allow allocations above current base */
43076 - if (mm->free_area_cache > mm->mmap_base)
43077 + if (mm->free_area_cache > mm->mmap_base) {
43078 mm->free_area_cache = mm->mmap_base;
43079 + mm->cached_hole_size = ~0UL;
43080 + }
43081 }
43082
43083 unsigned long
43084 @@ -1535,6 +1709,27 @@ out:
43085 return prev ? prev->vm_next : vma;
43086 }
43087
43088 +#ifdef CONFIG_PAX_SEGMEXEC
43089 +struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
43090 +{
43091 + struct vm_area_struct *vma_m;
43092 +
43093 + BUG_ON(!vma || vma->vm_start >= vma->vm_end);
43094 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
43095 + BUG_ON(vma->vm_mirror);
43096 + return NULL;
43097 + }
43098 + BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
43099 + vma_m = vma->vm_mirror;
43100 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
43101 + BUG_ON(vma->vm_file != vma_m->vm_file);
43102 + BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
43103 + BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
43104 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
43105 + return vma_m;
43106 +}
43107 +#endif
43108 +
43109 /*
43110 * Verify that the stack growth is acceptable and
43111 * update accounting. This is shared with both the
43112 @@ -1551,6 +1746,7 @@ static int acct_stack_growth(struct vm_a
43113 return -ENOMEM;
43114
43115 /* Stack limit test */
43116 + gr_learn_resource(current, RLIMIT_STACK, size, 1);
43117 if (size > rlim[RLIMIT_STACK].rlim_cur)
43118 return -ENOMEM;
43119
43120 @@ -1560,6 +1756,7 @@ static int acct_stack_growth(struct vm_a
43121 unsigned long limit;
43122 locked = mm->locked_vm + grow;
43123 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
43124 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
43125 if (locked > limit && !capable(CAP_IPC_LOCK))
43126 return -ENOMEM;
43127 }
43128 @@ -1595,35 +1792,40 @@ static
43129 #endif
43130 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
43131 {
43132 - int error;
43133 + int error, locknext;
43134
43135 if (!(vma->vm_flags & VM_GROWSUP))
43136 return -EFAULT;
43137
43138 + /* Also guard against wrapping around to address 0. */
43139 + if (address < PAGE_ALIGN(address+1))
43140 + address = PAGE_ALIGN(address+1);
43141 + else
43142 + return -ENOMEM;
43143 +
43144 /*
43145 * We must make sure the anon_vma is allocated
43146 * so that the anon_vma locking is not a noop.
43147 */
43148 if (unlikely(anon_vma_prepare(vma)))
43149 return -ENOMEM;
43150 + locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
43151 + if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
43152 + return -ENOMEM;
43153 anon_vma_lock(vma);
43154 + if (locknext)
43155 + anon_vma_lock(vma->vm_next);
43156
43157 /*
43158 * vma->vm_start/vm_end cannot change under us because the caller
43159 * is required to hold the mmap_sem in read mode. We need the
43160 - * anon_vma lock to serialize against concurrent expand_stacks.
43161 - * Also guard against wrapping around to address 0.
43162 + * anon_vma locks to serialize against concurrent expand_stacks
43163 + * and expand_upwards.
43164 */
43165 - if (address < PAGE_ALIGN(address+4))
43166 - address = PAGE_ALIGN(address+4);
43167 - else {
43168 - anon_vma_unlock(vma);
43169 - return -ENOMEM;
43170 - }
43171 error = 0;
43172
43173 /* Somebody else might have raced and expanded it already */
43174 - if (address > vma->vm_end) {
43175 + if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
43176 unsigned long size, grow;
43177
43178 size = address - vma->vm_start;
43179 @@ -1633,6 +1835,8 @@ int expand_upwards(struct vm_area_struct
43180 if (!error)
43181 vma->vm_end = address;
43182 }
43183 + if (locknext)
43184 + anon_vma_unlock(vma->vm_next);
43185 anon_vma_unlock(vma);
43186 return error;
43187 }
43188 @@ -1644,7 +1848,8 @@ int expand_upwards(struct vm_area_struct
43189 static int expand_downwards(struct vm_area_struct *vma,
43190 unsigned long address)
43191 {
43192 - int error;
43193 + int error, lockprev = 0;
43194 + struct vm_area_struct *prev = NULL;
43195
43196 /*
43197 * We must make sure the anon_vma is allocated
43198 @@ -1658,6 +1863,15 @@ static int expand_downwards(struct vm_ar
43199 if (error)
43200 return error;
43201
43202 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
43203 + find_vma_prev(vma->vm_mm, address, &prev);
43204 + lockprev = prev && (prev->vm_flags & VM_GROWSUP);
43205 +#endif
43206 + if (lockprev && unlikely(anon_vma_prepare(prev)))
43207 + return -ENOMEM;
43208 + if (lockprev)
43209 + anon_vma_lock(prev);
43210 +
43211 anon_vma_lock(vma);
43212
43213 /*
43214 @@ -1667,9 +1881,15 @@ static int expand_downwards(struct vm_ar
43215 */
43216
43217 /* Somebody else might have raced and expanded it already */
43218 - if (address < vma->vm_start) {
43219 + if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
43220 unsigned long size, grow;
43221
43222 +#ifdef CONFIG_PAX_SEGMEXEC
43223 + struct vm_area_struct *vma_m;
43224 +
43225 + vma_m = pax_find_mirror_vma(vma);
43226 +#endif
43227 +
43228 size = vma->vm_end - address;
43229 grow = (vma->vm_start - address) >> PAGE_SHIFT;
43230
43231 @@ -1677,9 +1897,20 @@ static int expand_downwards(struct vm_ar
43232 if (!error) {
43233 vma->vm_start = address;
43234 vma->vm_pgoff -= grow;
43235 + track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
43236 +
43237 +#ifdef CONFIG_PAX_SEGMEXEC
43238 + if (vma_m) {
43239 + vma_m->vm_start -= grow << PAGE_SHIFT;
43240 + vma_m->vm_pgoff -= grow;
43241 + }
43242 +#endif
43243 +
43244 }
43245 }
43246 anon_vma_unlock(vma);
43247 + if (lockprev)
43248 + anon_vma_unlock(prev);
43249 return error;
43250 }
43251
43252 @@ -1755,6 +1986,13 @@ static void remove_vma_list(struct mm_st
43253 do {
43254 long nrpages = vma_pages(vma);
43255
43256 +#ifdef CONFIG_PAX_SEGMEXEC
43257 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
43258 + vma = remove_vma(vma);
43259 + continue;
43260 + }
43261 +#endif
43262 +
43263 mm->total_vm -= nrpages;
43264 vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
43265 vma = remove_vma(vma);
43266 @@ -1799,6 +2037,16 @@ detach_vmas_to_be_unmapped(struct mm_str
43267
43268 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
43269 do {
43270 +
43271 +#ifdef CONFIG_PAX_SEGMEXEC
43272 + if (vma->vm_mirror) {
43273 + BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
43274 + vma->vm_mirror->vm_mirror = NULL;
43275 + vma->vm_mirror->vm_flags &= ~VM_EXEC;
43276 + vma->vm_mirror = NULL;
43277 + }
43278 +#endif
43279 +
43280 rb_erase(&vma->vm_rb, &mm->mm_rb);
43281 mm->map_count--;
43282 tail_vma = vma;
43283 @@ -1818,6 +2066,108 @@ detach_vmas_to_be_unmapped(struct mm_str
43284 * Split a vma into two pieces at address 'addr', a new vma is allocated
43285 * either for the first part or the tail.
43286 */
43287 +
43288 +#ifdef CONFIG_PAX_SEGMEXEC
43289 +int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
43290 + unsigned long addr, int new_below)
43291 +{
43292 + struct mempolicy *pol;
43293 + struct vm_area_struct *new, *vma_m, *new_m = NULL;
43294 + unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
43295 +
43296 + if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
43297 + return -EINVAL;
43298 +
43299 + vma_m = pax_find_mirror_vma(vma);
43300 + if (vma_m) {
43301 + BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
43302 + if (mm->map_count >= sysctl_max_map_count-1)
43303 + return -ENOMEM;
43304 + } else if (mm->map_count >= sysctl_max_map_count)
43305 + return -ENOMEM;
43306 +
43307 + new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
43308 + if (!new)
43309 + return -ENOMEM;
43310 +
43311 + if (vma_m) {
43312 + new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
43313 + if (!new_m) {
43314 + kmem_cache_free(vm_area_cachep, new);
43315 + return -ENOMEM;
43316 + }
43317 + }
43318 +
43319 + /* most fields are the same, copy all, and then fixup */
43320 + *new = *vma;
43321 +
43322 + if (new_below)
43323 + new->vm_end = addr;
43324 + else {
43325 + new->vm_start = addr;
43326 + new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
43327 + }
43328 +
43329 + if (vma_m) {
43330 + *new_m = *vma_m;
43331 + new_m->vm_mirror = new;
43332 + new->vm_mirror = new_m;
43333 +
43334 + if (new_below)
43335 + new_m->vm_end = addr_m;
43336 + else {
43337 + new_m->vm_start = addr_m;
43338 + new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
43339 + }
43340 + }
43341 +
43342 + pol = mpol_dup(vma_policy(vma));
43343 + if (IS_ERR(pol)) {
43344 + if (new_m)
43345 + kmem_cache_free(vm_area_cachep, new_m);
43346 + kmem_cache_free(vm_area_cachep, new);
43347 + return PTR_ERR(pol);
43348 + }
43349 + vma_set_policy(new, pol);
43350 +
43351 + if (new->vm_file) {
43352 + get_file(new->vm_file);
43353 + if (vma->vm_flags & VM_EXECUTABLE)
43354 + added_exe_file_vma(mm);
43355 + }
43356 +
43357 + if (new->vm_ops && new->vm_ops->open)
43358 + new->vm_ops->open(new);
43359 +
43360 + if (new_below)
43361 + vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
43362 + ((addr - new->vm_start) >> PAGE_SHIFT), new);
43363 + else
43364 + vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
43365 +
43366 + if (vma_m) {
43367 + mpol_get(pol);
43368 + vma_set_policy(new_m, pol);
43369 +
43370 + if (new_m->vm_file) {
43371 + get_file(new_m->vm_file);
43372 + if (vma_m->vm_flags & VM_EXECUTABLE)
43373 + added_exe_file_vma(mm);
43374 + }
43375 +
43376 + if (new_m->vm_ops && new_m->vm_ops->open)
43377 + new_m->vm_ops->open(new_m);
43378 +
43379 + if (new_below)
43380 + vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
43381 + ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
43382 + else
43383 + vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
43384 + }
43385 +
43386 + return 0;
43387 +}
43388 +#else
43389 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
43390 unsigned long addr, int new_below)
43391 {
43392 @@ -1869,17 +2219,37 @@ int split_vma(struct mm_struct * mm, str
43393
43394 return 0;
43395 }
43396 +#endif
43397
43398 /* Munmap is split into 2 main parts -- this part which finds
43399 * what needs doing, and the areas themselves, which do the
43400 * work. This now handles partial unmappings.
43401 * Jeremy Fitzhardinge <jeremy@goop.org>
43402 */
43403 +#ifdef CONFIG_PAX_SEGMEXEC
43404 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
43405 {
43406 + int ret = __do_munmap(mm, start, len);
43407 + if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
43408 + return ret;
43409 +
43410 + return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
43411 +}
43412 +
43413 +int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
43414 +#else
43415 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
43416 +#endif
43417 +{
43418 unsigned long end;
43419 struct vm_area_struct *vma, *prev, *last;
43420
43421 + /*
43422 + * mm->mmap_sem is required to protect against another thread
43423 + * changing the mappings in case we sleep.
43424 + */
43425 + verify_mm_writelocked(mm);
43426 +
43427 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
43428 return -EINVAL;
43429
43430 @@ -1943,6 +2313,8 @@ int do_munmap(struct mm_struct *mm, unsi
43431 /* Fix up all other VM information */
43432 remove_vma_list(mm, vma);
43433
43434 + track_exec_limit(mm, start, end, 0UL);
43435 +
43436 return 0;
43437 }
43438
43439 @@ -1955,22 +2327,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, a
43440
43441 profile_munmap(addr);
43442
43443 +#ifdef CONFIG_PAX_SEGMEXEC
43444 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
43445 + (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
43446 + return -EINVAL;
43447 +#endif
43448 +
43449 down_write(&mm->mmap_sem);
43450 ret = do_munmap(mm, addr, len);
43451 up_write(&mm->mmap_sem);
43452 return ret;
43453 }
43454
43455 -static inline void verify_mm_writelocked(struct mm_struct *mm)
43456 -{
43457 -#ifdef CONFIG_DEBUG_VM
43458 - if (unlikely(down_read_trylock(&mm->mmap_sem))) {
43459 - WARN_ON(1);
43460 - up_read(&mm->mmap_sem);
43461 - }
43462 -#endif
43463 -}
43464 -
43465 /*
43466 * this is really a simplified "do_mmap". it only handles
43467 * anonymous maps. eventually we may be able to do some
43468 @@ -1984,6 +2352,11 @@ unsigned long do_brk(unsigned long addr,
43469 struct rb_node ** rb_link, * rb_parent;
43470 pgoff_t pgoff = addr >> PAGE_SHIFT;
43471 int error;
43472 + unsigned long charged;
43473 +
43474 +#ifdef CONFIG_PAX_SEGMEXEC
43475 + struct vm_area_struct *vma_m = NULL;
43476 +#endif
43477
43478 len = PAGE_ALIGN(len);
43479 if (!len)
43480 @@ -2001,19 +2374,34 @@ unsigned long do_brk(unsigned long addr,
43481
43482 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
43483
43484 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
43485 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
43486 + flags &= ~VM_EXEC;
43487 +
43488 +#ifdef CONFIG_PAX_MPROTECT
43489 + if (mm->pax_flags & MF_PAX_MPROTECT)
43490 + flags &= ~VM_MAYEXEC;
43491 +#endif
43492 +
43493 + }
43494 +#endif
43495 +
43496 error = arch_mmap_check(addr, len, flags);
43497 if (error)
43498 return error;
43499
43500 + charged = len >> PAGE_SHIFT;
43501 +
43502 /*
43503 * mlock MCL_FUTURE?
43504 */
43505 if (mm->def_flags & VM_LOCKED) {
43506 unsigned long locked, lock_limit;
43507 - locked = len >> PAGE_SHIFT;
43508 + locked = charged;
43509 locked += mm->locked_vm;
43510 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
43511 lock_limit >>= PAGE_SHIFT;
43512 + gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
43513 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
43514 return -EAGAIN;
43515 }
43516 @@ -2027,22 +2415,22 @@ unsigned long do_brk(unsigned long addr,
43517 /*
43518 * Clear old maps. this also does some error checking for us
43519 */
43520 - munmap_back:
43521 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
43522 if (vma && vma->vm_start < addr + len) {
43523 if (do_munmap(mm, addr, len))
43524 return -ENOMEM;
43525 - goto munmap_back;
43526 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
43527 + BUG_ON(vma && vma->vm_start < addr + len);
43528 }
43529
43530 /* Check against address space limits *after* clearing old maps... */
43531 - if (!may_expand_vm(mm, len >> PAGE_SHIFT))
43532 + if (!may_expand_vm(mm, charged))
43533 return -ENOMEM;
43534
43535 if (mm->map_count > sysctl_max_map_count)
43536 return -ENOMEM;
43537
43538 - if (security_vm_enough_memory(len >> PAGE_SHIFT))
43539 + if (security_vm_enough_memory(charged))
43540 return -ENOMEM;
43541
43542 /* Can we just expand an old private anonymous mapping? */
43543 @@ -2056,10 +2444,21 @@ unsigned long do_brk(unsigned long addr,
43544 */
43545 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
43546 if (!vma) {
43547 - vm_unacct_memory(len >> PAGE_SHIFT);
43548 + vm_unacct_memory(charged);
43549 return -ENOMEM;
43550 }
43551
43552 +#ifdef CONFIG_PAX_SEGMEXEC
43553 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
43554 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
43555 + if (!vma_m) {
43556 + kmem_cache_free(vm_area_cachep, vma);
43557 + vm_unacct_memory(charged);
43558 + return -ENOMEM;
43559 + }
43560 + }
43561 +#endif
43562 +
43563 vma->vm_mm = mm;
43564 vma->vm_start = addr;
43565 vma->vm_end = addr + len;
43566 @@ -2068,11 +2467,12 @@ unsigned long do_brk(unsigned long addr,
43567 vma->vm_page_prot = vm_get_page_prot(flags);
43568 vma_link(mm, vma, prev, rb_link, rb_parent);
43569 out:
43570 - mm->total_vm += len >> PAGE_SHIFT;
43571 + mm->total_vm += charged;
43572 if (flags & VM_LOCKED) {
43573 if (!mlock_vma_pages_range(vma, addr, addr + len))
43574 - mm->locked_vm += (len >> PAGE_SHIFT);
43575 + mm->locked_vm += charged;
43576 }
43577 + track_exec_limit(mm, addr, addr + len, flags);
43578 return addr;
43579 }
43580
43581 @@ -2118,8 +2518,10 @@ void exit_mmap(struct mm_struct *mm)
43582 * Walk the list again, actually closing and freeing it,
43583 * with preemption enabled, without holding any MM locks.
43584 */
43585 - while (vma)
43586 + while (vma) {
43587 + vma->vm_mirror = NULL;
43588 vma = remove_vma(vma);
43589 + }
43590
43591 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
43592 }
43593 @@ -2133,6 +2535,10 @@ int insert_vm_struct(struct mm_struct *
43594 struct vm_area_struct * __vma, * prev;
43595 struct rb_node ** rb_link, * rb_parent;
43596
43597 +#ifdef CONFIG_PAX_SEGMEXEC
43598 + struct vm_area_struct *vma_m = NULL;
43599 +#endif
43600 +
43601 /*
43602 * The vm_pgoff of a purely anonymous vma should be irrelevant
43603 * until its first write fault, when page's anon_vma and index
43604 @@ -2155,7 +2561,22 @@ int insert_vm_struct(struct mm_struct *
43605 if ((vma->vm_flags & VM_ACCOUNT) &&
43606 security_vm_enough_memory_mm(mm, vma_pages(vma)))
43607 return -ENOMEM;
43608 +
43609 +#ifdef CONFIG_PAX_SEGMEXEC
43610 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
43611 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
43612 + if (!vma_m)
43613 + return -ENOMEM;
43614 + }
43615 +#endif
43616 +
43617 vma_link(mm, vma, prev, rb_link, rb_parent);
43618 +
43619 +#ifdef CONFIG_PAX_SEGMEXEC
43620 + if (vma_m)
43621 + pax_mirror_vma(vma_m, vma);
43622 +#endif
43623 +
43624 return 0;
43625 }
43626
43627 @@ -2173,6 +2594,8 @@ struct vm_area_struct *copy_vma(struct v
43628 struct rb_node **rb_link, *rb_parent;
43629 struct mempolicy *pol;
43630
43631 + BUG_ON(vma->vm_mirror);
43632 +
43633 /*
43634 * If anonymous vma has not yet been faulted, update new pgoff
43635 * to match new location, to increase its chance of merging.
43636 @@ -2216,6 +2639,35 @@ struct vm_area_struct *copy_vma(struct v
43637 return new_vma;
43638 }
43639
43640 +#ifdef CONFIG_PAX_SEGMEXEC
43641 +void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
43642 +{
43643 + struct vm_area_struct *prev_m;
43644 + struct rb_node **rb_link_m, *rb_parent_m;
43645 + struct mempolicy *pol_m;
43646 +
43647 + BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
43648 + BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
43649 + BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
43650 + *vma_m = *vma;
43651 + pol_m = vma_policy(vma_m);
43652 + mpol_get(pol_m);
43653 + vma_set_policy(vma_m, pol_m);
43654 + vma_m->vm_start += SEGMEXEC_TASK_SIZE;
43655 + vma_m->vm_end += SEGMEXEC_TASK_SIZE;
43656 + vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
43657 + vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
43658 + if (vma_m->vm_file)
43659 + get_file(vma_m->vm_file);
43660 + if (vma_m->vm_ops && vma_m->vm_ops->open)
43661 + vma_m->vm_ops->open(vma_m);
43662 + find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
43663 + vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
43664 + vma_m->vm_mirror = vma;
43665 + vma->vm_mirror = vma_m;
43666 +}
43667 +#endif
43668 +
43669 /*
43670 * Return true if the calling process may expand its vm space by the passed
43671 * number of pages
43672 @@ -2226,7 +2678,7 @@ int may_expand_vm(struct mm_struct *mm,
43673 unsigned long lim;
43674
43675 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
43676 -
43677 + gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
43678 if (cur + npages > lim)
43679 return 0;
43680 return 1;
43681 @@ -2267,7 +2719,7 @@ static void special_mapping_close(struct
43682 {
43683 }
43684
43685 -static struct vm_operations_struct special_mapping_vmops = {
43686 +static const struct vm_operations_struct special_mapping_vmops = {
43687 .close = special_mapping_close,
43688 .fault = special_mapping_fault,
43689 };
43690 @@ -2295,6 +2747,15 @@ int install_special_mapping(struct mm_st
43691 vma->vm_start = addr;
43692 vma->vm_end = addr + len;
43693
43694 +#ifdef CONFIG_PAX_MPROTECT
43695 + if (mm->pax_flags & MF_PAX_MPROTECT) {
43696 + if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
43697 + vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
43698 + else
43699 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
43700 + }
43701 +#endif
43702 +
43703 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
43704 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
43705
43706 diff -urNp linux-2.6.31.1/mm/mprotect.c linux-2.6.31.1/mm/mprotect.c
43707 --- linux-2.6.31.1/mm/mprotect.c 2009-09-24 11:45:25.000000000 -0400
43708 +++ linux-2.6.31.1/mm/mprotect.c 2009-10-01 20:12:45.000000000 -0400
43709 @@ -24,10 +24,16 @@
43710 #include <linux/mmu_notifier.h>
43711 #include <linux/migrate.h>
43712 #include <linux/perf_counter.h>
43713 +
43714 +#ifdef CONFIG_PAX_MPROTECT
43715 +#include <linux/elf.h>
43716 +#endif
43717 +
43718 #include <asm/uaccess.h>
43719 #include <asm/pgtable.h>
43720 #include <asm/cacheflush.h>
43721 #include <asm/tlbflush.h>
43722 +#include <asm/mmu_context.h>
43723
43724 #ifndef pgprot_modify
43725 static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
43726 @@ -132,6 +138,48 @@ static void change_protection(struct vm_
43727 flush_tlb_range(vma, start, end);
43728 }
43729
43730 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
43731 +/* called while holding the mmap semaphor for writing except stack expansion */
43732 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
43733 +{
43734 + unsigned long oldlimit, newlimit = 0UL;
43735 +
43736 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
43737 + return;
43738 +
43739 + spin_lock(&mm->page_table_lock);
43740 + oldlimit = mm->context.user_cs_limit;
43741 + if ((prot & VM_EXEC) && oldlimit < end)
43742 + /* USER_CS limit moved up */
43743 + newlimit = end;
43744 + else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
43745 + /* USER_CS limit moved down */
43746 + newlimit = start;
43747 +
43748 + if (newlimit) {
43749 + mm->context.user_cs_limit = newlimit;
43750 +
43751 +#ifdef CONFIG_SMP
43752 + wmb();
43753 + cpus_clear(mm->context.cpu_user_cs_mask);
43754 + cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
43755 +#endif
43756 +
43757 + set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
43758 + }
43759 + spin_unlock(&mm->page_table_lock);
43760 + if (newlimit == end) {
43761 + struct vm_area_struct *vma = find_vma(mm, oldlimit);
43762 +
43763 + for (; vma && vma->vm_start < end; vma = vma->vm_next)
43764 + if (is_vm_hugetlb_page(vma))
43765 + hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
43766 + else
43767 + change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
43768 + }
43769 +}
43770 +#endif
43771 +
43772 int
43773 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
43774 unsigned long start, unsigned long end, unsigned long newflags)
43775 @@ -144,6 +192,14 @@ mprotect_fixup(struct vm_area_struct *vm
43776 int error;
43777 int dirty_accountable = 0;
43778
43779 +#ifdef CONFIG_PAX_SEGMEXEC
43780 + struct vm_area_struct *vma_m = NULL;
43781 + unsigned long start_m, end_m;
43782 +
43783 + start_m = start + SEGMEXEC_TASK_SIZE;
43784 + end_m = end + SEGMEXEC_TASK_SIZE;
43785 +#endif
43786 +
43787 if (newflags == oldflags) {
43788 *pprev = vma;
43789 return 0;
43790 @@ -165,6 +221,38 @@ mprotect_fixup(struct vm_area_struct *vm
43791 }
43792 }
43793
43794 +#ifdef CONFIG_PAX_SEGMEXEC
43795 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
43796 + if (start != vma->vm_start) {
43797 + error = split_vma(mm, vma, start, 1);
43798 + if (error)
43799 + goto fail;
43800 + BUG_ON(!*pprev || (*pprev)->vm_next == vma);
43801 + *pprev = (*pprev)->vm_next;
43802 + }
43803 +
43804 + if (end != vma->vm_end) {
43805 + error = split_vma(mm, vma, end, 0);
43806 + if (error)
43807 + goto fail;
43808 + }
43809 +
43810 + if (pax_find_mirror_vma(vma)) {
43811 + error = __do_munmap(mm, start_m, end_m - start_m);
43812 + if (error)
43813 + goto fail;
43814 + } else {
43815 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
43816 + if (!vma_m) {
43817 + error = -ENOMEM;
43818 + goto fail;
43819 + }
43820 + vma->vm_flags = newflags;
43821 + pax_mirror_vma(vma_m, vma);
43822 + }
43823 + }
43824 +#endif
43825 +
43826 /*
43827 * First try to merge with previous and/or next vma.
43828 */
43829 @@ -196,8 +284,14 @@ success:
43830 * held in write mode.
43831 */
43832 vma->vm_flags = newflags;
43833 +
43834 +#ifdef CONFIG_PAX_MPROTECT
43835 + if (current->binfmt && current->binfmt->handle_mprotect)
43836 + current->binfmt->handle_mprotect(vma, newflags);
43837 +#endif
43838 +
43839 vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
43840 - vm_get_page_prot(newflags));
43841 + vm_get_page_prot(vma->vm_flags));
43842
43843 if (vma_wants_writenotify(vma)) {
43844 vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
43845 @@ -238,6 +332,17 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
43846 end = start + len;
43847 if (end <= start)
43848 return -ENOMEM;
43849 +
43850 +#ifdef CONFIG_PAX_SEGMEXEC
43851 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
43852 + if (end > SEGMEXEC_TASK_SIZE)
43853 + return -EINVAL;
43854 + } else
43855 +#endif
43856 +
43857 + if (end > TASK_SIZE)
43858 + return -EINVAL;
43859 +
43860 if (!arch_validate_prot(prot))
43861 return -EINVAL;
43862
43863 @@ -245,7 +350,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
43864 /*
43865 * Does the application expect PROT_READ to imply PROT_EXEC:
43866 */
43867 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
43868 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
43869 prot |= PROT_EXEC;
43870
43871 vm_flags = calc_vm_prot_bits(prot);
43872 @@ -277,6 +382,16 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
43873 if (start > vma->vm_start)
43874 prev = vma;
43875
43876 + if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
43877 + error = -EACCES;
43878 + goto out;
43879 + }
43880 +
43881 +#ifdef CONFIG_PAX_MPROTECT
43882 + if (current->binfmt && current->binfmt->handle_mprotect)
43883 + current->binfmt->handle_mprotect(vma, vm_flags);
43884 +#endif
43885 +
43886 for (nstart = start ; ; ) {
43887 unsigned long newflags;
43888
43889 @@ -301,6 +416,9 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
43890 if (error)
43891 goto out;
43892 perf_counter_mmap(vma);
43893 +
43894 + track_exec_limit(current->mm, nstart, tmp, vm_flags);
43895 +
43896 nstart = tmp;
43897
43898 if (nstart < prev->vm_end)
43899 diff -urNp linux-2.6.31.1/mm/mremap.c linux-2.6.31.1/mm/mremap.c
43900 --- linux-2.6.31.1/mm/mremap.c 2009-09-24 11:45:25.000000000 -0400
43901 +++ linux-2.6.31.1/mm/mremap.c 2009-10-01 20:12:45.000000000 -0400
43902 @@ -113,6 +113,12 @@ static void move_ptes(struct vm_area_str
43903 continue;
43904 pte = ptep_clear_flush(vma, old_addr, old_pte);
43905 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
43906 +
43907 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
43908 + if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
43909 + pte = pte_exprotect(pte);
43910 +#endif
43911 +
43912 set_pte_at(mm, new_addr, new_pte, pte);
43913 }
43914
43915 @@ -262,6 +268,7 @@ unsigned long do_mremap(unsigned long ad
43916 struct vm_area_struct *vma;
43917 unsigned long ret = -EINVAL;
43918 unsigned long charged = 0;
43919 + unsigned long pax_task_size = TASK_SIZE;
43920
43921 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
43922 goto out;
43923 @@ -280,6 +287,15 @@ unsigned long do_mremap(unsigned long ad
43924 if (!new_len)
43925 goto out;
43926
43927 +#ifdef CONFIG_PAX_SEGMEXEC
43928 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
43929 + pax_task_size = SEGMEXEC_TASK_SIZE;
43930 +#endif
43931 +
43932 + if (new_len > pax_task_size || addr > pax_task_size-new_len ||
43933 + old_len > pax_task_size || addr > pax_task_size-old_len)
43934 + goto out;
43935 +
43936 /* new_addr is only valid if MREMAP_FIXED is specified */
43937 if (flags & MREMAP_FIXED) {
43938 if (new_addr & ~PAGE_MASK)
43939 @@ -287,16 +303,13 @@ unsigned long do_mremap(unsigned long ad
43940 if (!(flags & MREMAP_MAYMOVE))
43941 goto out;
43942
43943 - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
43944 + if (new_addr > pax_task_size - new_len)
43945 goto out;
43946
43947 /* Check if the location we're moving into overlaps the
43948 * old location at all, and fail if it does.
43949 */
43950 - if ((new_addr <= addr) && (new_addr+new_len) > addr)
43951 - goto out;
43952 -
43953 - if ((addr <= new_addr) && (addr+old_len) > new_addr)
43954 + if (addr + old_len > new_addr && new_addr + new_len > addr)
43955 goto out;
43956
43957 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
43958 @@ -334,6 +347,14 @@ unsigned long do_mremap(unsigned long ad
43959 ret = -EINVAL;
43960 goto out;
43961 }
43962 +
43963 +#ifdef CONFIG_PAX_SEGMEXEC
43964 + if (pax_find_mirror_vma(vma)) {
43965 + ret = -EINVAL;
43966 + goto out;
43967 + }
43968 +#endif
43969 +
43970 /* We can't remap across vm area boundaries */
43971 if (old_len > vma->vm_end - addr)
43972 goto out;
43973 @@ -367,7 +388,7 @@ unsigned long do_mremap(unsigned long ad
43974 if (old_len == vma->vm_end - addr &&
43975 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
43976 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
43977 - unsigned long max_addr = TASK_SIZE;
43978 + unsigned long max_addr = pax_task_size;
43979 if (vma->vm_next)
43980 max_addr = vma->vm_next->vm_start;
43981 /* can we just expand the current mapping? */
43982 @@ -385,6 +406,7 @@ unsigned long do_mremap(unsigned long ad
43983 addr + new_len);
43984 }
43985 ret = addr;
43986 + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
43987 goto out;
43988 }
43989 }
43990 @@ -395,8 +417,8 @@ unsigned long do_mremap(unsigned long ad
43991 */
43992 ret = -ENOMEM;
43993 if (flags & MREMAP_MAYMOVE) {
43994 + unsigned long map_flags = 0;
43995 if (!(flags & MREMAP_FIXED)) {
43996 - unsigned long map_flags = 0;
43997 if (vma->vm_flags & VM_MAYSHARE)
43998 map_flags |= MAP_SHARED;
43999
44000 @@ -411,7 +433,12 @@ unsigned long do_mremap(unsigned long ad
44001 if (ret)
44002 goto out;
44003 }
44004 + map_flags = vma->vm_flags;
44005 ret = move_vma(vma, addr, old_len, new_len, new_addr);
44006 + if (!(ret & ~PAGE_MASK)) {
44007 + track_exec_limit(current->mm, addr, addr + old_len, 0UL);
44008 + track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
44009 + }
44010 }
44011 out:
44012 if (ret & ~PAGE_MASK)
44013 diff -urNp linux-2.6.31.1/mm/nommu.c linux-2.6.31.1/mm/nommu.c
44014 --- linux-2.6.31.1/mm/nommu.c 2009-09-24 11:45:25.000000000 -0400
44015 +++ linux-2.6.31.1/mm/nommu.c 2009-10-01 20:12:45.000000000 -0400
44016 @@ -79,7 +79,7 @@ static struct kmem_cache *vm_region_jar;
44017 struct rb_root nommu_region_tree = RB_ROOT;
44018 DECLARE_RWSEM(nommu_region_sem);
44019
44020 -struct vm_operations_struct generic_file_vm_ops = {
44021 +const struct vm_operations_struct generic_file_vm_ops = {
44022 };
44023
44024 /*
44025 @@ -780,15 +780,6 @@ struct vm_area_struct *find_vma(struct m
44026 EXPORT_SYMBOL(find_vma);
44027
44028 /*
44029 - * find a VMA
44030 - * - we don't extend stack VMAs under NOMMU conditions
44031 - */
44032 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
44033 -{
44034 - return find_vma(mm, addr);
44035 -}
44036 -
44037 -/*
44038 * expand a stack to a given address
44039 * - not supported under NOMMU conditions
44040 */
44041 diff -urNp linux-2.6.31.1/mm/page_alloc.c linux-2.6.31.1/mm/page_alloc.c
44042 --- linux-2.6.31.1/mm/page_alloc.c 2009-09-24 11:45:25.000000000 -0400
44043 +++ linux-2.6.31.1/mm/page_alloc.c 2009-10-01 20:12:45.000000000 -0400
44044 @@ -559,6 +559,10 @@ static void __free_pages_ok(struct page
44045 int bad = 0;
44046 int wasMlocked = TestClearPageMlocked(page);
44047
44048 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
44049 + unsigned long index = 1UL << order;
44050 +#endif
44051 +
44052 kmemcheck_free_shadow(page, order);
44053
44054 for (i = 0 ; i < (1 << order) ; ++i)
44055 @@ -571,6 +575,12 @@ static void __free_pages_ok(struct page
44056 debug_check_no_obj_freed(page_address(page),
44057 PAGE_SIZE << order);
44058 }
44059 +
44060 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
44061 + for (; index; --index)
44062 + sanitize_highpage(page + index - 1);
44063 +#endif
44064 +
44065 arch_free_page(page, order);
44066 kernel_map_pages(page, 1 << order, 0);
44067
44068 @@ -662,8 +672,10 @@ static int prep_new_page(struct page *pa
44069 arch_alloc_page(page, order);
44070 kernel_map_pages(page, 1 << order, 1);
44071
44072 +#ifndef CONFIG_PAX_MEMORY_SANITIZE
44073 if (gfp_flags & __GFP_ZERO)
44074 prep_zero_page(page, order, gfp_flags);
44075 +#endif
44076
44077 if (order && (gfp_flags & __GFP_COMP))
44078 prep_compound_page(page, order);
44079 @@ -1039,6 +1051,11 @@ static void free_hot_cold_page(struct pa
44080 debug_check_no_locks_freed(page_address(page), PAGE_SIZE);
44081 debug_check_no_obj_freed(page_address(page), PAGE_SIZE);
44082 }
44083 +
44084 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
44085 + sanitize_highpage(page);
44086 +#endif
44087 +
44088 arch_free_page(page, 0);
44089 kernel_map_pages(page, 1, 0);
44090
44091 diff -urNp linux-2.6.31.1/mm/percpu.c linux-2.6.31.1/mm/percpu.c
44092 --- linux-2.6.31.1/mm/percpu.c 2009-09-24 11:45:25.000000000 -0400
44093 +++ linux-2.6.31.1/mm/percpu.c 2009-10-01 20:12:45.000000000 -0400
44094 @@ -105,7 +105,7 @@ static int pcpu_nr_slots __read_mostly;
44095 static size_t pcpu_chunk_struct_size __read_mostly;
44096
44097 /* the address of the first chunk which starts with the kernel static area */
44098 -void *pcpu_base_addr __read_mostly;
44099 +void *pcpu_base_addr __read_only;
44100 EXPORT_SYMBOL_GPL(pcpu_base_addr);
44101
44102 /*
44103 diff -urNp linux-2.6.31.1/mm/rmap.c linux-2.6.31.1/mm/rmap.c
44104 --- linux-2.6.31.1/mm/rmap.c 2009-09-24 11:45:25.000000000 -0400
44105 +++ linux-2.6.31.1/mm/rmap.c 2009-10-01 20:12:45.000000000 -0400
44106 @@ -103,6 +103,10 @@ int anon_vma_prepare(struct vm_area_stru
44107 struct mm_struct *mm = vma->vm_mm;
44108 struct anon_vma *allocated;
44109
44110 +#ifdef CONFIG_PAX_SEGMEXEC
44111 + struct vm_area_struct *vma_m;
44112 +#endif
44113 +
44114 anon_vma = find_mergeable_anon_vma(vma);
44115 allocated = NULL;
44116 if (!anon_vma) {
44117 @@ -116,6 +120,15 @@ int anon_vma_prepare(struct vm_area_stru
44118 /* page_table_lock to protect against threads */
44119 spin_lock(&mm->page_table_lock);
44120 if (likely(!vma->anon_vma)) {
44121 +
44122 +#ifdef CONFIG_PAX_SEGMEXEC
44123 + vma_m = pax_find_mirror_vma(vma);
44124 + if (vma_m) {
44125 + vma_m->anon_vma = anon_vma;
44126 + __anon_vma_link(vma_m);
44127 + }
44128 +#endif
44129 +
44130 vma->anon_vma = anon_vma;
44131 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
44132 allocated = NULL;
44133 diff -urNp linux-2.6.31.1/mm/shmem.c linux-2.6.31.1/mm/shmem.c
44134 --- linux-2.6.31.1/mm/shmem.c 2009-09-24 11:45:25.000000000 -0400
44135 +++ linux-2.6.31.1/mm/shmem.c 2009-10-01 20:12:45.000000000 -0400
44136 @@ -31,7 +31,7 @@
44137 #include <linux/swap.h>
44138 #include <linux/ima.h>
44139
44140 -static struct vfsmount *shm_mnt;
44141 +struct vfsmount *shm_mnt;
44142
44143 #ifdef CONFIG_SHMEM
44144 /*
44145 @@ -219,7 +219,7 @@ static const struct file_operations shme
44146 static const struct inode_operations shmem_inode_operations;
44147 static const struct inode_operations shmem_dir_inode_operations;
44148 static const struct inode_operations shmem_special_inode_operations;
44149 -static struct vm_operations_struct shmem_vm_ops;
44150 +static const struct vm_operations_struct shmem_vm_ops;
44151
44152 static struct backing_dev_info shmem_backing_dev_info __read_mostly = {
44153 .ra_pages = 0, /* No readahead */
44154 @@ -2497,7 +2497,7 @@ static const struct super_operations shm
44155 .put_super = shmem_put_super,
44156 };
44157
44158 -static struct vm_operations_struct shmem_vm_ops = {
44159 +static const struct vm_operations_struct shmem_vm_ops = {
44160 .fault = shmem_fault,
44161 #ifdef CONFIG_NUMA
44162 .set_policy = shmem_set_policy,
44163 diff -urNp linux-2.6.31.1/mm/slab.c linux-2.6.31.1/mm/slab.c
44164 --- linux-2.6.31.1/mm/slab.c 2009-09-24 11:45:25.000000000 -0400
44165 +++ linux-2.6.31.1/mm/slab.c 2009-10-01 20:12:45.000000000 -0400
44166 @@ -308,7 +308,7 @@ struct kmem_list3 {
44167 * Need this for bootstrapping a per node allocator.
44168 */
44169 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
44170 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
44171 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
44172 #define CACHE_CACHE 0
44173 #define SIZE_AC MAX_NUMNODES
44174 #define SIZE_L3 (2 * MAX_NUMNODES)
44175 @@ -558,7 +558,7 @@ static inline void *index_to_obj(struct
44176 * reciprocal_divide(offset, cache->reciprocal_buffer_size)
44177 */
44178 static inline unsigned int obj_to_index(const struct kmem_cache *cache,
44179 - const struct slab *slab, void *obj)
44180 + const struct slab *slab, const void *obj)
44181 {
44182 u32 offset = (obj - slab->s_mem);
44183 return reciprocal_divide(offset, cache->reciprocal_buffer_size);
44184 @@ -584,14 +584,14 @@ struct cache_names {
44185 static struct cache_names __initdata cache_names[] = {
44186 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
44187 #include <linux/kmalloc_sizes.h>
44188 - {NULL,}
44189 + {NULL, NULL}
44190 #undef CACHE
44191 };
44192
44193 static struct arraycache_init initarray_cache __initdata =
44194 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
44195 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
44196 static struct arraycache_init initarray_generic =
44197 - { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
44198 + { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
44199
44200 /* internal cache of cache description objs */
44201 static struct kmem_cache cache_cache = {
44202 @@ -4473,15 +4473,64 @@ static const struct file_operations proc
44203
44204 static int __init slab_proc_init(void)
44205 {
44206 +#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
44207 proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
44208 #ifdef CONFIG_DEBUG_SLAB_LEAK
44209 proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
44210 #endif
44211 +#endif
44212 return 0;
44213 }
44214 module_init(slab_proc_init);
44215 #endif
44216
44217 +void check_object_size(const void *ptr, unsigned long n, bool to)
44218 +{
44219 +
44220 +#ifdef CONFIG_PAX_USERCOPY
44221 + struct kmem_cache *cachep;
44222 + struct slab *slabp;
44223 + struct page *page;
44224 + unsigned int objnr;
44225 + unsigned long offset;
44226 +
44227 + if (!n)
44228 + return;
44229 +
44230 + if (ZERO_OR_NULL_PTR(ptr))
44231 + goto report;
44232 +
44233 + if (!virt_addr_valid(ptr))
44234 + return;
44235 +
44236 + page = virt_to_head_page(ptr);
44237 +
44238 + /* XXX: can get a little tighter with this stack check */
44239 + if (!PageSlab(page) && object_is_on_stack(ptr) &&
44240 + (n > ((unsigned long)task_stack_page(current) + THREAD_SIZE -
44241 + (unsigned long)ptr)))
44242 + goto report;
44243 + else
44244 + return;
44245 +
44246 + cachep = page_get_cache(page);
44247 + slabp = page_get_slab(page);
44248 + objnr = obj_to_index(cachep, slabp, ptr);
44249 + BUG_ON(objnr >= cachep->num);
44250 + offset = ptr - index_to_obj(cachep, slabp, objnr) - obj_offset(cachep);
44251 + if (offset <= obj_size(cachep) && n <= obj_size(cachep) - offset)
44252 + return;
44253 +
44254 +report:
44255 + if (to)
44256 + pax_report_leak_to_user(ptr, n);
44257 + else
44258 + pax_report_overflow_from_user(ptr, n);
44259 +#endif
44260 +
44261 +}
44262 +EXPORT_SYMBOL(check_object_size);
44263 +
44264 /**
44265 * ksize - get the actual amount of memory allocated for a given object
44266 * @objp: Pointer to the object
44267 diff -urNp linux-2.6.31.1/mm/slob.c linux-2.6.31.1/mm/slob.c
44268 --- linux-2.6.31.1/mm/slob.c 2009-09-24 11:45:25.000000000 -0400
44269 +++ linux-2.6.31.1/mm/slob.c 2009-10-01 20:12:45.000000000 -0400
44270 @@ -29,7 +29,7 @@
44271 * If kmalloc is asked for objects of PAGE_SIZE or larger, it calls
44272 * alloc_pages() directly, allocating compound pages so the page order
44273 * does not have to be separately tracked, and also stores the exact
44274 - * allocation size in page->private so that it can be used to accurately
44275 + * allocation size in slob_page->size so that it can be used to accurately
44276 * provide ksize(). These objects are detected in kfree() because slob_page()
44277 * is false for them.
44278 *
44279 @@ -58,6 +58,7 @@
44280 */
44281
44282 #include <linux/kernel.h>
44283 +#include <linux/sched.h>
44284 #include <linux/slab.h>
44285 #include <linux/mm.h>
44286 #include <linux/swap.h> /* struct reclaim_state */
44287 @@ -100,7 +101,8 @@ struct slob_page {
44288 unsigned long flags; /* mandatory */
44289 atomic_t _count; /* mandatory */
44290 slobidx_t units; /* free units left in page */
44291 - unsigned long pad[2];
44292 + unsigned long pad[1];
44293 + unsigned long size; /* size when >=PAGE_SIZE */
44294 slob_t *free; /* first free slob_t in page */
44295 struct list_head list; /* linked list of free pages */
44296 };
44297 @@ -133,7 +135,7 @@ static LIST_HEAD(free_slob_large);
44298 */
44299 static inline int is_slob_page(struct slob_page *sp)
44300 {
44301 - return PageSlab((struct page *)sp);
44302 + return PageSlab((struct page *)sp) && !sp->size;
44303 }
44304
44305 static inline void set_slob_page(struct slob_page *sp)
44306 @@ -148,7 +150,7 @@ static inline void clear_slob_page(struc
44307
44308 static inline struct slob_page *slob_page(const void *addr)
44309 {
44310 - return (struct slob_page *)virt_to_page(addr);
44311 + return (struct slob_page *)virt_to_head_page(addr);
44312 }
44313
44314 /*
44315 @@ -208,7 +210,7 @@ static void set_slob(slob_t *s, slobidx_
44316 /*
44317 * Return the size of a slob block.
44318 */
44319 -static slobidx_t slob_units(slob_t *s)
44320 +static slobidx_t slob_units(const slob_t *s)
44321 {
44322 if (s->units > 0)
44323 return s->units;
44324 @@ -218,7 +220,7 @@ static slobidx_t slob_units(slob_t *s)
44325 /*
44326 * Return the next free slob block pointer after this one.
44327 */
44328 -static slob_t *slob_next(slob_t *s)
44329 +static slob_t *slob_next(const slob_t *s)
44330 {
44331 slob_t *base = (slob_t *)((unsigned long)s & PAGE_MASK);
44332 slobidx_t next;
44333 @@ -233,7 +235,7 @@ static slob_t *slob_next(slob_t *s)
44334 /*
44335 * Returns true if s is the last free block in its page.
44336 */
44337 -static int slob_last(slob_t *s)
44338 +static int slob_last(const slob_t *s)
44339 {
44340 return !((unsigned long)slob_next(s) & ~PAGE_MASK);
44341 }
44342 @@ -252,6 +254,7 @@ static void *slob_new_pages(gfp_t gfp, i
44343 if (!page)
44344 return NULL;
44345
44346 + set_slob_page(page);
44347 return page_address(page);
44348 }
44349
44350 @@ -368,11 +371,11 @@ static void *slob_alloc(size_t size, gfp
44351 if (!b)
44352 return NULL;
44353 sp = slob_page(b);
44354 - set_slob_page(sp);
44355
44356 spin_lock_irqsave(&slob_lock, flags);
44357 sp->units = SLOB_UNITS(PAGE_SIZE);
44358 sp->free = b;
44359 + sp->size = 0;
44360 INIT_LIST_HEAD(&sp->list);
44361 set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
44362 set_slob_page_free(sp, slob_list);
44363 @@ -475,10 +478,9 @@ out:
44364 #define ARCH_SLAB_MINALIGN __alignof__(unsigned long)
44365 #endif
44366
44367 -void *__kmalloc_node(size_t size, gfp_t gfp, int node)
44368 +static void *__kmalloc_node_align(size_t size, gfp_t gfp, int node, int align)
44369 {
44370 - unsigned int *m;
44371 - int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
44372 + slob_t *m;
44373 void *ret;
44374
44375 lockdep_trace_alloc(gfp);
44376 @@ -491,7 +493,10 @@ void *__kmalloc_node(size_t size, gfp_t
44377
44378 if (!m)
44379 return NULL;
44380 - *m = size;
44381 + BUILD_BUG_ON(ARCH_KMALLOC_MINALIGN < 2 * SLOB_UNIT);
44382 + BUILD_BUG_ON(ARCH_SLAB_MINALIGN < 2 * SLOB_UNIT);
44383 + m[0].units = size;
44384 + m[1].units = align;
44385 ret = (void *)m + align;
44386
44387 trace_kmalloc_node(_RET_IP_, ret,
44388 @@ -501,9 +506,9 @@ void *__kmalloc_node(size_t size, gfp_t
44389
44390 ret = slob_new_pages(gfp | __GFP_COMP, get_order(size), node);
44391 if (ret) {
44392 - struct page *page;
44393 - page = virt_to_page(ret);
44394 - page->private = size;
44395 + struct slob_page *sp;
44396 + sp = slob_page(ret);
44397 + sp->size = size;
44398 }
44399
44400 trace_kmalloc_node(_RET_IP_, ret,
44401 @@ -513,6 +518,13 @@ void *__kmalloc_node(size_t size, gfp_t
44402 kmemleak_alloc(ret, size, 1, gfp);
44403 return ret;
44404 }
44405 +
44406 +void *__kmalloc_node(size_t size, gfp_t gfp, int node)
44407 +{
44408 + int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
44409 +
44410 + return __kmalloc_node_align(size, gfp, node, align);
44411 +}
44412 EXPORT_SYMBOL(__kmalloc_node);
44413
44414 void kfree(const void *block)
44415 @@ -528,13 +540,86 @@ void kfree(const void *block)
44416 sp = slob_page(block);
44417 if (is_slob_page(sp)) {
44418 int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
44419 - unsigned int *m = (unsigned int *)(block - align);
44420 - slob_free(m, *m + align);
44421 - } else
44422 + slob_t *m = (slob_t *)(block - align);
44423 + slob_free(m, m[0].units + align);
44424 + } else {
44425 + clear_slob_page(sp);
44426 + free_slob_page(sp);
44427 + sp->size = 0;
44428 put_page(&sp->page);
44429 + }
44430 }
44431 EXPORT_SYMBOL(kfree);
44432
44433 +void check_object_size(const void *ptr, unsigned long n, bool to)
44434 +{
44435 +
44436 +#ifdef CONFIG_PAX_USERCOPY
44437 + struct slob_page *sp;
44438 + const slob_t *free;
44439 + const void *base;
44440 +
44441 + if (!n)
44442 + return;
44443 +
44444 + if (ZERO_OR_NULL_PTR(ptr))
44445 + goto report;
44446 +
44447 + if (!virt_addr_valid(ptr))
44448 + return;
44449 +
44450 + sp = slob_page(ptr);
44451 + /* XXX: can get a little tighter with this stack check */
44452 + if (!PageSlobPage((struct page*)sp) && object_is_on_stack(ptr) &&
44453 + (n > ((unsigned long)task_stack_page(current) + THREAD_SIZE -
44454 + (unsigned long)ptr)))
44455 + goto report;
44456 + else
44457 + return;
44458 +
44459 + if (sp->size) {
44460 + base = page_address(&sp->page);
44461 + if (base <= ptr && n <= sp->size - (ptr - base))
44462 + return;
44463 + goto report;
44464 + }
44465 +
44466 + /* some tricky double walking to find the chunk */
44467 + base = (void *)((unsigned long)ptr & PAGE_MASK);
44468 + free = sp->free;
44469 +
44470 + while (!slob_last(free) && (void *)free <= ptr) {
44471 + base = free + slob_units(free);
44472 + free = slob_next(free);
44473 + }
44474 +
44475 + while (base < (void *)free) {
44476 + slobidx_t m = ((slob_t *)base)[0].units, align = ((slob_t *)base)[1].units;
44477 + int size = SLOB_UNIT * SLOB_UNITS(m + align);
44478 + int offset;
44479 +
44480 + if (ptr < base + align)
44481 + goto report;
44482 +
44483 + offset = ptr - base - align;
44484 + if (offset < m) {
44485 + if (n <= m - offset)
44486 + return;
44487 + goto report;
44488 + }
44489 + base += size;
44490 + }
44491 +
44492 +report:
44493 + if (to)
44494 + pax_report_leak_to_user(ptr, n);
44495 + else
44496 + pax_report_overflow_from_user(ptr, n);
44497 +#endif
44498 +
44499 +}
44500 +EXPORT_SYMBOL(check_object_size);
44501 +
44502 /* can't use ksize for kmem_cache_alloc memory, only kmalloc */
44503 size_t ksize(const void *block)
44504 {
44505 @@ -547,10 +632,10 @@ size_t ksize(const void *block)
44506 sp = slob_page(block);
44507 if (is_slob_page(sp)) {
44508 int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
44509 - unsigned int *m = (unsigned int *)(block - align);
44510 - return SLOB_UNITS(*m) * SLOB_UNIT;
44511 + slob_t *m = (slob_t *)(block - align);
44512 + return SLOB_UNITS(m[0].units) * SLOB_UNIT;
44513 } else
44514 - return sp->page.private;
44515 + return sp->size;
44516 }
44517 EXPORT_SYMBOL(ksize);
44518
44519 @@ -605,17 +690,25 @@ void *kmem_cache_alloc_node(struct kmem_
44520 {
44521 void *b;
44522
44523 +#ifdef CONFIG_PAX_USERCOPY
44524 + b = __kmalloc_node_align(c->size, flags, node, c->align);
44525 +#else
44526 if (c->size < PAGE_SIZE) {
44527 b = slob_alloc(c->size, flags, c->align, node);
44528 trace_kmem_cache_alloc_node(_RET_IP_, b, c->size,
44529 SLOB_UNITS(c->size) * SLOB_UNIT,
44530 flags, node);
44531 } else {
44532 + struct slob_page *sp;
44533 +
44534 b = slob_new_pages(flags, get_order(c->size), node);
44535 + sp = slob_page(b);
44536 + sp->size = c->size;
44537 trace_kmem_cache_alloc_node(_RET_IP_, b, c->size,
44538 PAGE_SIZE << get_order(c->size),
44539 flags, node);
44540 }
44541 +#endif
44542
44543 if (c->ctor)
44544 c->ctor(b);
44545 @@ -627,10 +720,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
44546
44547 static void __kmem_cache_free(void *b, int size)
44548 {
44549 - if (size < PAGE_SIZE)
44550 + struct slob_page *sp = slob_page(b);
44551 +
44552 + if (is_slob_page(sp))
44553 slob_free(b, size);
44554 - else
44555 + else {
44556 + clear_slob_page(sp);
44557 + free_slob_page(sp);
44558 + sp->size = 0;
44559 slob_free_pages(b, get_order(size));
44560 + }
44561 }
44562
44563 static void kmem_rcu_free(struct rcu_head *head)
44564 @@ -643,15 +742,24 @@ static void kmem_rcu_free(struct rcu_hea
44565
44566 void kmem_cache_free(struct kmem_cache *c, void *b)
44567 {
44568 + int size = c->size;
44569 +
44570 +#ifdef CONFIG_PAX_USERCOPY
44571 + if (size + c->align < PAGE_SIZE) {
44572 + size += c->align;
44573 + b -= c->align;
44574 + }
44575 +#endif
44576 +
44577 kmemleak_free_recursive(b, c->flags);
44578 if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {
44579 struct slob_rcu *slob_rcu;
44580 - slob_rcu = b + (c->size - sizeof(struct slob_rcu));
44581 + slob_rcu = b + (size - sizeof(struct slob_rcu));
44582 INIT_RCU_HEAD(&slob_rcu->head);
44583 - slob_rcu->size = c->size;
44584 + slob_rcu->size = size;
44585 call_rcu(&slob_rcu->head, kmem_rcu_free);
44586 } else {
44587 - __kmem_cache_free(b, c->size);
44588 + __kmem_cache_free(b, size);
44589 }
44590
44591 trace_kmem_cache_free(_RET_IP_, b);
44592 diff -urNp linux-2.6.31.1/mm/slub.c linux-2.6.31.1/mm/slub.c
44593 --- linux-2.6.31.1/mm/slub.c 2009-09-24 11:45:25.000000000 -0400
44594 +++ linux-2.6.31.1/mm/slub.c 2009-10-01 20:12:45.000000000 -0400
44595 @@ -1915,7 +1915,7 @@ static int slub_min_objects;
44596 * Merge control. If this is set then no merging of slab caches will occur.
44597 * (Could be removed. This was introduced to pacify the merge skeptics.)
44598 */
44599 -static int slub_nomerge;
44600 +static int slub_nomerge = 1;
44601
44602 /*
44603 * Calculate the order of allocation given an slab object size.
44604 @@ -2458,7 +2458,7 @@ static int kmem_cache_open(struct kmem_c
44605 * list to avoid pounding the page allocator excessively.
44606 */
44607 set_min_partial(s, ilog2(s->size));
44608 - s->refcount = 1;
44609 + atomic_set(&s->refcount, 1);
44610 #ifdef CONFIG_NUMA
44611 s->remote_node_defrag_ratio = 1000;
44612 #endif
44613 @@ -2595,8 +2595,7 @@ static inline int kmem_cache_close(struc
44614 void kmem_cache_destroy(struct kmem_cache *s)
44615 {
44616 down_write(&slub_lock);
44617 - s->refcount--;
44618 - if (!s->refcount) {
44619 + if (atomic_dec_and_test(&s->refcount)) {
44620 list_del(&s->list);
44621 up_write(&slub_lock);
44622 if (kmem_cache_close(s)) {
44623 @@ -2875,6 +2874,48 @@ void *__kmalloc_node(size_t size, gfp_t
44624 EXPORT_SYMBOL(__kmalloc_node);
44625 #endif
44626
44627 +void check_object_size(const void *ptr, unsigned long n, bool to)
44628 +{
44629 +
44630 +#ifdef CONFIG_PAX_USERCOPY
44631 + struct page *page;
44632 + struct kmem_cache *s;
44633 + unsigned long offset;
44634 +
44635 + if (!n)
44636 + return;
44637 +
44638 + if (ZERO_OR_NULL_PTR(ptr))
44639 + goto report;
44640 +
44641 + if (!virt_addr_valid(ptr))
44642 + return;
44643 +
44644 + page = get_object_page(ptr);
44645 +
44646 + /* XXX: can get a little tighter with this stack check */
44647 + if (!page && object_is_on_stack(ptr) &&
44648 + (n > ((unsigned long)task_stack_page(current) + THREAD_SIZE -
44649 + (unsigned long)ptr)))
44650 + goto report;
44651 + else
44652 + return;
44653 +
44654 + s = page->slab;
44655 + offset = (ptr - page_address(page)) % s->size;
44656 + if (offset <= s->objsize && n <= s->objsize - offset)
44657 + return;
44658 +
44659 +report:
44660 + if (to)
44661 + pax_report_leak_to_user(ptr, n);
44662 + else
44663 + pax_report_overflow_from_user(ptr, n);
44664 +#endif
44665 +
44666 +}
44667 +EXPORT_SYMBOL(check_object_size);
44668 +
44669 size_t ksize(const void *object)
44670 {
44671 struct page *page;
44672 @@ -3146,7 +3187,7 @@ void __init kmem_cache_init(void)
44673 */
44674 create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node",
44675 sizeof(struct kmem_cache_node), GFP_NOWAIT);
44676 - kmalloc_caches[0].refcount = -1;
44677 + atomic_set(&kmalloc_caches[0].refcount, -1);
44678 caches++;
44679
44680 hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI);
44681 @@ -3240,7 +3281,7 @@ static int slab_unmergeable(struct kmem_
44682 /*
44683 * We may have set a slab to be unmergeable during bootstrap.
44684 */
44685 - if (s->refcount < 0)
44686 + if (atomic_read(&s->refcount) < 0)
44687 return 1;
44688
44689 return 0;
44690 @@ -3297,7 +3338,7 @@ struct kmem_cache *kmem_cache_create(con
44691 if (s) {
44692 int cpu;
44693
44694 - s->refcount++;
44695 + atomic_inc(&s->refcount);
44696 /*
44697 * Adjust the object sizes so that we clear
44698 * the complete object on kzalloc.
44699 @@ -3316,7 +3357,7 @@ struct kmem_cache *kmem_cache_create(con
44700
44701 if (sysfs_slab_alias(s, name)) {
44702 down_write(&slub_lock);
44703 - s->refcount--;
44704 + atomic_dec(&s->refcount);
44705 up_write(&slub_lock);
44706 goto err;
44707 }
44708 @@ -4045,7 +4086,7 @@ SLAB_ATTR_RO(ctor);
44709
44710 static ssize_t aliases_show(struct kmem_cache *s, char *buf)
44711 {
44712 - return sprintf(buf, "%d\n", s->refcount - 1);
44713 + return sprintf(buf, "%d\n", atomic_read(&s->refcount) - 1);
44714 }
44715 SLAB_ATTR_RO(aliases);
44716
44717 @@ -4726,7 +4767,9 @@ static const struct file_operations proc
44718
44719 static int __init slab_proc_init(void)
44720 {
44721 +#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
44722 proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
44723 +#endif
44724 return 0;
44725 }
44726 module_init(slab_proc_init);
44727 diff -urNp linux-2.6.31.1/mm/util.c linux-2.6.31.1/mm/util.c
44728 --- linux-2.6.31.1/mm/util.c 2009-09-24 11:45:25.000000000 -0400
44729 +++ linux-2.6.31.1/mm/util.c 2009-10-01 20:12:45.000000000 -0400
44730 @@ -224,6 +224,12 @@ EXPORT_SYMBOL(strndup_user);
44731 void arch_pick_mmap_layout(struct mm_struct *mm)
44732 {
44733 mm->mmap_base = TASK_UNMAPPED_BASE;
44734 +
44735 +#ifdef CONFIG_PAX_RANDMMAP
44736 + if (mm->pax_flags & MF_PAX_RANDMMAP)
44737 + mm->mmap_base += mm->delta_mmap;
44738 +#endif
44739 +
44740 mm->get_unmapped_area = arch_get_unmapped_area;
44741 mm->unmap_area = arch_unmap_area;
44742 }
44743 diff -urNp linux-2.6.31.1/mm/vmalloc.c linux-2.6.31.1/mm/vmalloc.c
44744 --- linux-2.6.31.1/mm/vmalloc.c 2009-09-24 11:45:25.000000000 -0400
44745 +++ linux-2.6.31.1/mm/vmalloc.c 2009-10-01 20:12:45.000000000 -0400
44746 @@ -91,6 +91,11 @@ static int vmap_pte_range(pmd_t *pmd, un
44747 unsigned long end, pgprot_t prot, struct page **pages, int *nr)
44748 {
44749 pte_t *pte;
44750 + int ret = -ENOMEM;
44751 +
44752 +#ifdef CONFIG_PAX_KERNEXEC
44753 + unsigned long cr0;
44754 +#endif
44755
44756 /*
44757 * nr is a running index into the array which helps higher level
44758 @@ -100,17 +105,33 @@ static int vmap_pte_range(pmd_t *pmd, un
44759 pte = pte_alloc_kernel(pmd, addr);
44760 if (!pte)
44761 return -ENOMEM;
44762 +
44763 +#ifdef CONFIG_PAX_KERNEXEC
44764 + pax_open_kernel(cr0);
44765 +#endif
44766 +
44767 do {
44768 struct page *page = pages[*nr];
44769
44770 - if (WARN_ON(!pte_none(*pte)))
44771 - return -EBUSY;
44772 - if (WARN_ON(!page))
44773 - return -ENOMEM;
44774 + if (WARN_ON(!pte_none(*pte))) {
44775 + ret = -EBUSY;
44776 + goto out;
44777 + }
44778 + if (WARN_ON(!page)) {
44779 + ret = -ENOMEM;
44780 + goto out;
44781 + }
44782 set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
44783 (*nr)++;
44784 } while (pte++, addr += PAGE_SIZE, addr != end);
44785 - return 0;
44786 + ret = 0;
44787 +out:
44788 +
44789 +#ifdef CONFIG_PAX_KERNEXEC
44790 + pax_close_kernel(cr0);
44791 +#endif
44792 +
44793 + return ret;
44794 }
44795
44796 static int vmap_pmd_range(pud_t *pud, unsigned long addr,
44797 @@ -1132,6 +1153,16 @@ static struct vm_struct *__get_vm_area_n
44798 unsigned long align = 1;
44799
44800 BUG_ON(in_interrupt());
44801 +
44802 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
44803 + if (flags & VM_KERNEXEC) {
44804 + if (start != VMALLOC_START || end != VMALLOC_END)
44805 + return NULL;
44806 + start = (unsigned long)&MODULES_EXEC_VADDR;
44807 + end = (unsigned long)&MODULES_EXEC_END;
44808 + }
44809 +#endif
44810 +
44811 if (flags & VM_IOREMAP) {
44812 int bit = fls(size);
44813
44814 @@ -1371,6 +1402,11 @@ void *vmap(struct page **pages, unsigned
44815 if (count > num_physpages)
44816 return NULL;
44817
44818 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
44819 + if (!(pgprot_val(prot) & _PAGE_NX))
44820 + flags |= VM_KERNEXEC;
44821 +#endif
44822 +
44823 area = get_vm_area_caller((count << PAGE_SHIFT), flags,
44824 __builtin_return_address(0));
44825 if (!area)
44826 @@ -1478,6 +1514,13 @@ static void *__vmalloc_node(unsigned lon
44827 if (!size || (size >> PAGE_SHIFT) > num_physpages)
44828 return NULL;
44829
44830 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
44831 + if (!(pgprot_val(prot) & _PAGE_NX))
44832 + area = __get_vm_area_node(size, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
44833 + node, gfp_mask, caller);
44834 + else
44835 +#endif
44836 +
44837 area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
44838 node, gfp_mask, caller);
44839
44840 @@ -1496,6 +1539,7 @@ static void *__vmalloc_node(unsigned lon
44841 return addr;
44842 }
44843
44844 +#undef __vmalloc
44845 void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
44846 {
44847 return __vmalloc_node(size, gfp_mask, prot, -1,
44848 @@ -1512,6 +1556,7 @@ EXPORT_SYMBOL(__vmalloc);
44849 * For tight control over page level allocator and protection flags
44850 * use __vmalloc() instead.
44851 */
44852 +#undef vmalloc
44853 void *vmalloc(unsigned long size)
44854 {
44855 return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
44856 @@ -1526,6 +1571,7 @@ EXPORT_SYMBOL(vmalloc);
44857 * The resulting memory area is zeroed so it can be mapped to userspace
44858 * without leaking data.
44859 */
44860 +#undef vmalloc_user
44861 void *vmalloc_user(unsigned long size)
44862 {
44863 struct vm_struct *area;
44864 @@ -1552,6 +1598,7 @@ EXPORT_SYMBOL(vmalloc_user);
44865 * For tight control over page level allocator and protection flags
44866 * use __vmalloc() instead.
44867 */
44868 +#undef vmalloc_node
44869 void *vmalloc_node(unsigned long size, int node)
44870 {
44871 return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
44872 @@ -1574,10 +1621,10 @@ EXPORT_SYMBOL(vmalloc_node);
44873 * For tight control over page level allocator and protection flags
44874 * use __vmalloc() instead.
44875 */
44876 -
44877 +#undef vmalloc_exec
44878 void *vmalloc_exec(unsigned long size)
44879 {
44880 - return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
44881 + return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC,
44882 -1, __builtin_return_address(0));
44883 }
44884
44885 @@ -1596,6 +1643,7 @@ void *vmalloc_exec(unsigned long size)
44886 * Allocate enough 32bit PA addressable pages to cover @size from the
44887 * page level allocator and map them into contiguous kernel virtual space.
44888 */
44889 +#undef vmalloc_32
44890 void *vmalloc_32(unsigned long size)
44891 {
44892 return __vmalloc_node(size, GFP_VMALLOC32, PAGE_KERNEL,
44893 @@ -1610,6 +1658,7 @@ EXPORT_SYMBOL(vmalloc_32);
44894 * The resulting memory area is 32bit addressable and zeroed so it can be
44895 * mapped to userspace without leaking data.
44896 */
44897 +#undef vmalloc_32_user
44898 void *vmalloc_32_user(unsigned long size)
44899 {
44900 struct vm_struct *area;
44901 diff -urNp linux-2.6.31.1/net/atm/atm_misc.c linux-2.6.31.1/net/atm/atm_misc.c
44902 --- linux-2.6.31.1/net/atm/atm_misc.c 2009-09-24 11:45:25.000000000 -0400
44903 +++ linux-2.6.31.1/net/atm/atm_misc.c 2009-10-01 20:12:45.000000000 -0400
44904 @@ -19,7 +19,7 @@ int atm_charge(struct atm_vcc *vcc,int t
44905 if (atomic_read(&sk_atm(vcc)->sk_rmem_alloc) <= sk_atm(vcc)->sk_rcvbuf)
44906 return 1;
44907 atm_return(vcc,truesize);
44908 - atomic_inc(&vcc->stats->rx_drop);
44909 + atomic_inc_unchecked(&vcc->stats->rx_drop);
44910 return 0;
44911 }
44912
44913 @@ -41,7 +41,7 @@ struct sk_buff *atm_alloc_charge(struct
44914 }
44915 }
44916 atm_return(vcc,guess);
44917 - atomic_inc(&vcc->stats->rx_drop);
44918 + atomic_inc_unchecked(&vcc->stats->rx_drop);
44919 return NULL;
44920 }
44921
44922 @@ -88,7 +88,7 @@ int atm_pcr_goal(const struct atm_trafpr
44923
44924 void sonet_copy_stats(struct k_sonet_stats *from,struct sonet_stats *to)
44925 {
44926 -#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
44927 +#define __HANDLE_ITEM(i) to->i = atomic_read_unchecked(&from->i)
44928 __SONET_ITEMS
44929 #undef __HANDLE_ITEM
44930 }
44931 @@ -96,7 +96,7 @@ void sonet_copy_stats(struct k_sonet_sta
44932
44933 void sonet_subtract_stats(struct k_sonet_stats *from,struct sonet_stats *to)
44934 {
44935 -#define __HANDLE_ITEM(i) atomic_sub(to->i,&from->i)
44936 +#define __HANDLE_ITEM(i) atomic_sub_unchecked(to->i,&from->i)
44937 __SONET_ITEMS
44938 #undef __HANDLE_ITEM
44939 }
44940 diff -urNp linux-2.6.31.1/net/atm/proc.c linux-2.6.31.1/net/atm/proc.c
44941 --- linux-2.6.31.1/net/atm/proc.c 2009-09-24 11:45:25.000000000 -0400
44942 +++ linux-2.6.31.1/net/atm/proc.c 2009-10-01 20:12:45.000000000 -0400
44943 @@ -43,9 +43,9 @@ static void add_stats(struct seq_file *s
44944 const struct k_atm_aal_stats *stats)
44945 {
44946 seq_printf(seq, "%s ( %d %d %d %d %d )", aal,
44947 - atomic_read(&stats->tx),atomic_read(&stats->tx_err),
44948 - atomic_read(&stats->rx),atomic_read(&stats->rx_err),
44949 - atomic_read(&stats->rx_drop));
44950 + atomic_read_unchecked(&stats->tx),atomic_read_unchecked(&stats->tx_err),
44951 + atomic_read_unchecked(&stats->rx),atomic_read_unchecked(&stats->rx_err),
44952 + atomic_read_unchecked(&stats->rx_drop));
44953 }
44954
44955 static void atm_dev_info(struct seq_file *seq, const struct atm_dev *dev)
44956 diff -urNp linux-2.6.31.1/net/atm/resources.c linux-2.6.31.1/net/atm/resources.c
44957 --- linux-2.6.31.1/net/atm/resources.c 2009-09-24 11:45:25.000000000 -0400
44958 +++ linux-2.6.31.1/net/atm/resources.c 2009-10-01 20:12:45.000000000 -0400
44959 @@ -161,7 +161,7 @@ void atm_dev_deregister(struct atm_dev *
44960 static void copy_aal_stats(struct k_atm_aal_stats *from,
44961 struct atm_aal_stats *to)
44962 {
44963 -#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
44964 +#define __HANDLE_ITEM(i) to->i = atomic_read_unchecked(&from->i)
44965 __AAL_STAT_ITEMS
44966 #undef __HANDLE_ITEM
44967 }
44968 @@ -170,7 +170,7 @@ static void copy_aal_stats(struct k_atm_
44969 static void subtract_aal_stats(struct k_atm_aal_stats *from,
44970 struct atm_aal_stats *to)
44971 {
44972 -#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
44973 +#define __HANDLE_ITEM(i) atomic_sub_unchecked(to->i, &from->i)
44974 __AAL_STAT_ITEMS
44975 #undef __HANDLE_ITEM
44976 }
44977 diff -urNp linux-2.6.31.1/net/bridge/br_stp_if.c linux-2.6.31.1/net/bridge/br_stp_if.c
44978 --- linux-2.6.31.1/net/bridge/br_stp_if.c 2009-09-24 11:45:25.000000000 -0400
44979 +++ linux-2.6.31.1/net/bridge/br_stp_if.c 2009-10-01 20:12:45.000000000 -0400
44980 @@ -146,7 +146,7 @@ static void br_stp_stop(struct net_bridg
44981 char *envp[] = { NULL };
44982
44983 if (br->stp_enabled == BR_USER_STP) {
44984 - r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
44985 + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
44986 printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
44987 br->dev->name, r);
44988
44989 diff -urNp linux-2.6.31.1/net/core/flow.c linux-2.6.31.1/net/core/flow.c
44990 --- linux-2.6.31.1/net/core/flow.c 2009-09-24 11:45:25.000000000 -0400
44991 +++ linux-2.6.31.1/net/core/flow.c 2009-10-01 20:12:45.000000000 -0400
44992 @@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
44993
44994 static u32 flow_hash_shift;
44995 #define flow_hash_size (1 << flow_hash_shift)
44996 -static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
44997 +static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
44998
44999 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
45000
45001 @@ -52,7 +52,7 @@ struct flow_percpu_info {
45002 u32 hash_rnd;
45003 int count;
45004 };
45005 -static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
45006 +static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
45007
45008 #define flow_hash_rnd_recalc(cpu) \
45009 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
45010 @@ -69,7 +69,7 @@ struct flow_flush_info {
45011 atomic_t cpuleft;
45012 struct completion completion;
45013 };
45014 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
45015 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
45016
45017 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
45018
45019 diff -urNp linux-2.6.31.1/net/dccp/ccids/ccid3.c linux-2.6.31.1/net/dccp/ccids/ccid3.c
45020 --- linux-2.6.31.1/net/dccp/ccids/ccid3.c 2009-09-24 11:45:25.000000000 -0400
45021 +++ linux-2.6.31.1/net/dccp/ccids/ccid3.c 2009-10-01 20:12:45.000000000 -0400
45022 @@ -43,7 +43,7 @@
45023 static int ccid3_debug;
45024 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
45025 #else
45026 -#define ccid3_pr_debug(format, a...)
45027 +#define ccid3_pr_debug(format, a...) do {} while (0)
45028 #endif
45029
45030 /*
45031 diff -urNp linux-2.6.31.1/net/dccp/dccp.h linux-2.6.31.1/net/dccp/dccp.h
45032 --- linux-2.6.31.1/net/dccp/dccp.h 2009-09-24 11:45:25.000000000 -0400
45033 +++ linux-2.6.31.1/net/dccp/dccp.h 2009-10-01 20:12:45.000000000 -0400
45034 @@ -44,9 +44,9 @@ extern int dccp_debug;
45035 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
45036 #define dccp_debug(fmt, a...) dccp_pr_debug_cat(KERN_DEBUG fmt, ##a)
45037 #else
45038 -#define dccp_pr_debug(format, a...)
45039 -#define dccp_pr_debug_cat(format, a...)
45040 -#define dccp_debug(format, a...)
45041 +#define dccp_pr_debug(format, a...) do {} while (0)
45042 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
45043 +#define dccp_debug(format, a...) do {} while (0)
45044 #endif
45045
45046 extern struct inet_hashinfo dccp_hashinfo;
45047 diff -urNp linux-2.6.31.1/net/ipv4/inet_hashtables.c linux-2.6.31.1/net/ipv4/inet_hashtables.c
45048 --- linux-2.6.31.1/net/ipv4/inet_hashtables.c 2009-09-24 11:45:25.000000000 -0400
45049 +++ linux-2.6.31.1/net/ipv4/inet_hashtables.c 2009-10-01 20:12:45.000000000 -0400
45050 @@ -18,11 +18,14 @@
45051 #include <linux/sched.h>
45052 #include <linux/slab.h>
45053 #include <linux/wait.h>
45054 +#include <linux/security.h>
45055
45056 #include <net/inet_connection_sock.h>
45057 #include <net/inet_hashtables.h>
45058 #include <net/ip.h>
45059
45060 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
45061 +
45062 /*
45063 * Allocate and initialize a new local port bind bucket.
45064 * The bindhash mutex for snum's hash chain must be held here.
45065 @@ -490,6 +493,8 @@ ok:
45066 }
45067 spin_unlock(&head->lock);
45068
45069 + gr_update_task_in_ip_table(current, inet_sk(sk));
45070 +
45071 if (tw) {
45072 inet_twsk_deschedule(tw, death_row);
45073 inet_twsk_put(tw);
45074 diff -urNp linux-2.6.31.1/net/ipv4/netfilter/nf_nat_snmp_basic.c linux-2.6.31.1/net/ipv4/netfilter/nf_nat_snmp_basic.c
45075 --- linux-2.6.31.1/net/ipv4/netfilter/nf_nat_snmp_basic.c 2009-09-24 11:45:25.000000000 -0400
45076 +++ linux-2.6.31.1/net/ipv4/netfilter/nf_nat_snmp_basic.c 2009-10-01 20:12:45.000000000 -0400
45077 @@ -397,7 +397,7 @@ static unsigned char asn1_octets_decode(
45078
45079 *len = 0;
45080
45081 - *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
45082 + *octets = kmalloc((eoc - ctx->pointer), GFP_ATOMIC);
45083 if (*octets == NULL) {
45084 if (net_ratelimit())
45085 printk("OOM in bsalg (%d)\n", __LINE__);
45086 diff -urNp linux-2.6.31.1/net/ipv4/tcp_ipv4.c linux-2.6.31.1/net/ipv4/tcp_ipv4.c
45087 --- linux-2.6.31.1/net/ipv4/tcp_ipv4.c 2009-09-24 11:45:25.000000000 -0400
45088 +++ linux-2.6.31.1/net/ipv4/tcp_ipv4.c 2009-10-01 20:12:45.000000000 -0400
45089 @@ -1504,6 +1504,9 @@ int tcp_v4_do_rcv(struct sock *sk, struc
45090 return 0;
45091
45092 reset:
45093 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
45094 + if (!skb->dev || (skb->dev->flags & IFF_LOOPBACK))
45095 +#endif
45096 tcp_v4_send_reset(rsk, skb);
45097 discard:
45098 kfree_skb(skb);
45099 @@ -1612,6 +1615,9 @@ no_tcp_socket:
45100 bad_packet:
45101 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
45102 } else {
45103 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
45104 + if (skb->dev->flags & IFF_LOOPBACK)
45105 +#endif
45106 tcp_v4_send_reset(NULL, skb);
45107 }
45108
45109 diff -urNp linux-2.6.31.1/net/ipv4/tcp_minisocks.c linux-2.6.31.1/net/ipv4/tcp_minisocks.c
45110 --- linux-2.6.31.1/net/ipv4/tcp_minisocks.c 2009-09-24 11:45:25.000000000 -0400
45111 +++ linux-2.6.31.1/net/ipv4/tcp_minisocks.c 2009-10-01 20:12:45.000000000 -0400
45112 @@ -695,8 +695,11 @@ listen_overflow:
45113
45114 embryonic_reset:
45115 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS);
45116 +
45117 +#ifndef CONFIG_GRKERNSEC_BLACKHOLE
45118 if (!(flg & TCP_FLAG_RST))
45119 req->rsk_ops->send_reset(sk, skb);
45120 +#endif
45121
45122 inet_csk_reqsk_queue_drop(sk, req, prev);
45123 return NULL;
45124 diff -urNp linux-2.6.31.1/net/ipv4/udp.c linux-2.6.31.1/net/ipv4/udp.c
45125 --- linux-2.6.31.1/net/ipv4/udp.c 2009-09-24 11:45:25.000000000 -0400
45126 +++ linux-2.6.31.1/net/ipv4/udp.c 2009-10-01 20:12:45.000000000 -0400
45127 @@ -86,6 +86,7 @@
45128 #include <linux/types.h>
45129 #include <linux/fcntl.h>
45130 #include <linux/module.h>
45131 +#include <linux/security.h>
45132 #include <linux/socket.h>
45133 #include <linux/sockios.h>
45134 #include <linux/igmp.h>
45135 @@ -369,6 +370,9 @@ found:
45136 return s;
45137 }
45138
45139 +extern int gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb);
45140 +extern int gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr);
45141 +
45142 /*
45143 * This routine is called by the ICMP module when it gets some
45144 * sort of error condition. If err < 0 then the socket should
45145 @@ -631,9 +635,18 @@ int udp_sendmsg(struct kiocb *iocb, stru
45146 dport = usin->sin_port;
45147 if (dport == 0)
45148 return -EINVAL;
45149 +
45150 + err = gr_search_udp_sendmsg(sk, usin);
45151 + if (err)
45152 + return err;
45153 } else {
45154 if (sk->sk_state != TCP_ESTABLISHED)
45155 return -EDESTADDRREQ;
45156 +
45157 + err = gr_search_udp_sendmsg(sk, NULL);
45158 + if (err)
45159 + return err;
45160 +
45161 daddr = inet->daddr;
45162 dport = inet->dport;
45163 /* Open fast path for connected socket.
45164 @@ -903,6 +916,10 @@ try_again:
45165 if (!skb)
45166 goto out;
45167
45168 + err = gr_search_udp_recvmsg(sk, skb);
45169 + if (err)
45170 + goto out_free;
45171 +
45172 ulen = skb->len - sizeof(struct udphdr);
45173 copied = len;
45174 if (copied > ulen)
45175 @@ -1293,6 +1310,9 @@ int __udp4_lib_rcv(struct sk_buff *skb,
45176 goto csum_error;
45177
45178 UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
45179 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
45180 + if (skb->dev->flags & IFF_LOOPBACK)
45181 +#endif
45182 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
45183
45184 /*
45185 diff -urNp linux-2.6.31.1/net/ipv6/exthdrs.c linux-2.6.31.1/net/ipv6/exthdrs.c
45186 --- linux-2.6.31.1/net/ipv6/exthdrs.c 2009-09-24 11:45:25.000000000 -0400
45187 +++ linux-2.6.31.1/net/ipv6/exthdrs.c 2009-10-01 20:12:45.000000000 -0400
45188 @@ -630,7 +630,7 @@ static struct tlvtype_proc tlvprochopopt
45189 .type = IPV6_TLV_JUMBO,
45190 .func = ipv6_hop_jumbo,
45191 },
45192 - { -1, }
45193 + { -1, NULL }
45194 };
45195
45196 int ipv6_parse_hopopts(struct sk_buff *skb)
45197 diff -urNp linux-2.6.31.1/net/ipv6/ip6mr.c linux-2.6.31.1/net/ipv6/ip6mr.c
45198 --- linux-2.6.31.1/net/ipv6/ip6mr.c 2009-09-24 11:45:25.000000000 -0400
45199 +++ linux-2.6.31.1/net/ipv6/ip6mr.c 2009-10-01 20:12:45.000000000 -0400
45200 @@ -204,7 +204,7 @@ static int ip6mr_vif_seq_show(struct seq
45201 return 0;
45202 }
45203
45204 -static struct seq_operations ip6mr_vif_seq_ops = {
45205 +static const struct seq_operations ip6mr_vif_seq_ops = {
45206 .start = ip6mr_vif_seq_start,
45207 .next = ip6mr_vif_seq_next,
45208 .stop = ip6mr_vif_seq_stop,
45209 @@ -217,7 +217,7 @@ static int ip6mr_vif_open(struct inode *
45210 sizeof(struct ipmr_vif_iter));
45211 }
45212
45213 -static struct file_operations ip6mr_vif_fops = {
45214 +static const struct file_operations ip6mr_vif_fops = {
45215 .owner = THIS_MODULE,
45216 .open = ip6mr_vif_open,
45217 .read = seq_read,
45218 @@ -328,7 +328,7 @@ static int ipmr_mfc_seq_show(struct seq_
45219 return 0;
45220 }
45221
45222 -static struct seq_operations ipmr_mfc_seq_ops = {
45223 +static const struct seq_operations ipmr_mfc_seq_ops = {
45224 .start = ipmr_mfc_seq_start,
45225 .next = ipmr_mfc_seq_next,
45226 .stop = ipmr_mfc_seq_stop,
45227 @@ -341,7 +341,7 @@ static int ipmr_mfc_open(struct inode *i
45228 sizeof(struct ipmr_mfc_iter));
45229 }
45230
45231 -static struct file_operations ip6mr_mfc_fops = {
45232 +static const struct file_operations ip6mr_mfc_fops = {
45233 .owner = THIS_MODULE,
45234 .open = ipmr_mfc_open,
45235 .read = seq_read,
45236 diff -urNp linux-2.6.31.1/net/ipv6/raw.c linux-2.6.31.1/net/ipv6/raw.c
45237 --- linux-2.6.31.1/net/ipv6/raw.c 2009-09-24 11:45:25.000000000 -0400
45238 +++ linux-2.6.31.1/net/ipv6/raw.c 2009-10-01 20:12:45.000000000 -0400
45239 @@ -600,7 +600,7 @@ out:
45240 return err;
45241 }
45242
45243 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
45244 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
45245 struct flowi *fl, struct rt6_info *rt,
45246 unsigned int flags)
45247 {
45248 diff -urNp linux-2.6.31.1/net/ipv6/tcp_ipv6.c linux-2.6.31.1/net/ipv6/tcp_ipv6.c
45249 --- linux-2.6.31.1/net/ipv6/tcp_ipv6.c 2009-09-24 11:45:25.000000000 -0400
45250 +++ linux-2.6.31.1/net/ipv6/tcp_ipv6.c 2009-10-01 20:12:45.000000000 -0400
45251 @@ -1577,6 +1577,9 @@ static int tcp_v6_do_rcv(struct sock *sk
45252 return 0;
45253
45254 reset:
45255 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
45256 + if (!skb->dev || (skb->dev->flags & IFF_LOOPBACK))
45257 +#endif
45258 tcp_v6_send_reset(sk, skb);
45259 discard:
45260 if (opt_skb)
45261 @@ -1699,6 +1702,9 @@ no_tcp_socket:
45262 bad_packet:
45263 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
45264 } else {
45265 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
45266 + if (skb->dev->flags & IFF_LOOPBACK)
45267 +#endif
45268 tcp_v6_send_reset(NULL, skb);
45269 }
45270
45271 diff -urNp linux-2.6.31.1/net/ipv6/udp.c linux-2.6.31.1/net/ipv6/udp.c
45272 --- linux-2.6.31.1/net/ipv6/udp.c 2009-09-24 11:45:25.000000000 -0400
45273 +++ linux-2.6.31.1/net/ipv6/udp.c 2009-10-01 20:12:45.000000000 -0400
45274 @@ -589,6 +589,9 @@ int __udp6_lib_rcv(struct sk_buff *skb,
45275 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS,
45276 proto == IPPROTO_UDPLITE);
45277
45278 +#ifdef CONFIG_GRKERNSEC_BLACKHOLE
45279 + if (skb->dev->flags & IFF_LOOPBACK)
45280 +#endif
45281 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
45282
45283 kfree_skb(skb);
45284 diff -urNp linux-2.6.31.1/net/irda/ircomm/ircomm_tty.c linux-2.6.31.1/net/irda/ircomm/ircomm_tty.c
45285 --- linux-2.6.31.1/net/irda/ircomm/ircomm_tty.c 2009-09-24 11:45:25.000000000 -0400
45286 +++ linux-2.6.31.1/net/irda/ircomm/ircomm_tty.c 2009-10-01 20:12:45.000000000 -0400
45287 @@ -280,16 +280,16 @@ static int ircomm_tty_block_til_ready(st
45288 add_wait_queue(&self->open_wait, &wait);
45289
45290 IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
45291 - __FILE__,__LINE__, tty->driver->name, self->open_count );
45292 + __FILE__,__LINE__, tty->driver->name, atomic_read(&self->open_count) );
45293
45294 /* As far as I can see, we protect open_count - Jean II */
45295 spin_lock_irqsave(&self->spinlock, flags);
45296 if (!tty_hung_up_p(filp)) {
45297 extra_count = 1;
45298 - self->open_count--;
45299 + atomic_dec(&self->open_count);
45300 }
45301 spin_unlock_irqrestore(&self->spinlock, flags);
45302 - self->blocked_open++;
45303 + atomic_inc(&self->blocked_open);
45304
45305 while (1) {
45306 if (tty->termios->c_cflag & CBAUD) {
45307 @@ -329,7 +329,7 @@ static int ircomm_tty_block_til_ready(st
45308 }
45309
45310 IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
45311 - __FILE__,__LINE__, tty->driver->name, self->open_count );
45312 + __FILE__,__LINE__, tty->driver->name, atomic_read(&self->open_count) );
45313
45314 schedule();
45315 }
45316 @@ -340,13 +340,13 @@ static int ircomm_tty_block_til_ready(st
45317 if (extra_count) {
45318 /* ++ is not atomic, so this should be protected - Jean II */
45319 spin_lock_irqsave(&self->spinlock, flags);
45320 - self->open_count++;
45321 + atomic_inc(&self->open_count);
45322 spin_unlock_irqrestore(&self->spinlock, flags);
45323 }
45324 - self->blocked_open--;
45325 + atomic_dec(&self->blocked_open);
45326
45327 IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
45328 - __FILE__,__LINE__, tty->driver->name, self->open_count);
45329 + __FILE__,__LINE__, tty->driver->name, atomic_read(&self->open_count));
45330
45331 if (!retval)
45332 self->flags |= ASYNC_NORMAL_ACTIVE;
45333 @@ -415,14 +415,14 @@ static int ircomm_tty_open(struct tty_st
45334 }
45335 /* ++ is not atomic, so this should be protected - Jean II */
45336 spin_lock_irqsave(&self->spinlock, flags);
45337 - self->open_count++;
45338 + atomic_inc(&self->open_count);
45339
45340 tty->driver_data = self;
45341 self->tty = tty;
45342 spin_unlock_irqrestore(&self->spinlock, flags);
45343
45344 IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name,
45345 - self->line, self->open_count);
45346 + self->line, atomic_read(&self->open_count));
45347
45348 /* Not really used by us, but lets do it anyway */
45349 self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
45350 @@ -511,7 +511,7 @@ static void ircomm_tty_close(struct tty_
45351 return;
45352 }
45353
45354 - if ((tty->count == 1) && (self->open_count != 1)) {
45355 + if ((tty->count == 1) && (atomic_read(&self->open_count) != 1)) {
45356 /*
45357 * Uh, oh. tty->count is 1, which means that the tty
45358 * structure will be freed. state->count should always
45359 @@ -521,16 +521,16 @@ static void ircomm_tty_close(struct tty_
45360 */
45361 IRDA_DEBUG(0, "%s(), bad serial port count; "
45362 "tty->count is 1, state->count is %d\n", __func__ ,
45363 - self->open_count);
45364 - self->open_count = 1;
45365 + atomic_read(&self->open_count));
45366 + atomic_set(&self->open_count, 1);
45367 }
45368
45369 - if (--self->open_count < 0) {
45370 + if (atomic_dec_return(&self->open_count) < 0) {
45371 IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
45372 - __func__, self->line, self->open_count);
45373 - self->open_count = 0;
45374 + __func__, self->line, atomic_read(&self->open_count));
45375 + atomic_set(&self->open_count, 0);
45376 }
45377 - if (self->open_count) {
45378 + if (atomic_read(&self->open_count)) {
45379 spin_unlock_irqrestore(&self->spinlock, flags);
45380
45381 IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ );
45382 @@ -562,7 +562,7 @@ static void ircomm_tty_close(struct tty_
45383 tty->closing = 0;
45384 self->tty = NULL;
45385
45386 - if (self->blocked_open) {
45387 + if (atomic_read(&self->blocked_open)) {
45388 if (self->close_delay)
45389 schedule_timeout_interruptible(self->close_delay);
45390 wake_up_interruptible(&self->open_wait);
45391 @@ -1017,7 +1017,7 @@ static void ircomm_tty_hangup(struct tty
45392 spin_lock_irqsave(&self->spinlock, flags);
45393 self->flags &= ~ASYNC_NORMAL_ACTIVE;
45394 self->tty = NULL;
45395 - self->open_count = 0;
45396 + atomic_set(&self->open_count, 0);
45397 spin_unlock_irqrestore(&self->spinlock, flags);
45398
45399 wake_up_interruptible(&self->open_wait);
45400 @@ -1369,7 +1369,7 @@ static void ircomm_tty_line_info(struct
45401 seq_putc(m, '\n');
45402
45403 seq_printf(m, "Role: %s\n", self->client ? "client" : "server");
45404 - seq_printf(m, "Open count: %d\n", self->open_count);
45405 + seq_printf(m, "Open count: %d\n", atomic_read(&self->open_count));
45406 seq_printf(m, "Max data size: %d\n", self->max_data_size);
45407 seq_printf(m, "Max header size: %d\n", self->max_header_size);
45408
45409 diff -urNp linux-2.6.31.1/net/key/af_key.c linux-2.6.31.1/net/key/af_key.c
45410 --- linux-2.6.31.1/net/key/af_key.c 2009-09-24 11:45:25.000000000 -0400
45411 +++ linux-2.6.31.1/net/key/af_key.c 2009-10-01 20:12:45.000000000 -0400
45412 @@ -3705,7 +3705,7 @@ static void pfkey_seq_stop(struct seq_fi
45413 read_unlock(&pfkey_table_lock);
45414 }
45415
45416 -static struct seq_operations pfkey_seq_ops = {
45417 +static const struct seq_operations pfkey_seq_ops = {
45418 .start = pfkey_seq_start,
45419 .next = pfkey_seq_next,
45420 .stop = pfkey_seq_stop,
45421 @@ -3718,7 +3718,7 @@ static int pfkey_seq_open(struct inode *
45422 sizeof(struct seq_net_private));
45423 }
45424
45425 -static struct file_operations pfkey_proc_ops = {
45426 +static const struct file_operations pfkey_proc_ops = {
45427 .open = pfkey_seq_open,
45428 .read = seq_read,
45429 .llseek = seq_lseek,
45430 diff -urNp linux-2.6.31.1/net/mac80211/ieee80211_i.h linux-2.6.31.1/net/mac80211/ieee80211_i.h
45431 --- linux-2.6.31.1/net/mac80211/ieee80211_i.h 2009-09-24 11:45:25.000000000 -0400
45432 +++ linux-2.6.31.1/net/mac80211/ieee80211_i.h 2009-10-01 20:12:45.000000000 -0400
45433 @@ -609,7 +609,7 @@ struct ieee80211_local {
45434 spinlock_t queue_stop_reason_lock;
45435
45436 struct net_device *mdev; /* wmaster# - "master" 802.11 device */
45437 - int open_count;
45438 + atomic_t open_count;
45439 int monitors, cooked_mntrs;
45440 /* number of interfaces with corresponding FIF_ flags */
45441 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss;
45442 diff -urNp linux-2.6.31.1/net/mac80211/iface.c linux-2.6.31.1/net/mac80211/iface.c
45443 --- linux-2.6.31.1/net/mac80211/iface.c 2009-09-24 11:45:25.000000000 -0400
45444 +++ linux-2.6.31.1/net/mac80211/iface.c 2009-10-01 20:12:45.000000000 -0400
45445 @@ -164,7 +164,7 @@ static int ieee80211_open(struct net_dev
45446 break;
45447 }
45448
45449 - if (local->open_count == 0) {
45450 + if (atomic_read(&local->open_count) == 0) {
45451 res = drv_start(local);
45452 if (res)
45453 goto err_del_bss;
45454 @@ -198,7 +198,7 @@ static int ieee80211_open(struct net_dev
45455 * Validate the MAC address for this device.
45456 */
45457 if (!is_valid_ether_addr(dev->dev_addr)) {
45458 - if (!local->open_count)
45459 + if (!atomic_read(&local->open_count))
45460 drv_stop(local);
45461 return -EADDRNOTAVAIL;
45462 }
45463 @@ -281,7 +281,7 @@ static int ieee80211_open(struct net_dev
45464 }
45465 }
45466
45467 - if (local->open_count == 0) {
45468 + if (atomic_read(&local->open_count) == 0) {
45469 res = dev_open(local->mdev);
45470 WARN_ON(res);
45471 if (res)
45472 @@ -303,7 +303,7 @@ static int ieee80211_open(struct net_dev
45473
45474 hw_reconf_flags |= __ieee80211_recalc_idle(local);
45475
45476 - local->open_count++;
45477 + atomic_inc(&local->open_count);
45478 if (hw_reconf_flags) {
45479 ieee80211_hw_config(local, hw_reconf_flags);
45480 /*
45481 @@ -331,7 +331,7 @@ static int ieee80211_open(struct net_dev
45482 err_del_interface:
45483 drv_remove_interface(local, &conf);
45484 err_stop:
45485 - if (!local->open_count)
45486 + if (!atomic_read(&local->open_count))
45487 drv_stop(local);
45488 err_del_bss:
45489 sdata->bss = NULL;
45490 @@ -429,7 +429,7 @@ static int ieee80211_stop(struct net_dev
45491 WARN_ON(!list_empty(&sdata->u.ap.vlans));
45492 }
45493
45494 - local->open_count--;
45495 + atomic_dec(&local->open_count);
45496
45497 switch (sdata->vif.type) {
45498 case NL80211_IFTYPE_AP_VLAN:
45499 @@ -554,7 +554,7 @@ static int ieee80211_stop(struct net_dev
45500
45501 ieee80211_recalc_ps(local, -1);
45502
45503 - if (local->open_count == 0) {
45504 + if (atomic_read(&local->open_count) == 0) {
45505 if (netif_running(local->mdev))
45506 dev_close(local->mdev);
45507
45508 diff -urNp linux-2.6.31.1/net/mac80211/main.c linux-2.6.31.1/net/mac80211/main.c
45509 --- linux-2.6.31.1/net/mac80211/main.c 2009-09-24 11:45:25.000000000 -0400
45510 +++ linux-2.6.31.1/net/mac80211/main.c 2009-10-01 20:12:45.000000000 -0400
45511 @@ -193,7 +193,7 @@ int ieee80211_hw_config(struct ieee80211
45512 local->hw.conf.power_level = power;
45513 }
45514
45515 - if (changed && local->open_count) {
45516 + if (changed && atomic_read(&local->open_count)) {
45517 ret = drv_config(local, changed);
45518 /*
45519 * Goal:
45520 diff -urNp linux-2.6.31.1/net/mac80211/pm.c linux-2.6.31.1/net/mac80211/pm.c
45521 --- linux-2.6.31.1/net/mac80211/pm.c 2009-09-24 11:45:25.000000000 -0400
45522 +++ linux-2.6.31.1/net/mac80211/pm.c 2009-10-01 20:12:45.000000000 -0400
45523 @@ -103,7 +103,7 @@ int __ieee80211_suspend(struct ieee80211
45524 }
45525
45526 /* stop hardware - this must stop RX */
45527 - if (local->open_count) {
45528 + if (atomic_read(&local->open_count)) {
45529 ieee80211_led_radio(local, false);
45530 drv_stop(local);
45531 }
45532 diff -urNp linux-2.6.31.1/net/mac80211/rate.c linux-2.6.31.1/net/mac80211/rate.c
45533 --- linux-2.6.31.1/net/mac80211/rate.c 2009-09-24 11:45:25.000000000 -0400
45534 +++ linux-2.6.31.1/net/mac80211/rate.c 2009-10-01 20:12:45.000000000 -0400
45535 @@ -258,7 +258,7 @@ int ieee80211_init_rate_ctrl_alg(struct
45536 struct rate_control_ref *ref, *old;
45537
45538 ASSERT_RTNL();
45539 - if (local->open_count || netif_running(local->mdev))
45540 + if (atomic_read(&local->open_count) || netif_running(local->mdev))
45541 return -EBUSY;
45542
45543 ref = rate_control_alloc(name, local);
45544 diff -urNp linux-2.6.31.1/net/mac80211/rc80211_minstrel_debugfs.c linux-2.6.31.1/net/mac80211/rc80211_minstrel_debugfs.c
45545 --- linux-2.6.31.1/net/mac80211/rc80211_minstrel_debugfs.c 2009-09-24 11:45:25.000000000 -0400
45546 +++ linux-2.6.31.1/net/mac80211/rc80211_minstrel_debugfs.c 2009-10-01 20:12:45.000000000 -0400
45547 @@ -139,7 +139,7 @@ minstrel_stats_release(struct inode *ino
45548 return 0;
45549 }
45550
45551 -static struct file_operations minstrel_stat_fops = {
45552 +static const struct file_operations minstrel_stat_fops = {
45553 .owner = THIS_MODULE,
45554 .open = minstrel_stats_open,
45555 .read = minstrel_stats_read,
45556 diff -urNp linux-2.6.31.1/net/mac80211/rc80211_pid_debugfs.c linux-2.6.31.1/net/mac80211/rc80211_pid_debugfs.c
45557 --- linux-2.6.31.1/net/mac80211/rc80211_pid_debugfs.c 2009-09-24 11:45:25.000000000 -0400
45558 +++ linux-2.6.31.1/net/mac80211/rc80211_pid_debugfs.c 2009-10-01 20:12:45.000000000 -0400
45559 @@ -198,7 +198,7 @@ static ssize_t rate_control_pid_events_r
45560
45561 #undef RC_PID_PRINT_BUF_SIZE
45562
45563 -static struct file_operations rc_pid_fop_events = {
45564 +static const struct file_operations rc_pid_fop_events = {
45565 .owner = THIS_MODULE,
45566 .read = rate_control_pid_events_read,
45567 .poll = rate_control_pid_events_poll,
45568 diff -urNp linux-2.6.31.1/net/mac80211/util.c linux-2.6.31.1/net/mac80211/util.c
45569 --- linux-2.6.31.1/net/mac80211/util.c 2009-09-24 11:45:25.000000000 -0400
45570 +++ linux-2.6.31.1/net/mac80211/util.c 2009-10-01 20:12:45.000000000 -0400
45571 @@ -991,7 +991,7 @@ int ieee80211_reconfig(struct ieee80211_
45572 local->suspended = false;
45573
45574 /* restart hardware */
45575 - if (local->open_count) {
45576 + if (atomic_read(&local->open_count)) {
45577 res = drv_start(local);
45578
45579 ieee80211_led_radio(local, true);
45580 diff -urNp linux-2.6.31.1/net/packet/af_packet.c linux-2.6.31.1/net/packet/af_packet.c
45581 --- linux-2.6.31.1/net/packet/af_packet.c 2009-09-24 11:45:25.000000000 -0400
45582 +++ linux-2.6.31.1/net/packet/af_packet.c 2009-10-01 20:12:45.000000000 -0400
45583 @@ -2086,7 +2086,7 @@ static void packet_mm_close(struct vm_ar
45584 atomic_dec(&pkt_sk(sk)->mapped);
45585 }
45586
45587 -static struct vm_operations_struct packet_mmap_ops = {
45588 +static const struct vm_operations_struct packet_mmap_ops = {
45589 .open = packet_mm_open,
45590 .close =packet_mm_close,
45591 };
45592 diff -urNp linux-2.6.31.1/net/sctp/socket.c linux-2.6.31.1/net/sctp/socket.c
45593 --- linux-2.6.31.1/net/sctp/socket.c 2009-09-24 11:45:25.000000000 -0400
45594 +++ linux-2.6.31.1/net/sctp/socket.c 2009-10-01 20:12:45.000000000 -0400
45595 @@ -1471,7 +1471,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
45596 struct sctp_sndrcvinfo *sinfo;
45597 struct sctp_initmsg *sinit;
45598 sctp_assoc_t associd = 0;
45599 - sctp_cmsgs_t cmsgs = { NULL };
45600 + sctp_cmsgs_t cmsgs = { NULL, NULL };
45601 int err;
45602 sctp_scope_t scope;
45603 long timeo;
45604 @@ -5790,7 +5790,6 @@ pp_found:
45605 */
45606 int reuse = sk->sk_reuse;
45607 struct sock *sk2;
45608 - struct hlist_node *node;
45609
45610 SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
45611 if (pp->fastreuse && sk->sk_reuse &&
45612 diff -urNp linux-2.6.31.1/net/socket.c linux-2.6.31.1/net/socket.c
45613 --- linux-2.6.31.1/net/socket.c 2009-09-24 11:45:25.000000000 -0400
45614 +++ linux-2.6.31.1/net/socket.c 2009-10-01 20:12:45.000000000 -0400
45615 @@ -86,6 +86,7 @@
45616 #include <linux/audit.h>
45617 #include <linux/wireless.h>
45618 #include <linux/nsproxy.h>
45619 +#include <linux/in.h>
45620
45621 #include <asm/uaccess.h>
45622 #include <asm/unistd.h>
45623 @@ -96,6 +97,21 @@
45624 #include <net/sock.h>
45625 #include <linux/netfilter.h>
45626
45627 +extern void gr_attach_curr_ip(const struct sock *sk);
45628 +extern int gr_handle_sock_all(const int family, const int type,
45629 + const int protocol);
45630 +extern int gr_handle_sock_server(const struct sockaddr *sck);
45631 +extern int gr_handle_sock_server_other(const struct socket *sck);
45632 +extern int gr_handle_sock_client(const struct sockaddr *sck);
45633 +extern int gr_search_connect(struct socket * sock,
45634 + struct sockaddr_in * addr);
45635 +extern int gr_search_bind(struct socket * sock,
45636 + struct sockaddr_in * addr);
45637 +extern int gr_search_listen(struct socket * sock);
45638 +extern int gr_search_accept(struct socket * sock);
45639 +extern int gr_search_socket(const int domain, const int type,
45640 + const int protocol);
45641 +
45642 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
45643 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
45644 unsigned long nr_segs, loff_t pos);
45645 @@ -285,7 +301,7 @@ static int init_inodecache(void)
45646 return 0;
45647 }
45648
45649 -static struct super_operations sockfs_ops = {
45650 +static const struct super_operations sockfs_ops = {
45651 .alloc_inode = sock_alloc_inode,
45652 .destroy_inode =sock_destroy_inode,
45653 .statfs = simple_statfs,
45654 @@ -299,7 +315,7 @@ static int sockfs_get_sb(struct file_sys
45655 mnt);
45656 }
45657
45658 -static struct vfsmount *sock_mnt __read_mostly;
45659 +struct vfsmount *sock_mnt __read_mostly;
45660
45661 static struct file_system_type sock_fs_type = {
45662 .name = "sockfs",
45663 @@ -1283,6 +1299,16 @@ SYSCALL_DEFINE3(socket, int, family, int
45664 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
45665 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
45666
45667 + if(!gr_search_socket(family, type, protocol)) {
45668 + retval = -EACCES;
45669 + goto out;
45670 + }
45671 +
45672 + if (gr_handle_sock_all(family, type, protocol)) {
45673 + retval = -EACCES;
45674 + goto out;
45675 + }
45676 +
45677 retval = sock_create(family, type, protocol, &sock);
45678 if (retval < 0)
45679 goto out;
45680 @@ -1415,6 +1441,14 @@ SYSCALL_DEFINE3(bind, int, fd, struct so
45681 if (sock) {
45682 err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
45683 if (err >= 0) {
45684 + if (gr_handle_sock_server((struct sockaddr *)&address)) {
45685 + err = -EACCES;
45686 + goto error;
45687 + }
45688 + err = gr_search_bind(sock, (struct sockaddr_in *)&address);
45689 + if (err)
45690 + goto error;
45691 +
45692 err = security_socket_bind(sock,
45693 (struct sockaddr *)&address,
45694 addrlen);
45695 @@ -1423,6 +1457,7 @@ SYSCALL_DEFINE3(bind, int, fd, struct so
45696 (struct sockaddr *)
45697 &address, addrlen);
45698 }
45699 +error:
45700 fput_light(sock->file, fput_needed);
45701 }
45702 return err;
45703 @@ -1446,10 +1481,20 @@ SYSCALL_DEFINE2(listen, int, fd, int, ba
45704 if ((unsigned)backlog > somaxconn)
45705 backlog = somaxconn;
45706
45707 + if (gr_handle_sock_server_other(sock)) {
45708 + err = -EPERM;
45709 + goto error;
45710 + }
45711 +
45712 + err = gr_search_listen(sock);
45713 + if (err)
45714 + goto error;
45715 +
45716 err = security_socket_listen(sock, backlog);
45717 if (!err)
45718 err = sock->ops->listen(sock, backlog);
45719
45720 +error:
45721 fput_light(sock->file, fput_needed);
45722 }
45723 return err;
45724 @@ -1492,6 +1537,18 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
45725 newsock->type = sock->type;
45726 newsock->ops = sock->ops;
45727
45728 + if (gr_handle_sock_server_other(sock)) {
45729 + err = -EPERM;
45730 + sock_release(newsock);
45731 + goto out_put;
45732 + }
45733 +
45734 + err = gr_search_accept(sock);
45735 + if (err) {
45736 + sock_release(newsock);
45737 + goto out_put;
45738 + }
45739 +
45740 /*
45741 * We don't need try_module_get here, as the listening socket (sock)
45742 * has the protocol module (sock->ops->owner) held.
45743 @@ -1534,6 +1591,8 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
45744 fd_install(newfd, newfile);
45745 err = newfd;
45746
45747 + gr_attach_curr_ip(newsock->sk);
45748 +
45749 out_put:
45750 fput_light(sock->file, fput_needed);
45751 out:
45752 @@ -1571,6 +1630,7 @@ SYSCALL_DEFINE3(connect, int, fd, struct
45753 int, addrlen)
45754 {
45755 struct socket *sock;
45756 + struct sockaddr *sck;
45757 struct sockaddr_storage address;
45758 int err, fput_needed;
45759
45760 @@ -1581,6 +1641,17 @@ SYSCALL_DEFINE3(connect, int, fd, struct
45761 if (err < 0)
45762 goto out_put;
45763
45764 + sck = (struct sockaddr *)&address;
45765 +
45766 + if (gr_handle_sock_client(sck)) {
45767 + err = -EACCES;
45768 + goto out_put;
45769 + }
45770 +
45771 + err = gr_search_connect(sock, (struct sockaddr_in *)sck);
45772 + if (err)
45773 + goto out_put;
45774 +
45775 err =
45776 security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
45777 if (err)
45778 diff -urNp linux-2.6.31.1/net/sunrpc/rpc_pipe.c linux-2.6.31.1/net/sunrpc/rpc_pipe.c
45779 --- linux-2.6.31.1/net/sunrpc/rpc_pipe.c 2009-09-24 11:45:25.000000000 -0400
45780 +++ linux-2.6.31.1/net/sunrpc/rpc_pipe.c 2009-10-01 20:12:45.000000000 -0400
45781 @@ -858,7 +858,7 @@ EXPORT_SYMBOL_GPL(rpc_unlink);
45782 /*
45783 * populate the filesystem
45784 */
45785 -static struct super_operations s_ops = {
45786 +static const struct super_operations s_ops = {
45787 .alloc_inode = rpc_alloc_inode,
45788 .destroy_inode = rpc_destroy_inode,
45789 .statfs = simple_statfs,
45790 diff -urNp linux-2.6.31.1/net/unix/af_unix.c linux-2.6.31.1/net/unix/af_unix.c
45791 --- linux-2.6.31.1/net/unix/af_unix.c 2009-09-24 11:45:25.000000000 -0400
45792 +++ linux-2.6.31.1/net/unix/af_unix.c 2009-10-01 20:12:45.000000000 -0400
45793 @@ -734,6 +734,12 @@ static struct sock *unix_find_other(stru
45794 err = -ECONNREFUSED;
45795 if (!S_ISSOCK(inode->i_mode))
45796 goto put_fail;
45797 +
45798 + if (!gr_acl_handle_unix(path.dentry, path.mnt)) {
45799 + err = -EACCES;
45800 + goto put_fail;
45801 + }
45802 +
45803 u = unix_find_socket_byinode(net, inode);
45804 if (!u)
45805 goto put_fail;
45806 @@ -754,6 +760,13 @@ static struct sock *unix_find_other(stru
45807 if (u) {
45808 struct dentry *dentry;
45809 dentry = unix_sk(u)->dentry;
45810 +
45811 + if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
45812 + err = -EPERM;
45813 + sock_put(u);
45814 + goto fail;
45815 + }
45816 +
45817 if (dentry)
45818 touch_atime(unix_sk(u)->mnt, dentry);
45819 } else
45820 @@ -839,11 +852,18 @@ static int unix_bind(struct socket *sock
45821 err = security_path_mknod(&nd.path, dentry, mode, 0);
45822 if (err)
45823 goto out_mknod_drop_write;
45824 + if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
45825 + err = -EACCES;
45826 + goto out_mknod_drop_write;
45827 + }
45828 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
45829 out_mknod_drop_write:
45830 mnt_drop_write(nd.path.mnt);
45831 if (err)
45832 goto out_mknod_dput;
45833 +
45834 + gr_handle_create(dentry, nd.path.mnt);
45835 +
45836 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
45837 dput(nd.path.dentry);
45838 nd.path.dentry = dentry;
45839 @@ -861,6 +881,10 @@ out_mknod_drop_write:
45840 goto out_unlock;
45841 }
45842
45843 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
45844 + sk->sk_peercred.pid = current->pid;
45845 +#endif
45846 +
45847 list = &unix_socket_table[addr->hash];
45848 } else {
45849 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
45850 diff -urNp linux-2.6.31.1/net/xfrm/xfrm_proc.c linux-2.6.31.1/net/xfrm/xfrm_proc.c
45851 --- linux-2.6.31.1/net/xfrm/xfrm_proc.c 2009-09-24 11:45:25.000000000 -0400
45852 +++ linux-2.6.31.1/net/xfrm/xfrm_proc.c 2009-10-01 20:12:45.000000000 -0400
45853 @@ -60,7 +60,7 @@ static int xfrm_statistics_seq_open(stru
45854 return single_open_net(inode, file, xfrm_statistics_seq_show);
45855 }
45856
45857 -static struct file_operations xfrm_statistics_seq_fops = {
45858 +static const struct file_operations xfrm_statistics_seq_fops = {
45859 .owner = THIS_MODULE,
45860 .open = xfrm_statistics_seq_open,
45861 .read = seq_read,
45862 diff -urNp linux-2.6.31.1/samples/markers/marker-example.c linux-2.6.31.1/samples/markers/marker-example.c
45863 --- linux-2.6.31.1/samples/markers/marker-example.c 2009-09-24 11:45:25.000000000 -0400
45864 +++ linux-2.6.31.1/samples/markers/marker-example.c 2009-10-01 20:12:45.000000000 -0400
45865 @@ -26,7 +26,7 @@ static int my_open(struct inode *inode,
45866 return -EPERM;
45867 }
45868
45869 -static struct file_operations mark_ops = {
45870 +static const struct file_operations mark_ops = {
45871 .open = my_open,
45872 };
45873
45874 diff -urNp linux-2.6.31.1/samples/tracepoints/tracepoint-sample.c linux-2.6.31.1/samples/tracepoints/tracepoint-sample.c
45875 --- linux-2.6.31.1/samples/tracepoints/tracepoint-sample.c 2009-09-24 11:45:25.000000000 -0400
45876 +++ linux-2.6.31.1/samples/tracepoints/tracepoint-sample.c 2009-10-01 20:12:45.000000000 -0400
45877 @@ -28,7 +28,7 @@ static int my_open(struct inode *inode,
45878 return -EPERM;
45879 }
45880
45881 -static struct file_operations mark_ops = {
45882 +static const struct file_operations mark_ops = {
45883 .open = my_open,
45884 };
45885
45886 diff -urNp linux-2.6.31.1/scripts/basic/fixdep.c linux-2.6.31.1/scripts/basic/fixdep.c
45887 --- linux-2.6.31.1/scripts/basic/fixdep.c 2009-09-24 11:45:25.000000000 -0400
45888 +++ linux-2.6.31.1/scripts/basic/fixdep.c 2009-10-01 20:12:45.000000000 -0400
45889 @@ -224,9 +224,9 @@ void use_config(char *m, int slen)
45890
45891 void parse_config_file(char *map, size_t len)
45892 {
45893 - int *end = (int *) (map + len);
45894 + unsigned int *end = (unsigned int *) (map + len);
45895 /* start at +1, so that p can never be < map */
45896 - int *m = (int *) map + 1;
45897 + unsigned int *m = (unsigned int *) map + 1;
45898 char *p, *q;
45899
45900 for (; m < end; m++) {
45901 @@ -373,7 +373,7 @@ void print_deps(void)
45902 void traps(void)
45903 {
45904 static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
45905 - int *p = (int *)test;
45906 + unsigned int *p = (unsigned int *)test;
45907
45908 if (*p != INT_CONF) {
45909 fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianess? %#x\n",
45910 diff -urNp linux-2.6.31.1/scripts/kallsyms.c linux-2.6.31.1/scripts/kallsyms.c
45911 --- linux-2.6.31.1/scripts/kallsyms.c 2009-09-24 11:45:25.000000000 -0400
45912 +++ linux-2.6.31.1/scripts/kallsyms.c 2009-10-01 20:12:45.000000000 -0400
45913 @@ -43,10 +43,10 @@ struct text_range {
45914
45915 static unsigned long long _text;
45916 static struct text_range text_ranges[] = {
45917 - { "_stext", "_etext" },
45918 - { "_sinittext", "_einittext" },
45919 - { "_stext_l1", "_etext_l1" }, /* Blackfin on-chip L1 inst SRAM */
45920 - { "_stext_l2", "_etext_l2" }, /* Blackfin on-chip L2 SRAM */
45921 + { "_stext", "_etext", 0, 0 },
45922 + { "_sinittext", "_einittext", 0, 0 },
45923 + { "_stext_l1", "_etext_l1", 0, 0 }, /* Blackfin on-chip L1 inst SRAM */
45924 + { "_stext_l2", "_etext_l2", 0, 0 }, /* Blackfin on-chip L2 SRAM */
45925 };
45926 #define text_range_text (&text_ranges[0])
45927 #define text_range_inittext (&text_ranges[1])
45928 diff -urNp linux-2.6.31.1/scripts/kconfig/lkc.h linux-2.6.31.1/scripts/kconfig/lkc.h
45929 --- linux-2.6.31.1/scripts/kconfig/lkc.h 2009-09-24 11:45:25.000000000 -0400
45930 +++ linux-2.6.31.1/scripts/kconfig/lkc.h 2009-10-01 20:12:45.000000000 -0400
45931 @@ -97,7 +97,7 @@ void menu_add_expr(enum prop_type type,
45932 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
45933 void menu_add_option(int token, char *arg);
45934 void menu_finalize(struct menu *parent);
45935 -void menu_set_type(int type);
45936 +void menu_set_type(unsigned int type);
45937
45938 /* util.c */
45939 struct file *file_lookup(const char *name);
45940 diff -urNp linux-2.6.31.1/scripts/kconfig/mconf.c linux-2.6.31.1/scripts/kconfig/mconf.c
45941 --- linux-2.6.31.1/scripts/kconfig/mconf.c 2009-09-24 11:45:25.000000000 -0400
45942 +++ linux-2.6.31.1/scripts/kconfig/mconf.c 2009-10-01 20:12:45.000000000 -0400
45943 @@ -361,7 +361,7 @@ static char filename[PATH_MAX+1];
45944 static void set_config_filename(const char *config_filename)
45945 {
45946 static char menu_backtitle[PATH_MAX+128];
45947 - int size;
45948 + unsigned int size;
45949 struct symbol *sym;
45950
45951 sym = sym_lookup("KERNELVERSION", 0);
45952 diff -urNp linux-2.6.31.1/scripts/kconfig/menu.c linux-2.6.31.1/scripts/kconfig/menu.c
45953 --- linux-2.6.31.1/scripts/kconfig/menu.c 2009-09-24 11:45:25.000000000 -0400
45954 +++ linux-2.6.31.1/scripts/kconfig/menu.c 2009-10-01 20:12:45.000000000 -0400
45955 @@ -104,7 +104,7 @@ void menu_add_dep(struct expr *dep)
45956 current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
45957 }
45958
45959 -void menu_set_type(int type)
45960 +void menu_set_type(unsigned int type)
45961 {
45962 struct symbol *sym = current_entry->sym;
45963
45964 diff -urNp linux-2.6.31.1/scripts/mod/file2alias.c linux-2.6.31.1/scripts/mod/file2alias.c
45965 --- linux-2.6.31.1/scripts/mod/file2alias.c 2009-09-24 11:45:25.000000000 -0400
45966 +++ linux-2.6.31.1/scripts/mod/file2alias.c 2009-10-01 20:12:45.000000000 -0400
45967 @@ -72,7 +72,7 @@ static void device_id_check(const char *
45968 unsigned long size, unsigned long id_size,
45969 void *symval)
45970 {
45971 - int i;
45972 + unsigned int i;
45973
45974 if (size % id_size || size < id_size) {
45975 if (cross_build != 0)
45976 @@ -102,7 +102,7 @@ static void device_id_check(const char *
45977 /* USB is special because the bcdDevice can be matched against a numeric range */
45978 /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */
45979 static void do_usb_entry(struct usb_device_id *id,
45980 - unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
45981 + unsigned int bcdDevice_initial, unsigned int bcdDevice_initial_digits,
45982 unsigned char range_lo, unsigned char range_hi,
45983 struct module *mod)
45984 {
45985 @@ -368,7 +368,7 @@ static void do_pnp_device_entry(void *sy
45986 for (i = 0; i < count; i++) {
45987 const char *id = (char *)devs[i].id;
45988 char acpi_id[sizeof(devs[0].id)];
45989 - int j;
45990 + unsigned int j;
45991
45992 buf_printf(&mod->dev_table_buf,
45993 "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
45994 @@ -398,7 +398,7 @@ static void do_pnp_card_entries(void *sy
45995
45996 for (j = 0; j < PNP_MAX_DEVICES; j++) {
45997 const char *id = (char *)card->devs[j].id;
45998 - int i2, j2;
45999 + unsigned int i2, j2;
46000 int dup = 0;
46001
46002 if (!id[0])
46003 @@ -424,7 +424,7 @@ static void do_pnp_card_entries(void *sy
46004 /* add an individual alias for every device entry */
46005 if (!dup) {
46006 char acpi_id[sizeof(card->devs[0].id)];
46007 - int k;
46008 + unsigned int k;
46009
46010 buf_printf(&mod->dev_table_buf,
46011 "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
46012 @@ -690,7 +690,7 @@ static void dmi_ascii_filter(char *d, co
46013 static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
46014 char *alias)
46015 {
46016 - int i, j;
46017 + unsigned int i, j;
46018
46019 sprintf(alias, "dmi*");
46020
46021 diff -urNp linux-2.6.31.1/scripts/mod/modpost.c linux-2.6.31.1/scripts/mod/modpost.c
46022 --- linux-2.6.31.1/scripts/mod/modpost.c 2009-09-24 11:45:25.000000000 -0400
46023 +++ linux-2.6.31.1/scripts/mod/modpost.c 2009-10-01 20:12:45.000000000 -0400
46024 @@ -835,6 +835,7 @@ enum mismatch {
46025 INIT_TO_EXIT,
46026 EXIT_TO_INIT,
46027 EXPORT_TO_INIT_EXIT,
46028 + DATA_TO_TEXT
46029 };
46030
46031 struct sectioncheck {
46032 @@ -920,6 +921,12 @@ const struct sectioncheck sectioncheck[]
46033 .fromsec = { "__ksymtab*", NULL },
46034 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
46035 .mismatch = EXPORT_TO_INIT_EXIT
46036 +},
46037 +/* Do not reference code from writable data */
46038 +{
46039 + .fromsec = { DATA_SECTIONS, NULL },
46040 + .tosec = { TEXT_SECTIONS, NULL },
46041 + .mismatch = DATA_TO_TEXT
46042 }
46043 };
46044
46045 @@ -1024,10 +1031,10 @@ static Elf_Sym *find_elf_symbol(struct e
46046 continue;
46047 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
46048 continue;
46049 - if (sym->st_value == addr)
46050 - return sym;
46051 /* Find a symbol nearby - addr are maybe negative */
46052 d = sym->st_value - addr;
46053 + if (d == 0)
46054 + return sym;
46055 if (d < 0)
46056 d = addr - sym->st_value;
46057 if (d < distance) {
46058 @@ -1268,6 +1275,14 @@ static void report_sec_mismatch(const ch
46059 "Fix this by removing the %sannotation of %s "
46060 "or drop the export.\n",
46061 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
46062 + case DATA_TO_TEXT:
46063 +/*
46064 + fprintf(stderr,
46065 + "The variable %s references\n"
46066 + "the %s %s%s%s\n",
46067 + fromsym, to, sec2annotation(tosec), tosym, to_p);
46068 +*/
46069 + break;
46070 case NO_MISMATCH:
46071 /* To get warnings on missing members */
46072 break;
46073 @@ -1651,7 +1666,7 @@ void __attribute__((format(printf, 2, 3)
46074 va_end(ap);
46075 }
46076
46077 -void buf_write(struct buffer *buf, const char *s, int len)
46078 +void buf_write(struct buffer *buf, const char *s, unsigned int len)
46079 {
46080 if (buf->size - buf->pos < len) {
46081 buf->size += len + SZ;
46082 @@ -1863,7 +1878,7 @@ static void write_if_changed(struct buff
46083 if (fstat(fileno(file), &st) < 0)
46084 goto close_write;
46085
46086 - if (st.st_size != b->pos)
46087 + if (st.st_size != (off_t)b->pos)
46088 goto close_write;
46089
46090 tmp = NOFAIL(malloc(b->pos));
46091 diff -urNp linux-2.6.31.1/scripts/mod/modpost.h linux-2.6.31.1/scripts/mod/modpost.h
46092 --- linux-2.6.31.1/scripts/mod/modpost.h 2009-09-24 11:45:25.000000000 -0400
46093 +++ linux-2.6.31.1/scripts/mod/modpost.h 2009-10-01 20:12:45.000000000 -0400
46094 @@ -92,15 +92,15 @@ void *do_nofail(void *ptr, const char *e
46095
46096 struct buffer {
46097 char *p;
46098 - int pos;
46099 - int size;
46100 + unsigned int pos;
46101 + unsigned int size;
46102 };
46103
46104 void __attribute__((format(printf, 2, 3)))
46105 buf_printf(struct buffer *buf, const char *fmt, ...);
46106
46107 void
46108 -buf_write(struct buffer *buf, const char *s, int len);
46109 +buf_write(struct buffer *buf, const char *s, unsigned int len);
46110
46111 struct module {
46112 struct module *next;
46113 diff -urNp linux-2.6.31.1/scripts/mod/sumversion.c linux-2.6.31.1/scripts/mod/sumversion.c
46114 --- linux-2.6.31.1/scripts/mod/sumversion.c 2009-09-24 11:45:25.000000000 -0400
46115 +++ linux-2.6.31.1/scripts/mod/sumversion.c 2009-10-01 20:12:45.000000000 -0400
46116 @@ -457,7 +457,7 @@ static void write_version(const char *fi
46117 goto out;
46118 }
46119
46120 - if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) {
46121 + if (write(fd, sum, strlen(sum)+1) != (ssize_t)strlen(sum)+1) {
46122 warn("writing sum in %s failed: %s\n",
46123 filename, strerror(errno));
46124 goto out;
46125 diff -urNp linux-2.6.31.1/scripts/pnmtologo.c linux-2.6.31.1/scripts/pnmtologo.c
46126 --- linux-2.6.31.1/scripts/pnmtologo.c 2009-09-24 11:45:25.000000000 -0400
46127 +++ linux-2.6.31.1/scripts/pnmtologo.c 2009-10-01 20:12:45.000000000 -0400
46128 @@ -237,14 +237,14 @@ static void write_header(void)
46129 fprintf(out, " * Linux logo %s\n", logoname);
46130 fputs(" */\n\n", out);
46131 fputs("#include <linux/linux_logo.h>\n\n", out);
46132 - fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
46133 + fprintf(out, "static unsigned char %s_data[] = {\n",
46134 logoname);
46135 }
46136
46137 static void write_footer(void)
46138 {
46139 fputs("\n};\n\n", out);
46140 - fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname);
46141 + fprintf(out, "const struct linux_logo %s = {\n", logoname);
46142 fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]);
46143 fprintf(out, "\t.width\t\t= %d,\n", logo_width);
46144 fprintf(out, "\t.height\t\t= %d,\n", logo_height);
46145 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
46146 fputs("\n};\n\n", out);
46147
46148 /* write logo clut */
46149 - fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
46150 + fprintf(out, "static unsigned char %s_clut[] = {\n",
46151 logoname);
46152 write_hex_cnt = 0;
46153 for (i = 0; i < logo_clutsize; i++) {
46154 diff -urNp linux-2.6.31.1/security/commoncap.c linux-2.6.31.1/security/commoncap.c
46155 --- linux-2.6.31.1/security/commoncap.c 2009-09-24 11:45:25.000000000 -0400
46156 +++ linux-2.6.31.1/security/commoncap.c 2009-10-01 20:12:45.000000000 -0400
46157 @@ -27,7 +27,7 @@
46158 #include <linux/sched.h>
46159 #include <linux/prctl.h>
46160 #include <linux/securebits.h>
46161 -
46162 +#include <net/sock.h>
46163 /*
46164 * If a non-root user executes a setuid-root binary in
46165 * !secure(SECURE_NOROOT) mode, then we raise capabilities.
46166 @@ -50,9 +50,11 @@ static void warn_setuid_and_fcaps_mixed(
46167 }
46168 }
46169
46170 +extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
46171 +
46172 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
46173 {
46174 - NETLINK_CB(skb).eff_cap = current_cap();
46175 + NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
46176 return 0;
46177 }
46178
46179 diff -urNp linux-2.6.31.1/security/integrity/ima/ima_fs.c linux-2.6.31.1/security/integrity/ima/ima_fs.c
46180 --- linux-2.6.31.1/security/integrity/ima/ima_fs.c 2009-09-24 11:45:25.000000000 -0400
46181 +++ linux-2.6.31.1/security/integrity/ima/ima_fs.c 2009-10-01 20:12:45.000000000 -0400
46182 @@ -43,7 +43,7 @@ static ssize_t ima_show_htable_violation
46183 return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
46184 }
46185
46186 -static struct file_operations ima_htable_violations_ops = {
46187 +static const struct file_operations ima_htable_violations_ops = {
46188 .read = ima_show_htable_violations
46189 };
46190
46191 @@ -55,7 +55,7 @@ static ssize_t ima_show_measurements_cou
46192
46193 }
46194
46195 -static struct file_operations ima_measurements_count_ops = {
46196 +static const struct file_operations ima_measurements_count_ops = {
46197 .read = ima_show_measurements_count
46198 };
46199
46200 @@ -146,7 +146,7 @@ static int ima_measurements_show(struct
46201 return 0;
46202 }
46203
46204 -static struct seq_operations ima_measurments_seqops = {
46205 +static const struct seq_operations ima_measurments_seqops = {
46206 .start = ima_measurements_start,
46207 .next = ima_measurements_next,
46208 .stop = ima_measurements_stop,
46209 @@ -158,7 +158,7 @@ static int ima_measurements_open(struct
46210 return seq_open(file, &ima_measurments_seqops);
46211 }
46212
46213 -static struct file_operations ima_measurements_ops = {
46214 +static const struct file_operations ima_measurements_ops = {
46215 .open = ima_measurements_open,
46216 .read = seq_read,
46217 .llseek = seq_lseek,
46218 @@ -221,7 +221,7 @@ static int ima_ascii_measurements_show(s
46219 return 0;
46220 }
46221
46222 -static struct seq_operations ima_ascii_measurements_seqops = {
46223 +static const struct seq_operations ima_ascii_measurements_seqops = {
46224 .start = ima_measurements_start,
46225 .next = ima_measurements_next,
46226 .stop = ima_measurements_stop,
46227 @@ -233,7 +233,7 @@ static int ima_ascii_measurements_open(s
46228 return seq_open(file, &ima_ascii_measurements_seqops);
46229 }
46230
46231 -static struct file_operations ima_ascii_measurements_ops = {
46232 +static const struct file_operations ima_ascii_measurements_ops = {
46233 .open = ima_ascii_measurements_open,
46234 .read = seq_read,
46235 .llseek = seq_lseek,
46236 @@ -313,7 +313,7 @@ static int ima_release_policy(struct ino
46237 return 0;
46238 }
46239
46240 -static struct file_operations ima_measure_policy_ops = {
46241 +static const struct file_operations ima_measure_policy_ops = {
46242 .open = ima_open_policy,
46243 .write = ima_write_policy,
46244 .release = ima_release_policy
46245 diff -urNp linux-2.6.31.1/security/Kconfig linux-2.6.31.1/security/Kconfig
46246 --- linux-2.6.31.1/security/Kconfig 2009-09-24 11:45:25.000000000 -0400
46247 +++ linux-2.6.31.1/security/Kconfig 2009-10-01 20:12:45.000000000 -0400
46248 @@ -4,6 +4,465 @@
46249
46250 menu "Security options"
46251
46252 +source grsecurity/Kconfig
46253 +
46254 +menu "PaX"
46255 +
46256 +config PAX
46257 + bool "Enable various PaX features"
46258 + depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
46259 + help
46260 + This allows you to enable various PaX features. PaX adds
46261 + intrusion prevention mechanisms to the kernel that reduce
46262 + the risks posed by exploitable memory corruption bugs.
46263 +
46264 +menu "PaX Control"
46265 + depends on PAX
46266 +
46267 +config PAX_SOFTMODE
46268 + bool 'Support soft mode'
46269 + help
46270 + Enabling this option will allow you to run PaX in soft mode, that
46271 + is, PaX features will not be enforced by default, only on executables
46272 + marked explicitly. You must also enable PT_PAX_FLAGS support as it
46273 + is the only way to mark executables for soft mode use.
46274 +
46275 + Soft mode can be activated by using the "pax_softmode=1" kernel command
46276 + line option on boot. Furthermore you can control various PaX features
46277 + at runtime via the entries in /proc/sys/kernel/pax.
46278 +
46279 +config PAX_EI_PAX
46280 + bool 'Use legacy ELF header marking'
46281 + help
46282 + Enabling this option will allow you to control PaX features on
46283 + a per executable basis via the 'chpax' utility available at
46284 + http://pax.grsecurity.net/. The control flags will be read from
46285 + an otherwise reserved part of the ELF header. This marking has
46286 + numerous drawbacks (no support for soft-mode, toolchain does not
46287 + know about the non-standard use of the ELF header) therefore it
46288 + has been deprecated in favour of PT_PAX_FLAGS support.
46289 +
46290 + If you have applications not marked by the PT_PAX_FLAGS ELF
46291 + program header then you MUST enable this option otherwise they
46292 + will not get any protection.
46293 +
46294 + Note that if you enable PT_PAX_FLAGS marking support as well,
46295 + the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
46296 +
46297 +config PAX_PT_PAX_FLAGS
46298 + bool 'Use ELF program header marking'
46299 + help
46300 + Enabling this option will allow you to control PaX features on
46301 + a per executable basis via the 'paxctl' utility available at
46302 + http://pax.grsecurity.net/. The control flags will be read from
46303 + a PaX specific ELF program header (PT_PAX_FLAGS). This marking
46304 + has the benefits of supporting both soft mode and being fully
46305 + integrated into the toolchain (the binutils patch is available
46306 + from http://pax.grsecurity.net).
46307 +
46308 + If you have applications not marked by the PT_PAX_FLAGS ELF
46309 + program header then you MUST enable the EI_PAX marking support
46310 + otherwise they will not get any protection.
46311 +
46312 + Note that if you enable the legacy EI_PAX marking support as well,
46313 + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
46314 +
46315 +choice
46316 + prompt 'MAC system integration'
46317 + default PAX_HAVE_ACL_FLAGS
46318 + help
46319 + Mandatory Access Control systems have the option of controlling
46320 + PaX flags on a per executable basis, choose the method supported
46321 + by your particular system.
46322 +
46323 + - "none": if your MAC system does not interact with PaX,
46324 + - "direct": if your MAC system defines pax_set_initial_flags() itself,
46325 + - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
46326 +
46327 + NOTE: this option is for developers/integrators only.
46328 +
46329 + config PAX_NO_ACL_FLAGS
46330 + bool 'none'
46331 +
46332 + config PAX_HAVE_ACL_FLAGS
46333 + bool 'direct'
46334 +
46335 + config PAX_HOOK_ACL_FLAGS
46336 + bool 'hook'
46337 +endchoice
46338 +
46339 +endmenu
46340 +
46341 +menu "Non-executable pages"
46342 + depends on PAX
46343 +
46344 +config PAX_NOEXEC
46345 + bool "Enforce non-executable pages"
46346 + 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)
46347 + help
46348 + By design some architectures do not allow for protecting memory
46349 + pages against execution or even if they do, Linux does not make
46350 + use of this feature. In practice this means that if a page is
46351 + readable (such as the stack or heap) it is also executable.
46352 +
46353 + There is a well known exploit technique that makes use of this
46354 + fact and a common programming mistake where an attacker can
46355 + introduce code of his choice somewhere in the attacked program's
46356 + memory (typically the stack or the heap) and then execute it.
46357 +
46358 + If the attacked program was running with different (typically
46359 + higher) privileges than that of the attacker, then he can elevate
46360 + his own privilege level (e.g. get a root shell, write to files for
46361 + which he does not have write access to, etc).
46362 +
46363 + Enabling this option will let you choose from various features
46364 + that prevent the injection and execution of 'foreign' code in
46365 + a program.
46366 +
46367 + This will also break programs that rely on the old behaviour and
46368 + expect that dynamically allocated memory via the malloc() family
46369 + of functions is executable (which it is not). Notable examples
46370 + are the XFree86 4.x server, the java runtime and wine.
46371 +
46372 +config PAX_PAGEEXEC
46373 + bool "Paging based non-executable pages"
46374 + depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7)
46375 + help
46376 + This implementation is based on the paging feature of the CPU.
46377 + On i386 without hardware non-executable bit support there is a
46378 + variable but usually low performance impact, however on Intel's
46379 + P4 core based CPUs it is very high so you should not enable this
46380 + for kernels meant to be used on such CPUs.
46381 +
46382 + On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
46383 + with hardware non-executable bit support there is no performance
46384 + impact, on ppc the impact is negligible.
46385 +
46386 + Note that several architectures require various emulations due to
46387 + badly designed userland ABIs, this will cause a performance impact
46388 + but will disappear as soon as userland is fixed. For example, ppc
46389 + userland MUST have been built with secure-plt by a recent toolchain.
46390 +
46391 +config PAX_SEGMEXEC
46392 + bool "Segmentation based non-executable pages"
46393 + depends on PAX_NOEXEC && X86_32
46394 + help
46395 + This implementation is based on the segmentation feature of the
46396 + CPU and has a very small performance impact, however applications
46397 + will be limited to a 1.5 GB address space instead of the normal
46398 + 3 GB.
46399 +
46400 +config PAX_EMUTRAMP
46401 + bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || X86)
46402 + default y if PARISC
46403 + help
46404 + There are some programs and libraries that for one reason or
46405 + another attempt to execute special small code snippets from
46406 + non-executable memory pages. Most notable examples are the
46407 + signal handler return code generated by the kernel itself and
46408 + the GCC trampolines.
46409 +
46410 + If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
46411 + such programs will no longer work under your kernel.
46412 +
46413 + As a remedy you can say Y here and use the 'chpax' or 'paxctl'
46414 + utilities to enable trampoline emulation for the affected programs
46415 + yet still have the protection provided by the non-executable pages.
46416 +
46417 + On parisc you MUST enable this option and EMUSIGRT as well, otherwise
46418 + your system will not even boot.
46419 +
46420 + Alternatively you can say N here and use the 'chpax' or 'paxctl'
46421 + utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
46422 + for the affected files.
46423 +
46424 + NOTE: enabling this feature *may* open up a loophole in the
46425 + protection provided by non-executable pages that an attacker
46426 + could abuse. Therefore the best solution is to not have any
46427 + files on your system that would require this option. This can
46428 + be achieved by not using libc5 (which relies on the kernel
46429 + signal handler return code) and not using or rewriting programs
46430 + that make use of the nested function implementation of GCC.
46431 + Skilled users can just fix GCC itself so that it implements
46432 + nested function calls in a way that does not interfere with PaX.
46433 +
46434 +config PAX_EMUSIGRT
46435 + bool "Automatically emulate sigreturn trampolines"
46436 + depends on PAX_EMUTRAMP && PARISC
46437 + default y
46438 + help
46439 + Enabling this option will have the kernel automatically detect
46440 + and emulate signal return trampolines executing on the stack
46441 + that would otherwise lead to task termination.
46442 +
46443 + This solution is intended as a temporary one for users with
46444 + legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
46445 + Modula-3 runtime, etc) or executables linked to such, basically
46446 + everything that does not specify its own SA_RESTORER function in
46447 + normal executable memory like glibc 2.1+ does.
46448 +
46449 + On parisc you MUST enable this option, otherwise your system will
46450 + not even boot.
46451 +
46452 + NOTE: this feature cannot be disabled on a per executable basis
46453 + and since it *does* open up a loophole in the protection provided
46454 + by non-executable pages, the best solution is to not have any
46455 + files on your system that would require this option.
46456 +
46457 +config PAX_MPROTECT
46458 + bool "Restrict mprotect()"
46459 + depends on (PAX_PAGEEXEC || PAX_SEGMEXEC)
46460 + help
46461 + Enabling this option will prevent programs from
46462 + - changing the executable status of memory pages that were
46463 + not originally created as executable,
46464 + - making read-only executable pages writable again,
46465 + - creating executable pages from anonymous memory.
46466 +
46467 + You should say Y here to complete the protection provided by
46468 + the enforcement of non-executable pages.
46469 +
46470 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
46471 + this feature on a per file basis.
46472 +
46473 +config PAX_NOELFRELOCS
46474 + bool "Disallow ELF text relocations"
46475 + depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || PPC || X86)
46476 + help
46477 + Non-executable pages and mprotect() restrictions are effective
46478 + in preventing the introduction of new executable code into an
46479 + attacked task's address space. There remain only two venues
46480 + for this kind of attack: if the attacker can execute already
46481 + existing code in the attacked task then he can either have it
46482 + create and mmap() a file containing his code or have it mmap()
46483 + an already existing ELF library that does not have position
46484 + independent code in it and use mprotect() on it to make it
46485 + writable and copy his code there. While protecting against
46486 + the former approach is beyond PaX, the latter can be prevented
46487 + by having only PIC ELF libraries on one's system (which do not
46488 + need to relocate their code). If you are sure this is your case,
46489 + then enable this option otherwise be careful as you may not even
46490 + be able to boot or log on your system (for example, some PAM
46491 + modules are erroneously compiled as non-PIC by default).
46492 +
46493 + NOTE: if you are using dynamic ELF executables (as suggested
46494 + when using ASLR) then you must have made sure that you linked
46495 + your files using the PIC version of crt1 (the et_dyn.tar.gz package
46496 + referenced there has already been updated to support this).
46497 +
46498 +config PAX_ETEXECRELOCS
46499 + bool "Allow ELF ET_EXEC text relocations"
46500 + depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
46501 + default y
46502 + help
46503 + On some architectures there are incorrectly created applications
46504 + that require text relocations and would not work without enabling
46505 + this option. If you are an alpha, ia64 or parisc user, you should
46506 + enable this option and disable it once you have made sure that
46507 + none of your applications need it.
46508 +
46509 +config PAX_EMUPLT
46510 + bool "Automatically emulate ELF PLT"
46511 + depends on PAX_MPROTECT && (ALPHA || PARISC || SPARC32 || SPARC64)
46512 + default y
46513 + help
46514 + Enabling this option will have the kernel automatically detect
46515 + and emulate the Procedure Linkage Table entries in ELF files.
46516 + On some architectures such entries are in writable memory, and
46517 + become non-executable leading to task termination. Therefore
46518 + it is mandatory that you enable this option on alpha, parisc,
46519 + sparc and sparc64, otherwise your system would not even boot.
46520 +
46521 + NOTE: this feature *does* open up a loophole in the protection
46522 + provided by the non-executable pages, therefore the proper
46523 + solution is to modify the toolchain to produce a PLT that does
46524 + not need to be writable.
46525 +
46526 +config PAX_DLRESOLVE
46527 + bool 'Emulate old glibc resolver stub'
46528 + depends on PAX_EMUPLT && (SPARC32 || SPARC64)
46529 + default n
46530 + help
46531 + This option is needed if userland has an old glibc (before 2.4)
46532 + that puts a 'save' instruction into the runtime generated resolver
46533 + stub that needs special emulation.
46534 +
46535 +config PAX_KERNEXEC
46536 + bool "Enforce non-executable kernel pages"
46537 + depends on PAX_NOEXEC && X86 && (!X86_32 || X86_WP_WORKS_OK)
46538 + help
46539 + This is the kernel land equivalent of PAGEEXEC and MPROTECT,
46540 + that is, enabling this option will make it harder to inject
46541 + and execute 'foreign' code in kernel memory itself.
46542 +
46543 +endmenu
46544 +
46545 +menu "Address Space Layout Randomization"
46546 + depends on PAX
46547 +
46548 +config PAX_ASLR
46549 + bool "Address Space Layout Randomization"
46550 + depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
46551 + help
46552 + Many if not most exploit techniques rely on the knowledge of
46553 + certain addresses in the attacked program. The following options
46554 + will allow the kernel to apply a certain amount of randomization
46555 + to specific parts of the program thereby forcing an attacker to
46556 + guess them in most cases. Any failed guess will most likely crash
46557 + the attacked program which allows the kernel to detect such attempts
46558 + and react on them. PaX itself provides no reaction mechanisms,
46559 + instead it is strongly encouraged that you make use of Nergal's
46560 + segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
46561 + (http://www.grsecurity.net/) built-in crash detection features or
46562 + develop one yourself.
46563 +
46564 + By saying Y here you can choose to randomize the following areas:
46565 + - top of the task's kernel stack
46566 + - top of the task's userland stack
46567 + - base address for mmap() requests that do not specify one
46568 + (this includes all libraries)
46569 + - base address of the main executable
46570 +
46571 + It is strongly recommended to say Y here as address space layout
46572 + randomization has negligible impact on performance yet it provides
46573 + a very effective protection.
46574 +
46575 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
46576 + this feature on a per file basis.
46577 +
46578 +config PAX_RANDKSTACK
46579 + bool "Randomize kernel stack base"
46580 + depends on PAX_ASLR && X86_TSC && X86_32
46581 + help
46582 + By saying Y here the kernel will randomize every task's kernel
46583 + stack on every system call. This will not only force an attacker
46584 + to guess it but also prevent him from making use of possible
46585 + leaked information about it.
46586 +
46587 + Since the kernel stack is a rather scarce resource, randomization
46588 + may cause unexpected stack overflows, therefore you should very
46589 + carefully test your system. Note that once enabled in the kernel
46590 + configuration, this feature cannot be disabled on a per file basis.
46591 +
46592 +config PAX_RANDUSTACK
46593 + bool "Randomize user stack base"
46594 + depends on PAX_ASLR
46595 + help
46596 + By saying Y here the kernel will randomize every task's userland
46597 + stack. The randomization is done in two steps where the second
46598 + one may apply a big amount of shift to the top of the stack and
46599 + cause problems for programs that want to use lots of memory (more
46600 + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
46601 + For this reason the second step can be controlled by 'chpax' or
46602 + 'paxctl' on a per file basis.
46603 +
46604 +config PAX_RANDMMAP
46605 + bool "Randomize mmap() base"
46606 + depends on PAX_ASLR
46607 + help
46608 + By saying Y here the kernel will use a randomized base address for
46609 + mmap() requests that do not specify one themselves. As a result
46610 + all dynamically loaded libraries will appear at random addresses
46611 + and therefore be harder to exploit by a technique where an attacker
46612 + attempts to execute library code for his purposes (e.g. spawn a
46613 + shell from an exploited program that is running at an elevated
46614 + privilege level).
46615 +
46616 + Furthermore, if a program is relinked as a dynamic ELF file, its
46617 + base address will be randomized as well, completing the full
46618 + randomization of the address space layout. Attacking such programs
46619 + becomes a guess game. You can find an example of doing this at
46620 + http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
46621 + http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
46622 +
46623 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
46624 + feature on a per file basis.
46625 +
46626 +endmenu
46627 +
46628 +menu "Miscellaneous hardening features"
46629 +
46630 +config PAX_MEMORY_SANITIZE
46631 + bool "Sanitize all freed memory"
46632 + help
46633 + By saying Y here the kernel will erase memory pages as soon as they
46634 + are freed. This in turn reduces the lifetime of data stored in the
46635 + pages, making it less likely that sensitive information such as
46636 + passwords, cryptographic secrets, etc stay in memory for too long.
46637 +
46638 + This is especially useful for programs whose runtime is short, long
46639 + lived processes and the kernel itself benefit from this as long as
46640 + they operate on whole memory pages and ensure timely freeing of pages
46641 + that may hold sensitive information.
46642 +
46643 + The tradeoff is performance impact, on a single CPU system kernel
46644 + compilation sees a 3% slowdown, other systems and workloads may vary
46645 + and you are advised to test this feature on your expected workload
46646 + before deploying it.
46647 +
46648 + Note that this feature does not protect data stored in live pages,
46649 + e.g., process memory swapped to disk may stay there for a long time.
46650 +
46651 +config PAX_MEMORY_UDEREF
46652 + bool "Prevent invalid userland pointer dereference"
46653 + depends on X86_32 && !UML_X86
46654 + help
46655 + By saying Y here the kernel will be prevented from dereferencing
46656 + userland pointers in contexts where the kernel expects only kernel
46657 + pointers. This is both a useful runtime debugging feature and a
46658 + security measure that prevents exploiting a class of kernel bugs.
46659 +
46660 + The tradeoff is that some virtualization solutions may experience
46661 + a huge slowdown and therefore you should not enable this feature
46662 + for kernels meant to run in such environments. Whether a given VM
46663 + solution is affected or not is best determined by simply trying it
46664 + out, the performance impact will be obvious right on boot as this
46665 + mechanism engages from very early on. A good rule of thumb is that
46666 + VMs running on CPUs without hardware virtualization support (i.e.,
46667 + the majority of IA-32 CPUs) will likely experience the slowdown.
46668 +
46669 +config PAX_REFCOUNT
46670 + bool "Prevent various kernel object reference counter overflows"
46671 + depends on GRKERNSEC && (X86 || SPARC64)
46672 + help
46673 + By saying Y here the kernel will detect and prevent overflowing
46674 + various (but not all) kinds of object reference counters. Such
46675 + overflows can normally occur due to bugs only and are often, if
46676 + not always, exploitable.
46677 +
46678 + The tradeoff is that data structures protected by an overflowed
46679 + refcount will never be freed and therefore will leak memory. Note
46680 + that this leak also happens even without this protection but in
46681 + that case the overflow can eventually trigger the freeing of the
46682 + data structure while it is still being used elsewhere, resulting
46683 + in the exploitable situation that this feature prevents.
46684 +
46685 + Since this has a negligible performance impact, you should enable
46686 + this feature.
46687 +
46688 +config PAX_USERCOPY
46689 + bool "Bounds check heap object copies between kernel and userland"
46690 + depends on X86 || PPC32 || PPC64 || SPARC32 || SPARC64
46691 + depends on GRKERNSEC && (SLAB || SLUB || SLOB)
46692 + help
46693 + By saying Y here the kernel will enforce the size of heap objects
46694 + when they are copied in either direction between the kernel and
46695 + userland, even if only a part of the heap object is copied.
46696 +
46697 + Specifically, this checking prevents information leaking from the
46698 + kernel heap during kernel to userland copies (if the kernel heap
46699 + object is otherwise fully initialized) and prevents kernel heap
46700 + overflows during userland to kernel copies.
46701 +
46702 + Note that the current implementation provides the strictest checks
46703 + for the SLUB allocator.
46704 +
46705 + Since this has a negligible performance impact, you should enable
46706 + this feature.
46707 +endmenu
46708 +
46709 +endmenu
46710 +
46711 config KEYS
46712 bool "Enable access key retention support"
46713 help
46714 diff -urNp linux-2.6.31.1/security/min_addr.c linux-2.6.31.1/security/min_addr.c
46715 --- linux-2.6.31.1/security/min_addr.c 2009-09-24 11:45:25.000000000 -0400
46716 +++ linux-2.6.31.1/security/min_addr.c 2009-10-01 20:12:45.000000000 -0400
46717 @@ -14,6 +14,7 @@ unsigned long dac_mmap_min_addr = CONFIG
46718 */
46719 static void update_mmap_min_addr(void)
46720 {
46721 +#ifndef SPARC
46722 #ifdef CONFIG_LSM_MMAP_MIN_ADDR
46723 if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR)
46724 mmap_min_addr = dac_mmap_min_addr;
46725 @@ -22,6 +23,7 @@ static void update_mmap_min_addr(void)
46726 #else
46727 mmap_min_addr = dac_mmap_min_addr;
46728 #endif
46729 +#endif
46730 }
46731
46732 /*
46733 diff -urNp linux-2.6.31.1/security/smack/smackfs.c linux-2.6.31.1/security/smack/smackfs.c
46734 --- linux-2.6.31.1/security/smack/smackfs.c 2009-09-24 11:45:25.000000000 -0400
46735 +++ linux-2.6.31.1/security/smack/smackfs.c 2009-10-01 20:12:45.000000000 -0400
46736 @@ -187,7 +187,7 @@ static void load_seq_stop(struct seq_fil
46737 /* No-op */
46738 }
46739
46740 -static struct seq_operations load_seq_ops = {
46741 +static const struct seq_operations load_seq_ops = {
46742 .start = load_seq_start,
46743 .next = load_seq_next,
46744 .show = load_seq_show,
46745 @@ -503,7 +503,7 @@ static void cipso_seq_stop(struct seq_fi
46746 /* No-op */
46747 }
46748
46749 -static struct seq_operations cipso_seq_ops = {
46750 +static const struct seq_operations cipso_seq_ops = {
46751 .start = cipso_seq_start,
46752 .stop = cipso_seq_stop,
46753 .next = cipso_seq_next,
46754 @@ -697,7 +697,7 @@ static void netlbladdr_seq_stop(struct s
46755 /* No-op */
46756 }
46757
46758 -static struct seq_operations netlbladdr_seq_ops = {
46759 +static const struct seq_operations netlbladdr_seq_ops = {
46760 .start = netlbladdr_seq_start,
46761 .stop = netlbladdr_seq_stop,
46762 .next = netlbladdr_seq_next,
46763 diff -urNp linux-2.6.31.1/sound/aoa/codecs/onyx.c linux-2.6.31.1/sound/aoa/codecs/onyx.c
46764 --- linux-2.6.31.1/sound/aoa/codecs/onyx.c 2009-09-24 11:45:25.000000000 -0400
46765 +++ linux-2.6.31.1/sound/aoa/codecs/onyx.c 2009-10-01 20:12:45.000000000 -0400
46766 @@ -53,7 +53,7 @@ struct onyx {
46767 spdif_locked:1,
46768 analog_locked:1,
46769 original_mute:2;
46770 - int open_count;
46771 + atomic_t open_count;
46772 struct codec_info *codec_info;
46773
46774 /* mutex serializes concurrent access to the device
46775 @@ -752,7 +752,7 @@ static int onyx_open(struct codec_info_i
46776 struct onyx *onyx = cii->codec_data;
46777
46778 mutex_lock(&onyx->mutex);
46779 - onyx->open_count++;
46780 + atomic_inc(&onyx->open_count);
46781 mutex_unlock(&onyx->mutex);
46782
46783 return 0;
46784 @@ -764,8 +764,7 @@ static int onyx_close(struct codec_info_
46785 struct onyx *onyx = cii->codec_data;
46786
46787 mutex_lock(&onyx->mutex);
46788 - onyx->open_count--;
46789 - if (!onyx->open_count)
46790 + if (atomic_dec_and_test(&onyx->open_count))
46791 onyx->spdif_locked = onyx->analog_locked = 0;
46792 mutex_unlock(&onyx->mutex);
46793
46794 diff -urNp linux-2.6.31.1/sound/core/oss/pcm_oss.c linux-2.6.31.1/sound/core/oss/pcm_oss.c
46795 --- linux-2.6.31.1/sound/core/oss/pcm_oss.c 2009-09-24 11:45:25.000000000 -0400
46796 +++ linux-2.6.31.1/sound/core/oss/pcm_oss.c 2009-10-01 20:12:45.000000000 -0400
46797 @@ -2943,8 +2943,8 @@ static void snd_pcm_oss_proc_done(struct
46798 }
46799 }
46800 #else /* !CONFIG_SND_VERBOSE_PROCFS */
46801 -#define snd_pcm_oss_proc_init(pcm)
46802 -#define snd_pcm_oss_proc_done(pcm)
46803 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
46804 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
46805 #endif /* CONFIG_SND_VERBOSE_PROCFS */
46806
46807 /*
46808 diff -urNp linux-2.6.31.1/sound/core/seq/seq_lock.h linux-2.6.31.1/sound/core/seq/seq_lock.h
46809 --- linux-2.6.31.1/sound/core/seq/seq_lock.h 2009-09-24 11:45:25.000000000 -0400
46810 +++ linux-2.6.31.1/sound/core/seq/seq_lock.h 2009-10-01 20:12:45.000000000 -0400
46811 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
46812 #else /* SMP || CONFIG_SND_DEBUG */
46813
46814 typedef spinlock_t snd_use_lock_t; /* dummy */
46815 -#define snd_use_lock_init(lockp) /**/
46816 -#define snd_use_lock_use(lockp) /**/
46817 -#define snd_use_lock_free(lockp) /**/
46818 -#define snd_use_lock_sync(lockp) /**/
46819 +#define snd_use_lock_init(lockp) do {} while (0)
46820 +#define snd_use_lock_use(lockp) do {} while (0)
46821 +#define snd_use_lock_free(lockp) do {} while (0)
46822 +#define snd_use_lock_sync(lockp) do {} while (0)
46823
46824 #endif /* SMP || CONFIG_SND_DEBUG */
46825
46826 diff -urNp linux-2.6.31.1/sound/drivers/mts64.c linux-2.6.31.1/sound/drivers/mts64.c
46827 --- linux-2.6.31.1/sound/drivers/mts64.c 2009-09-24 11:45:25.000000000 -0400
46828 +++ linux-2.6.31.1/sound/drivers/mts64.c 2009-10-01 20:12:45.000000000 -0400
46829 @@ -65,7 +65,7 @@ struct mts64 {
46830 struct pardevice *pardev;
46831 int pardev_claimed;
46832
46833 - int open_count;
46834 + atomic_t open_count;
46835 int current_midi_output_port;
46836 int current_midi_input_port;
46837 u8 mode[MTS64_NUM_INPUT_PORTS];
46838 @@ -695,7 +695,7 @@ static int snd_mts64_rawmidi_open(struct
46839 {
46840 struct mts64 *mts = substream->rmidi->private_data;
46841
46842 - if (mts->open_count == 0) {
46843 + if (atomic_read(&mts->open_count) == 0) {
46844 /* We don't need a spinlock here, because this is just called
46845 if the device has not been opened before.
46846 So there aren't any IRQs from the device */
46847 @@ -703,7 +703,7 @@ static int snd_mts64_rawmidi_open(struct
46848
46849 msleep(50);
46850 }
46851 - ++(mts->open_count);
46852 + atomic_inc(&mts->open_count);
46853
46854 return 0;
46855 }
46856 @@ -713,8 +713,7 @@ static int snd_mts64_rawmidi_close(struc
46857 struct mts64 *mts = substream->rmidi->private_data;
46858 unsigned long flags;
46859
46860 - --(mts->open_count);
46861 - if (mts->open_count == 0) {
46862 + if (atomic_dec_return(&mts->open_count) == 0) {
46863 /* We need the spinlock_irqsave here because we can still
46864 have IRQs at this point */
46865 spin_lock_irqsave(&mts->lock, flags);
46866 @@ -723,8 +722,8 @@ static int snd_mts64_rawmidi_close(struc
46867
46868 msleep(500);
46869
46870 - } else if (mts->open_count < 0)
46871 - mts->open_count = 0;
46872 + } else if (atomic_read(&mts->open_count) < 0)
46873 + atomic_set(&mts->open_count, 0);
46874
46875 return 0;
46876 }
46877 diff -urNp linux-2.6.31.1/sound/drivers/portman2x4.c linux-2.6.31.1/sound/drivers/portman2x4.c
46878 --- linux-2.6.31.1/sound/drivers/portman2x4.c 2009-09-24 11:45:25.000000000 -0400
46879 +++ linux-2.6.31.1/sound/drivers/portman2x4.c 2009-10-01 20:12:45.000000000 -0400
46880 @@ -83,7 +83,7 @@ struct portman {
46881 struct pardevice *pardev;
46882 int pardev_claimed;
46883
46884 - int open_count;
46885 + atomic_t open_count;
46886 int mode[PORTMAN_NUM_INPUT_PORTS];
46887 struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS];
46888 };
46889 diff -urNp linux-2.6.31.1/sound/pci/ac97/ac97_patch.c linux-2.6.31.1/sound/pci/ac97/ac97_patch.c
46890 --- linux-2.6.31.1/sound/pci/ac97/ac97_patch.c 2009-09-24 11:45:25.000000000 -0400
46891 +++ linux-2.6.31.1/sound/pci/ac97/ac97_patch.c 2009-10-01 20:12:45.000000000 -0400
46892 @@ -1501,7 +1501,7 @@ static const struct snd_ac97_res_table a
46893 { AC97_VIDEO, 0x9f1f },
46894 { AC97_AUX, 0x9f1f },
46895 { AC97_PCM, 0x9f1f },
46896 - { } /* terminator */
46897 + { 0, 0 } /* terminator */
46898 };
46899
46900 static int patch_ad1819(struct snd_ac97 * ac97)
46901 @@ -3876,7 +3876,7 @@ static struct snd_ac97_res_table lm4550_
46902 { AC97_AUX, 0x1f1f },
46903 { AC97_PCM, 0x1f1f },
46904 { AC97_REC_GAIN, 0x0f0f },
46905 - { } /* terminator */
46906 + { 0, 0 } /* terminator */
46907 };
46908
46909 static int patch_lm4550(struct snd_ac97 *ac97)
46910 diff -urNp linux-2.6.31.1/sound/pci/ens1370.c linux-2.6.31.1/sound/pci/ens1370.c
46911 --- linux-2.6.31.1/sound/pci/ens1370.c 2009-09-24 11:45:25.000000000 -0400
46912 +++ linux-2.6.31.1/sound/pci/ens1370.c 2009-10-01 20:12:45.000000000 -0400
46913 @@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
46914 { PCI_VDEVICE(ENSONIQ, 0x5880), 0, }, /* ES1373 - CT5880 */
46915 { PCI_VDEVICE(ECTIVA, 0x8938), 0, }, /* Ectiva EV1938 */
46916 #endif
46917 - { 0, }
46918 + { 0, 0, 0, 0, 0, 0, 0 }
46919 };
46920
46921 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
46922 diff -urNp linux-2.6.31.1/sound/pci/intel8x0.c linux-2.6.31.1/sound/pci/intel8x0.c
46923 --- linux-2.6.31.1/sound/pci/intel8x0.c 2009-09-24 11:45:25.000000000 -0400
46924 +++ linux-2.6.31.1/sound/pci/intel8x0.c 2009-10-01 20:12:45.000000000 -0400
46925 @@ -444,7 +444,7 @@ static struct pci_device_id snd_intel8x0
46926 { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */
46927 { PCI_VDEVICE(AMD, 0x7445), DEVICE_INTEL }, /* AMD768 */
46928 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
46929 - { 0, }
46930 + { 0, 0, 0, 0, 0, 0, 0 }
46931 };
46932
46933 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
46934 @@ -2105,7 +2105,7 @@ static struct ac97_quirk ac97_quirks[] _
46935 .type = AC97_TUNE_HP_ONLY
46936 },
46937 #endif
46938 - { } /* terminator */
46939 + { 0, 0, 0, 0, NULL, 0 } /* terminator */
46940 };
46941
46942 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
46943 diff -urNp linux-2.6.31.1/sound/pci/intel8x0m.c linux-2.6.31.1/sound/pci/intel8x0m.c
46944 --- linux-2.6.31.1/sound/pci/intel8x0m.c 2009-09-24 11:45:25.000000000 -0400
46945 +++ linux-2.6.31.1/sound/pci/intel8x0m.c 2009-10-01 20:12:45.000000000 -0400
46946 @@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
46947 { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */
46948 { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
46949 #endif
46950 - { 0, }
46951 + { 0, 0, 0, 0, 0, 0, 0 }
46952 };
46953
46954 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
46955 @@ -1264,7 +1264,7 @@ static struct shortname_table {
46956 { 0x5455, "ALi M5455" },
46957 { 0x746d, "AMD AMD8111" },
46958 #endif
46959 - { 0 },
46960 + { 0, NULL },
46961 };
46962
46963 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
46964 diff -urNp linux-2.6.31.1/sound/usb/usx2y/us122l.c linux-2.6.31.1/sound/usb/usx2y/us122l.c
46965 --- linux-2.6.31.1/sound/usb/usx2y/us122l.c 2009-09-24 11:45:25.000000000 -0400
46966 +++ linux-2.6.31.1/sound/usb/usx2y/us122l.c 2009-10-01 20:12:45.000000000 -0400
46967 @@ -154,7 +154,7 @@ static void usb_stream_hwdep_vm_close(st
46968 snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
46969 }
46970
46971 -static struct vm_operations_struct usb_stream_hwdep_vm_ops = {
46972 +static const struct vm_operations_struct usb_stream_hwdep_vm_ops = {
46973 .open = usb_stream_hwdep_vm_open,
46974 .fault = usb_stream_hwdep_vm_fault,
46975 .close = usb_stream_hwdep_vm_close,
46976 diff -urNp linux-2.6.31.1/sound/usb/usx2y/usX2Yhwdep.c linux-2.6.31.1/sound/usb/usx2y/usX2Yhwdep.c
46977 --- linux-2.6.31.1/sound/usb/usx2y/usX2Yhwdep.c 2009-09-24 11:45:25.000000000 -0400
46978 +++ linux-2.6.31.1/sound/usb/usx2y/usX2Yhwdep.c 2009-10-01 20:12:45.000000000 -0400
46979 @@ -53,7 +53,7 @@ static int snd_us428ctls_vm_fault(struct
46980 return 0;
46981 }
46982
46983 -static struct vm_operations_struct us428ctls_vm_ops = {
46984 +static const struct vm_operations_struct us428ctls_vm_ops = {
46985 .fault = snd_us428ctls_vm_fault,
46986 };
46987
46988 diff -urNp linux-2.6.31.1/sound/usb/usx2y/usx2yhwdeppcm.c linux-2.6.31.1/sound/usb/usx2y/usx2yhwdeppcm.c
46989 --- linux-2.6.31.1/sound/usb/usx2y/usx2yhwdeppcm.c 2009-09-24 11:45:25.000000000 -0400
46990 +++ linux-2.6.31.1/sound/usb/usx2y/usx2yhwdeppcm.c 2009-10-01 20:12:45.000000000 -0400
46991 @@ -697,7 +697,7 @@ static int snd_usX2Y_hwdep_pcm_vm_fault(
46992 }
46993
46994
46995 -static struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
46996 +static const struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
46997 .open = snd_usX2Y_hwdep_pcm_vm_open,
46998 .close = snd_usX2Y_hwdep_pcm_vm_close,
46999 .fault = snd_usX2Y_hwdep_pcm_vm_fault,
47000 diff -urNp linux-2.6.31.1/usr/gen_init_cpio.c linux-2.6.31.1/usr/gen_init_cpio.c
47001 --- linux-2.6.31.1/usr/gen_init_cpio.c 2009-09-24 11:45:25.000000000 -0400
47002 +++ linux-2.6.31.1/usr/gen_init_cpio.c 2009-10-01 20:12:45.000000000 -0400
47003 @@ -299,7 +299,7 @@ static int cpio_mkfile(const char *name,
47004 int retval;
47005 int rc = -1;
47006 int namesize;
47007 - int i;
47008 + unsigned int i;
47009
47010 mode |= S_IFREG;
47011
47012 @@ -383,9 +383,10 @@ static char *cpio_replace_env(char *new_
47013 *env_var = *expanded = '\0';
47014 strncat(env_var, start + 2, end - start - 2);
47015 strncat(expanded, new_location, start - new_location);
47016 - strncat(expanded, getenv(env_var), PATH_MAX);
47017 - strncat(expanded, end + 1, PATH_MAX);
47018 + strncat(expanded, getenv(env_var), PATH_MAX - strlen(expanded));
47019 + strncat(expanded, end + 1, PATH_MAX - strlen(expanded));
47020 strncpy(new_location, expanded, PATH_MAX);
47021 + new_location[PATH_MAX] = 0;
47022 } else
47023 break;
47024 }
47025 diff -urNp linux-2.6.31.1/virt/kvm/kvm_main.c linux-2.6.31.1/virt/kvm/kvm_main.c
47026 --- linux-2.6.31.1/virt/kvm/kvm_main.c 2009-09-24 11:45:25.000000000 -0400
47027 +++ linux-2.6.31.1/virt/kvm/kvm_main.c 2009-10-01 20:12:45.000000000 -0400
47028 @@ -2353,6 +2353,9 @@ static struct miscdevice kvm_dev = {
47029 KVM_MINOR,
47030 "kvm",
47031 &kvm_chardev_ops,
47032 + {NULL, NULL},
47033 + NULL,
47034 + NULL
47035 };
47036
47037 static void hardware_enable(void *junk)
47038 @@ -2512,7 +2515,7 @@ static int vcpu_stat_get(void *_offset,
47039
47040 DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n");
47041
47042 -static struct file_operations *stat_fops[] = {
47043 +static const struct file_operations *stat_fops[] = {
47044 [KVM_STAT_VCPU] = &vcpu_stat_fops,
47045 [KVM_STAT_VM] = &vm_stat_fops,
47046 };
47047 @@ -2584,7 +2587,7 @@ static void kvm_sched_out(struct preempt
47048 kvm_arch_vcpu_put(vcpu);
47049 }
47050
47051 -int kvm_init(void *opaque, unsigned int vcpu_size,
47052 +int kvm_init(const void *opaque, unsigned int vcpu_size,
47053 struct module *module)
47054 {
47055 int r;