]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-grsec_full.patch
- new
[packages/kernel.git] / kernel-grsec_full.patch
CommitLineData
017d2877
AM
1diff -urNp linux-2.6.30.4/arch/alpha/include/asm/atomic.h linux-2.6.30.4/arch/alpha/include/asm/atomic.h
2--- linux-2.6.30.4/arch/alpha/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
3+++ linux-2.6.30.4/arch/alpha/include/asm/atomic.h 2009-07-30 09:48:09.872868955 -0400
de855c5d
AM
4@@ -246,6 +246,9 @@ static __inline__ int atomic64_add_unles
5 #define atomic64_dec_and_test(v) (atomic64_sub_return(1, (v)) == 0)
6
7 #define atomic_inc(v) atomic_add(1,(v))
8+#define atomic_inc_unchecked(v) atomic_inc(v)
9+#define atomic_add_unchecked(i,v) atomic_add((i),(v))
10+#define atomic_sub_unchecked(i,v) atomic_sub((i),(v))
11 #define atomic64_inc(v) atomic64_add(1,(v))
12
13 #define atomic_dec(v) atomic_sub(1,(v))
017d2877
AM
14diff -urNp linux-2.6.30.4/arch/alpha/include/asm/elf.h linux-2.6.30.4/arch/alpha/include/asm/elf.h
15--- linux-2.6.30.4/arch/alpha/include/asm/elf.h 2009-07-24 17:47:51.000000000 -0400
16+++ linux-2.6.30.4/arch/alpha/include/asm/elf.h 2009-07-30 09:48:09.873636524 -0400
2380c486
JR
17@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
18
19 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
20
21+#ifdef CONFIG_PAX_ASLR
22+#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
23+
24+#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
25+#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
26+#endif
27+
28 /* $0 is set by ld.so to a pointer to a function which might be
29 registered using atexit. This provides a mean for the dynamic
30 linker to call DT_FINI functions for shared libraries that have
017d2877
AM
31diff -urNp linux-2.6.30.4/arch/alpha/include/asm/kmap_types.h linux-2.6.30.4/arch/alpha/include/asm/kmap_types.h
32--- linux-2.6.30.4/arch/alpha/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
33+++ linux-2.6.30.4/arch/alpha/include/asm/kmap_types.h 2009-07-30 09:48:09.873636524 -0400
2380c486
JR
34@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
35 D(10) KM_IRQ1,
36 D(11) KM_SOFTIRQ0,
37 D(12) KM_SOFTIRQ1,
38-D(13) KM_TYPE_NR
39+D(13) KM_CLEARPAGE,
40+D(14) KM_TYPE_NR
41 };
42
43 #undef D
017d2877
AM
44diff -urNp linux-2.6.30.4/arch/alpha/include/asm/pgtable.h linux-2.6.30.4/arch/alpha/include/asm/pgtable.h
45--- linux-2.6.30.4/arch/alpha/include/asm/pgtable.h 2009-07-24 17:47:51.000000000 -0400
46+++ linux-2.6.30.4/arch/alpha/include/asm/pgtable.h 2009-07-30 09:48:09.874706218 -0400
2380c486
JR
47@@ -101,6 +101,17 @@ struct vm_area_struct;
48 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
49 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
50 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
51+
52+#ifdef CONFIG_PAX_PAGEEXEC
53+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
54+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
55+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
56+#else
57+# define PAGE_SHARED_NOEXEC PAGE_SHARED
58+# define PAGE_COPY_NOEXEC PAGE_COPY
59+# define PAGE_READONLY_NOEXEC PAGE_READONLY
60+#endif
61+
62 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
63
64 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
017d2877
AM
65diff -urNp linux-2.6.30.4/arch/alpha/kernel/module.c linux-2.6.30.4/arch/alpha/kernel/module.c
66--- linux-2.6.30.4/arch/alpha/kernel/module.c 2009-07-24 17:47:51.000000000 -0400
67+++ linux-2.6.30.4/arch/alpha/kernel/module.c 2009-07-30 09:48:09.875723461 -0400
2380c486
JR
68@@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
69
70 /* The small sections were sorted to the end of the segment.
71 The following should definitely cover them. */
72- gp = (u64)me->module_core + me->core_size - 0x8000;
73+ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
74 got = sechdrs[me->arch.gotsecindex].sh_addr;
75
76 for (i = 0; i < n; i++) {
017d2877
AM
77diff -urNp linux-2.6.30.4/arch/alpha/kernel/osf_sys.c linux-2.6.30.4/arch/alpha/kernel/osf_sys.c
78--- linux-2.6.30.4/arch/alpha/kernel/osf_sys.c 2009-07-24 17:47:51.000000000 -0400
79+++ linux-2.6.30.4/arch/alpha/kernel/osf_sys.c 2009-07-30 09:48:09.875723461 -0400
80@@ -1215,6 +1215,10 @@ arch_get_unmapped_area(struct file *filp
2380c486
JR
81 merely specific addresses, but regions of memory -- perhaps
82 this feature should be incorporated into all ports? */
83
84+#ifdef CONFIG_PAX_RANDMMAP
85+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
86+#endif
87+
88 if (addr) {
89 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
90 if (addr != (unsigned long) -ENOMEM)
017d2877 91@@ -1222,8 +1226,8 @@ arch_get_unmapped_area(struct file *filp
2380c486
JR
92 }
93
94 /* Next, try allocating at TASK_UNMAPPED_BASE. */
95- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
96- len, limit);
97+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
98+
99 if (addr != (unsigned long) -ENOMEM)
100 return addr;
101
017d2877
AM
102diff -urNp linux-2.6.30.4/arch/alpha/mm/fault.c linux-2.6.30.4/arch/alpha/mm/fault.c
103--- linux-2.6.30.4/arch/alpha/mm/fault.c 2009-07-24 17:47:51.000000000 -0400
104+++ linux-2.6.30.4/arch/alpha/mm/fault.c 2009-07-30 09:48:09.876636955 -0400
2380c486
JR
105@@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
106 __reload_thread(pcb);
107 }
108
109+#ifdef CONFIG_PAX_PAGEEXEC
110+/*
111+ * PaX: decide what to do with offenders (regs->pc = fault address)
112+ *
113+ * returns 1 when task should be killed
114+ * 2 when patched PLT trampoline was detected
115+ * 3 when unpatched PLT trampoline was detected
116+ */
117+static int pax_handle_fetch_fault(struct pt_regs *regs)
118+{
119+
120+#ifdef CONFIG_PAX_EMUPLT
121+ int err;
122+
123+ do { /* PaX: patched PLT emulation #1 */
124+ unsigned int ldah, ldq, jmp;
125+
126+ err = get_user(ldah, (unsigned int *)regs->pc);
127+ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
128+ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
129+
130+ if (err)
131+ break;
132+
133+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
134+ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
135+ jmp == 0x6BFB0000U)
136+ {
137+ unsigned long r27, addr;
138+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
139+ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
140+
141+ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
142+ err = get_user(r27, (unsigned long *)addr);
143+ if (err)
144+ break;
145+
146+ regs->r27 = r27;
147+ regs->pc = r27;
148+ return 2;
149+ }
150+ } while (0);
151+
152+ do { /* PaX: patched PLT emulation #2 */
153+ unsigned int ldah, lda, br;
154+
155+ err = get_user(ldah, (unsigned int *)regs->pc);
156+ err |= get_user(lda, (unsigned int *)(regs->pc+4));
157+ err |= get_user(br, (unsigned int *)(regs->pc+8));
158+
159+ if (err)
160+ break;
161+
162+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
163+ (lda & 0xFFFF0000U) == 0xA77B0000U &&
164+ (br & 0xFFE00000U) == 0xC3E00000U)
165+ {
166+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
167+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
168+ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
169+
170+ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
171+ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
172+ return 2;
173+ }
174+ } while (0);
175+
176+ do { /* PaX: unpatched PLT emulation */
177+ unsigned int br;
178+
179+ err = get_user(br, (unsigned int *)regs->pc);
180+
181+ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
182+ unsigned int br2, ldq, nop, jmp;
183+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
184+
185+ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
186+ err = get_user(br2, (unsigned int *)addr);
187+ err |= get_user(ldq, (unsigned int *)(addr+4));
188+ err |= get_user(nop, (unsigned int *)(addr+8));
189+ err |= get_user(jmp, (unsigned int *)(addr+12));
190+ err |= get_user(resolver, (unsigned long *)(addr+16));
191+
192+ if (err)
193+ break;
194+
195+ if (br2 == 0xC3600000U &&
196+ ldq == 0xA77B000CU &&
197+ nop == 0x47FF041FU &&
198+ jmp == 0x6B7B0000U)
199+ {
200+ regs->r28 = regs->pc+4;
201+ regs->r27 = addr+16;
202+ regs->pc = resolver;
203+ return 3;
204+ }
205+ }
206+ } while (0);
207+#endif
208+
209+ return 1;
210+}
211+
212+void pax_report_insns(void *pc, void *sp)
213+{
214+ unsigned long i;
215+
216+ printk(KERN_ERR "PAX: bytes at PC: ");
217+ for (i = 0; i < 5; i++) {
218+ unsigned int c;
219+ if (get_user(c, (unsigned int *)pc+i))
220+ printk(KERN_CONT "???????? ");
221+ else
222+ printk(KERN_CONT "%08x ", c);
223+ }
224+ printk("\n");
225+}
226+#endif
227
228 /*
229 * This routine handles page faults. It determines the address,
230@@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
231 good_area:
232 si_code = SEGV_ACCERR;
233 if (cause < 0) {
234- if (!(vma->vm_flags & VM_EXEC))
235+ if (!(vma->vm_flags & VM_EXEC)) {
236+
237+#ifdef CONFIG_PAX_PAGEEXEC
238+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
239+ goto bad_area;
240+
241+ up_read(&mm->mmap_sem);
242+ switch (pax_handle_fetch_fault(regs)) {
243+
244+#ifdef CONFIG_PAX_EMUPLT
245+ case 2:
246+ case 3:
247+ return;
248+#endif
249+
250+ }
251+ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
252+ do_group_exit(SIGKILL);
253+#else
254 goto bad_area;
255+#endif
256+
257+ }
258 } else if (!cause) {
259 /* Allow reads even for write-only mappings */
260 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
017d2877
AM
261diff -urNp linux-2.6.30.4/arch/arm/include/asm/atomic.h linux-2.6.30.4/arch/arm/include/asm/atomic.h
262--- linux-2.6.30.4/arch/arm/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
263+++ linux-2.6.30.4/arch/arm/include/asm/atomic.h 2009-07-30 09:48:09.876636955 -0400
264@@ -235,6 +235,9 @@ static inline int atomic_add_unless(atom
265
266 #define atomic_inc(v) atomic_add(1, v)
267 #define atomic_dec(v) atomic_sub(1, v)
268+#define atomic_inc_unchecked(v) atomic_inc(v)
269+#define atomic_add_unchecked(i, v) atomic_add(i, v)
270+#define atomic_sub_unchecked(i, v) atomic_sub(i, v)
de855c5d
AM
271
272 #define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
273 #define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
017d2877
AM
274diff -urNp linux-2.6.30.4/arch/arm/include/asm/elf.h linux-2.6.30.4/arch/arm/include/asm/elf.h
275--- linux-2.6.30.4/arch/arm/include/asm/elf.h 2009-07-24 17:47:51.000000000 -0400
276+++ linux-2.6.30.4/arch/arm/include/asm/elf.h 2009-07-30 09:48:09.877630671 -0400
277@@ -103,7 +103,14 @@ extern int arm_elf_read_implies_exec(con
2380c486
JR
278 the loader. We need to make sure that it is out of the way of the program
279 that it will "exec", and that there is sufficient room for the brk. */
280
281-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
282+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
283+
284+#ifdef CONFIG_PAX_ASLR
285+#define PAX_ELF_ET_DYN_BASE 0x00008000UL
286+
287+#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
288+#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
289+#endif
290
291 /* When the program starts, a1 contains a pointer to a function to be
292 registered with atexit, as per the SVR4 ABI. A value of 0 means we
017d2877
AM
293diff -urNp linux-2.6.30.4/arch/arm/include/asm/kmap_types.h linux-2.6.30.4/arch/arm/include/asm/kmap_types.h
294--- linux-2.6.30.4/arch/arm/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
295+++ linux-2.6.30.4/arch/arm/include/asm/kmap_types.h 2009-07-30 09:48:09.878525050 -0400
296@@ -19,6 +19,7 @@ enum km_type {
2380c486
JR
297 KM_SOFTIRQ0,
298 KM_SOFTIRQ1,
017d2877 299 KM_L2_CACHE,
2380c486
JR
300+ KM_CLEARPAGE,
301 KM_TYPE_NR
302 };
303
017d2877
AM
304diff -urNp linux-2.6.30.4/arch/arm/include/asm/uaccess.h linux-2.6.30.4/arch/arm/include/asm/uaccess.h
305--- linux-2.6.30.4/arch/arm/include/asm/uaccess.h 2009-07-24 17:47:51.000000000 -0400
306+++ linux-2.6.30.4/arch/arm/include/asm/uaccess.h 2009-07-30 09:48:09.878525050 -0400
307@@ -398,6 +398,9 @@ extern unsigned long __must_check __strn
308
309 static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
de855c5d 310 {
017d2877
AM
311+ if ((long)n < 0)
312+ return n;
313+
de855c5d
AM
314 if (access_ok(VERIFY_READ, from, n))
315 n = __copy_from_user(to, from, n);
017d2877
AM
316 else /* security hole - plug it */
317@@ -407,6 +410,9 @@ static inline unsigned long __must_check
318
319 static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
320 {
321+ if ((long)n < 0)
322+ return n;
323+
324 if (access_ok(VERIFY_WRITE, to, n))
325 n = __copy_to_user(to, from, n);
de855c5d 326 return n;
017d2877
AM
327diff -urNp linux-2.6.30.4/arch/arm/mach-ns9xxx/clock.c linux-2.6.30.4/arch/arm/mach-ns9xxx/clock.c
328--- linux-2.6.30.4/arch/arm/mach-ns9xxx/clock.c 2009-07-24 17:47:51.000000000 -0400
329+++ linux-2.6.30.4/arch/arm/mach-ns9xxx/clock.c 2009-07-30 09:48:09.879705308 -0400
330@@ -195,7 +195,7 @@ static int clk_debugfs_open(struct inode
331 return single_open(file, clk_debugfs_show, NULL);
332 }
333
334-static struct file_operations clk_debugfs_operations = {
335+static const struct file_operations clk_debugfs_operations = {
336 .open = clk_debugfs_open,
337 .read = seq_read,
338 .llseek = seq_lseek,
339diff -urNp linux-2.6.30.4/arch/arm/mm/mmap.c linux-2.6.30.4/arch/arm/mm/mmap.c
340--- linux-2.6.30.4/arch/arm/mm/mmap.c 2009-07-24 17:47:51.000000000 -0400
341+++ linux-2.6.30.4/arch/arm/mm/mmap.c 2009-07-30 09:48:09.881684524 -0400
2380c486
JR
342@@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp
343 if (len > TASK_SIZE)
344 return -ENOMEM;
345
346+#ifdef CONFIG_PAX_RANDMMAP
347+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
348+#endif
349+
350 if (addr) {
351 if (do_align)
352 addr = COLOUR_ALIGN(addr, pgoff);
353@@ -74,10 +78,10 @@ arch_get_unmapped_area(struct file *filp
354 return addr;
355 }
356 if (len > mm->cached_hole_size) {
357- start_addr = addr = mm->free_area_cache;
358+ start_addr = addr = mm->free_area_cache;
359 } else {
360- start_addr = addr = TASK_UNMAPPED_BASE;
361- mm->cached_hole_size = 0;
362+ start_addr = addr = mm->mmap_base;
363+ mm->cached_hole_size = 0;
364 }
365
366 full_search:
367@@ -93,8 +97,8 @@ full_search:
368 * Start a new search - just in case we missed
369 * some holes.
370 */
371- if (start_addr != TASK_UNMAPPED_BASE) {
372- start_addr = addr = TASK_UNMAPPED_BASE;
373+ if (start_addr != mm->mmap_base) {
374+ start_addr = addr = mm->mmap_base;
375 mm->cached_hole_size = 0;
376 goto full_search;
377 }
017d2877
AM
378diff -urNp linux-2.6.30.4/arch/avr32/include/asm/atomic.h linux-2.6.30.4/arch/avr32/include/asm/atomic.h
379--- linux-2.6.30.4/arch/avr32/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
380+++ linux-2.6.30.4/arch/avr32/include/asm/atomic.h 2009-07-30 09:48:09.881684524 -0400
de855c5d
AM
381@@ -176,9 +176,12 @@ static inline int atomic_sub_if_positive
382 #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
383
384 #define atomic_sub(i, v) (void)atomic_sub_return(i, v)
385+#define atomic_sub_unchecked(i, v) atomic_sub((i), (v))
386 #define atomic_add(i, v) (void)atomic_add_return(i, v)
387+#define atomic_add_unchecked(i, v) atomic_add((i), (v))
388 #define atomic_dec(v) atomic_sub(1, (v))
389 #define atomic_inc(v) atomic_add(1, (v))
390+#define atomic_inc_unchecked(v) atomic_inc(v)
391
392 #define atomic_dec_return(v) atomic_sub_return(1, v)
393 #define atomic_inc_return(v) atomic_add_return(1, v)
017d2877
AM
394diff -urNp linux-2.6.30.4/arch/avr32/include/asm/elf.h linux-2.6.30.4/arch/avr32/include/asm/elf.h
395--- linux-2.6.30.4/arch/avr32/include/asm/elf.h 2009-07-24 17:47:51.000000000 -0400
396+++ linux-2.6.30.4/arch/avr32/include/asm/elf.h 2009-07-30 09:48:09.881684524 -0400
2380c486
JR
397@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
398 the loader. We need to make sure that it is out of the way of the program
399 that it will "exec", and that there is sufficient room for the brk. */
400
401-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
402+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
403
404+#ifdef CONFIG_PAX_ASLR
405+#define PAX_ELF_ET_DYN_BASE 0x00001000UL
406+
407+#define PAX_DELTA_MMAP_LEN 15
408+#define PAX_DELTA_STACK_LEN 15
409+#endif
410
411 /* This yields a mask that user programs can use to figure out what
412 instruction set this CPU supports. This could be done in user space,
017d2877
AM
413diff -urNp linux-2.6.30.4/arch/avr32/include/asm/kmap_types.h linux-2.6.30.4/arch/avr32/include/asm/kmap_types.h
414--- linux-2.6.30.4/arch/avr32/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
415+++ linux-2.6.30.4/arch/avr32/include/asm/kmap_types.h 2009-07-30 09:48:09.882650296 -0400
2380c486
JR
416@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
417 D(11) KM_IRQ1,
418 D(12) KM_SOFTIRQ0,
419 D(13) KM_SOFTIRQ1,
420-D(14) KM_TYPE_NR
421+D(14) KM_CLEARPAGE,
422+D(15) KM_TYPE_NR
423 };
424
425 #undef D
017d2877
AM
426diff -urNp linux-2.6.30.4/arch/avr32/mm/fault.c linux-2.6.30.4/arch/avr32/mm/fault.c
427--- linux-2.6.30.4/arch/avr32/mm/fault.c 2009-07-24 17:47:51.000000000 -0400
428+++ linux-2.6.30.4/arch/avr32/mm/fault.c 2009-07-30 09:48:09.882650296 -0400
2380c486
JR
429@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
430
431 int exception_trace = 1;
432
433+#ifdef CONFIG_PAX_PAGEEXEC
434+void pax_report_insns(void *pc, void *sp)
435+{
436+ unsigned long i;
437+
438+ printk(KERN_ERR "PAX: bytes at PC: ");
439+ for (i = 0; i < 20; i++) {
440+ unsigned char c;
441+ if (get_user(c, (unsigned char *)pc+i))
442+ printk(KERN_CONT "???????? ");
443+ else
444+ printk(KERN_CONT "%02x ", c);
445+ }
446+ printk("\n");
447+}
448+#endif
449+
450 /*
451 * This routine handles page faults. It determines the address and the
452 * problem, and then passes it off to one of the appropriate routines.
453@@ -157,6 +174,16 @@ bad_area:
454 up_read(&mm->mmap_sem);
455
456 if (user_mode(regs)) {
457+
458+#ifdef CONFIG_PAX_PAGEEXEC
459+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
460+ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
461+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
462+ do_group_exit(SIGKILL);
463+ }
464+ }
465+#endif
466+
467 if (exception_trace && printk_ratelimit())
468 printk("%s%s[%d]: segfault at %08lx pc %08lx "
469 "sp %08lx ecr %lu\n",
017d2877
AM
470diff -urNp linux-2.6.30.4/arch/blackfin/include/asm/atomic.h linux-2.6.30.4/arch/blackfin/include/asm/atomic.h
471--- linux-2.6.30.4/arch/blackfin/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
472+++ linux-2.6.30.4/arch/blackfin/include/asm/atomic.h 2009-07-30 09:48:09.882650296 -0400
de855c5d
AM
473@@ -178,6 +178,9 @@ static inline void atomic_set_mask(unsig
474
475 #endif /* !CONFIG_SMP */
476
477+#define atomic_add_unchecked(i, v) atomic_add((i), (v))
478+#define atomic_sub_unchecked(i, v) atomic_sub((i), (v))
479+#define atomic_inc_unchecked(v) atomic_inc((v))
480 #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
481 #define atomic_dec_return(v) atomic_sub_return(1,(v))
482 #define atomic_inc_return(v) atomic_add_return(1,(v))
017d2877
AM
483diff -urNp linux-2.6.30.4/arch/blackfin/include/asm/kmap_types.h linux-2.6.30.4/arch/blackfin/include/asm/kmap_types.h
484--- linux-2.6.30.4/arch/blackfin/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
485+++ linux-2.6.30.4/arch/blackfin/include/asm/kmap_types.h 2009-07-30 09:48:09.883618875 -0400
2380c486
JR
486@@ -15,6 +15,7 @@ enum km_type {
487 KM_IRQ1,
488 KM_SOFTIRQ0,
489 KM_SOFTIRQ1,
490+ KM_CLEARPAGE,
491 KM_TYPE_NR
492 };
493
017d2877
AM
494diff -urNp linux-2.6.30.4/arch/blackfin/mach-bf561/coreb.c linux-2.6.30.4/arch/blackfin/mach-bf561/coreb.c
495--- linux-2.6.30.4/arch/blackfin/mach-bf561/coreb.c 2009-07-24 17:47:51.000000000 -0400
496+++ linux-2.6.30.4/arch/blackfin/mach-bf561/coreb.c 2009-07-30 09:48:09.883618875 -0400
497@@ -292,7 +292,7 @@ static int coreb_ioctl(struct inode *ino
498 return retval;
499 }
500
501-static struct file_operations coreb_fops = {
502+static const struct file_operations coreb_fops = {
503 .owner = THIS_MODULE,
504 .llseek = coreb_lseek,
505 .read = coreb_read,
506diff -urNp linux-2.6.30.4/arch/cris/arch-v10/drivers/sync_serial.c linux-2.6.30.4/arch/cris/arch-v10/drivers/sync_serial.c
507--- linux-2.6.30.4/arch/cris/arch-v10/drivers/sync_serial.c 2009-07-24 17:47:51.000000000 -0400
508+++ linux-2.6.30.4/arch/cris/arch-v10/drivers/sync_serial.c 2009-07-30 09:48:09.883618875 -0400
509@@ -244,7 +244,7 @@ static unsigned sync_serial_prescale_sha
510
511 #define NUMBER_OF_PORTS 2
512
513-static struct file_operations sync_serial_fops = {
514+static const struct file_operations sync_serial_fops = {
515 .owner = THIS_MODULE,
516 .write = sync_serial_write,
517 .read = sync_serial_read,
518diff -urNp linux-2.6.30.4/arch/cris/arch-v32/drivers/mach-fs/gpio.c linux-2.6.30.4/arch/cris/arch-v32/drivers/mach-fs/gpio.c
519--- linux-2.6.30.4/arch/cris/arch-v32/drivers/mach-fs/gpio.c 2009-07-24 17:47:51.000000000 -0400
520+++ linux-2.6.30.4/arch/cris/arch-v32/drivers/mach-fs/gpio.c 2009-07-30 12:06:52.081911892 -0400
521@@ -855,7 +855,7 @@ gpio_leds_ioctl(unsigned int cmd, unsign
522 return 0;
523 }
524
525-struct file_operations gpio_fops = {
526+struct struct file_operations gpio_fops = {
527 .owner = THIS_MODULE,
528 .poll = gpio_poll,
529 .ioctl = gpio_ioctl,
530diff -urNp linux-2.6.30.4/arch/cris/include/asm/atomic.h linux-2.6.30.4/arch/cris/include/asm/atomic.h
531--- linux-2.6.30.4/arch/cris/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
532+++ linux-2.6.30.4/arch/cris/include/asm/atomic.h 2009-07-30 09:48:09.884412595 -0400
de855c5d
AM
533@@ -152,6 +152,10 @@ static inline int atomic_add_unless(atom
534 }
535 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
536
537+#define atomic_inc_unchecked(v) atomic_inc((v))
538+#define atomic_add_unchecked(i,v) atomic_add((i),(v))
539+#define atomic_sub_unchecked(i,v) atomic_sub((i),(v))
540+
541 /* Atomic operations are already serializing */
542 #define smp_mb__before_atomic_dec() barrier()
543 #define smp_mb__after_atomic_dec() barrier()
017d2877
AM
544diff -urNp linux-2.6.30.4/arch/cris/include/asm/kmap_types.h linux-2.6.30.4/arch/cris/include/asm/kmap_types.h
545--- linux-2.6.30.4/arch/cris/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
546+++ linux-2.6.30.4/arch/cris/include/asm/kmap_types.h 2009-07-30 09:48:09.884412595 -0400
2380c486
JR
547@@ -19,6 +19,7 @@ enum km_type {
548 KM_IRQ1,
549 KM_SOFTIRQ0,
550 KM_SOFTIRQ1,
551+ KM_CLEARPAGE,
552 KM_TYPE_NR
553 };
554
017d2877
AM
555diff -urNp linux-2.6.30.4/arch/frv/include/asm/atomic.h linux-2.6.30.4/arch/frv/include/asm/atomic.h
556--- linux-2.6.30.4/arch/frv/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
557+++ linux-2.6.30.4/arch/frv/include/asm/atomic.h 2009-07-30 09:48:09.885412202 -0400
558@@ -114,6 +114,10 @@ static inline void atomic_dec(atomic_t *
559 atomic_sub_return(1, v);
560 }
561
562+#define atomic_inc_unchecked(v) atomic_inc(v)
563+#define atomic_add_unchecked(i,v) atomic_add((i),(v))
564+#define atomic_sub_unchecked(i,v) atomic_sub((i),(v))
565+
566 #define atomic_dec_return(v) atomic_sub_return(1, (v))
567 #define atomic_inc_return(v) atomic_add_return(1, (v))
568
569diff -urNp linux-2.6.30.4/arch/frv/include/asm/kmap_types.h linux-2.6.30.4/arch/frv/include/asm/kmap_types.h
570--- linux-2.6.30.4/arch/frv/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
571+++ linux-2.6.30.4/arch/frv/include/asm/kmap_types.h 2009-07-30 09:48:09.885412202 -0400
572@@ -23,6 +23,7 @@ enum km_type {
573 KM_IRQ1,
574 KM_SOFTIRQ0,
575 KM_SOFTIRQ1,
576+ KM_CLEARPAGE,
577 KM_TYPE_NR
578 };
579
580diff -urNp linux-2.6.30.4/arch/h8300/include/asm/atomic.h linux-2.6.30.4/arch/h8300/include/asm/atomic.h
581--- linux-2.6.30.4/arch/h8300/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
582+++ linux-2.6.30.4/arch/h8300/include/asm/atomic.h 2009-07-30 09:48:09.885412202 -0400
de855c5d
AM
583@@ -26,6 +26,7 @@ static __inline__ int atomic_add_return(
584 }
585
586 #define atomic_add(i, v) atomic_add_return(i, v)
587+#define atomic_add_unchecked(i, v) atomic_add((i), (v))
588 #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
589
590 static __inline__ int atomic_sub_return(int i, atomic_t *v)
591@@ -38,6 +39,7 @@ static __inline__ int atomic_sub_return(
592 }
593
594 #define atomic_sub(i, v) atomic_sub_return(i, v)
595+#define atomic_subUnchecked(i, v) atomic_sub(i, v)
596 #define atomic_sub_and_test(i,v) (atomic_sub_return(i, v) == 0)
597
598 static __inline__ int atomic_inc_return(atomic_t *v)
599@@ -51,6 +53,7 @@ static __inline__ int atomic_inc_return(
600 }
601
602 #define atomic_inc(v) atomic_inc_return(v)
603+#define atomic_inc_unchecked(v) atomic_inc(v)
604
605 /*
606 * atomic_inc_and_test - increment and test
017d2877
AM
607diff -urNp linux-2.6.30.4/arch/h8300/include/asm/kmap_types.h linux-2.6.30.4/arch/h8300/include/asm/kmap_types.h
608--- linux-2.6.30.4/arch/h8300/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
609+++ linux-2.6.30.4/arch/h8300/include/asm/kmap_types.h 2009-07-30 09:48:09.885412202 -0400
2380c486
JR
610@@ -15,6 +15,7 @@ enum km_type {
611 KM_IRQ1,
612 KM_SOFTIRQ0,
613 KM_SOFTIRQ1,
614+ KM_CLEARPAGE,
615 KM_TYPE_NR
616 };
617
017d2877
AM
618diff -urNp linux-2.6.30.4/arch/ia64/ia32/binfmt_elf32.c linux-2.6.30.4/arch/ia64/ia32/binfmt_elf32.c
619--- linux-2.6.30.4/arch/ia64/ia32/binfmt_elf32.c 2009-07-24 17:47:51.000000000 -0400
620+++ linux-2.6.30.4/arch/ia64/ia32/binfmt_elf32.c 2009-07-30 09:48:09.886522893 -0400
2380c486
JR
621@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
622
623 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
624
625+#ifdef CONFIG_PAX_ASLR
626+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
627+
628+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
629+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
630+#endif
631+
632 /* Ugly but avoids duplication */
633 #include "../../../fs/binfmt_elf.c"
634
017d2877
AM
635@@ -69,11 +76,11 @@ ia32_install_gate_page (struct vm_area_s
636 }
637
638
639-static struct vm_operations_struct ia32_shared_page_vm_ops = {
640+static const struct vm_operations_struct ia32_shared_page_vm_ops = {
641 .fault = ia32_install_shared_page
642 };
643
644-static struct vm_operations_struct ia32_gate_page_vm_ops = {
645+static const struct vm_operations_struct ia32_gate_page_vm_ops = {
646 .fault = ia32_install_gate_page
647 };
648
649diff -urNp linux-2.6.30.4/arch/ia64/ia32/ia32priv.h linux-2.6.30.4/arch/ia64/ia32/ia32priv.h
650--- linux-2.6.30.4/arch/ia64/ia32/ia32priv.h 2009-07-24 17:47:51.000000000 -0400
651+++ linux-2.6.30.4/arch/ia64/ia32/ia32priv.h 2009-07-30 09:48:09.886522893 -0400
2380c486
JR
652@@ -296,7 +296,14 @@ typedef struct compat_siginfo {
653 #define ELF_DATA ELFDATA2LSB
654 #define ELF_ARCH EM_386
655
656-#define IA32_STACK_TOP IA32_PAGE_OFFSET
657+#ifdef CONFIG_PAX_RANDUSTACK
658+#define __IA32_DELTA_STACK (current->mm->delta_stack)
659+#else
660+#define __IA32_DELTA_STACK 0UL
661+#endif
662+
663+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
664+
665 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
666 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
667
017d2877
AM
668diff -urNp linux-2.6.30.4/arch/ia64/include/asm/atomic.h linux-2.6.30.4/arch/ia64/include/asm/atomic.h
669--- linux-2.6.30.4/arch/ia64/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
670+++ linux-2.6.30.4/arch/ia64/include/asm/atomic.h 2009-07-30 09:48:09.886522893 -0400
de855c5d
AM
671@@ -201,8 +201,11 @@ atomic64_add_negative (__s64 i, atomic64
672 #define atomic64_inc_and_test(v) (atomic64_add_return(1, (v)) == 0)
673
674 #define atomic_add(i,v) atomic_add_return((i), (v))
675+#define atomic_add_unchecked(i,v) atomic_add((i), (v))
676 #define atomic_sub(i,v) atomic_sub_return((i), (v))
677+#define atomic_sub_unchecked(i,v) atomic_sub((i), (v))
678 #define atomic_inc(v) atomic_add(1, (v))
679+#define atomic_inc_unchecked(v) atomic_inc(v)
680 #define atomic_dec(v) atomic_sub(1, (v))
681
682 #define atomic64_add(i,v) atomic64_add_return((i), (v))
017d2877
AM
683diff -urNp linux-2.6.30.4/arch/ia64/include/asm/elf.h linux-2.6.30.4/arch/ia64/include/asm/elf.h
684--- linux-2.6.30.4/arch/ia64/include/asm/elf.h 2009-07-24 17:47:51.000000000 -0400
685+++ linux-2.6.30.4/arch/ia64/include/asm/elf.h 2009-07-30 09:48:09.887468908 -0400
2380c486
JR
686@@ -43,6 +43,13 @@
687 */
688 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
689
690+#ifdef CONFIG_PAX_ASLR
691+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
692+
693+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
694+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
695+#endif
696+
697 #define PT_IA_64_UNWIND 0x70000001
698
699 /* IA-64 relocations: */
017d2877
AM
700diff -urNp linux-2.6.30.4/arch/ia64/include/asm/kmap_types.h linux-2.6.30.4/arch/ia64/include/asm/kmap_types.h
701--- linux-2.6.30.4/arch/ia64/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
702+++ linux-2.6.30.4/arch/ia64/include/asm/kmap_types.h 2009-07-30 09:48:09.887468908 -0400
2380c486
JR
703@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
704 D(10) KM_IRQ1,
705 D(11) KM_SOFTIRQ0,
706 D(12) KM_SOFTIRQ1,
707-D(13) KM_TYPE_NR
708+D(13) KM_CLEARPAGE,
709+D(14) KM_TYPE_NR
710 };
711
712 #undef D
017d2877
AM
713diff -urNp linux-2.6.30.4/arch/ia64/include/asm/pgtable.h linux-2.6.30.4/arch/ia64/include/asm/pgtable.h
714--- linux-2.6.30.4/arch/ia64/include/asm/pgtable.h 2009-07-24 17:47:51.000000000 -0400
715+++ linux-2.6.30.4/arch/ia64/include/asm/pgtable.h 2009-07-30 09:48:09.887468908 -0400
2380c486
JR
716@@ -143,6 +143,17 @@
717 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
718 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
719 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
720+
721+#ifdef CONFIG_PAX_PAGEEXEC
722+# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
723+# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
724+# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
725+#else
726+# define PAGE_SHARED_NOEXEC PAGE_SHARED
727+# define PAGE_READONLY_NOEXEC PAGE_READONLY
728+# define PAGE_COPY_NOEXEC PAGE_COPY
729+#endif
730+
731 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
732 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
733 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
017d2877
AM
734diff -urNp linux-2.6.30.4/arch/ia64/include/asm/uaccess.h linux-2.6.30.4/arch/ia64/include/asm/uaccess.h
735--- linux-2.6.30.4/arch/ia64/include/asm/uaccess.h 2009-07-24 17:47:51.000000000 -0400
736+++ linux-2.6.30.4/arch/ia64/include/asm/uaccess.h 2009-07-30 11:10:48.660249525 -0400
de855c5d
AM
737@@ -257,7 +257,7 @@ __copy_from_user (void *to, const void _
738 const void *__cu_from = (from); \
739 long __cu_len = (n); \
740 \
741- if (__access_ok(__cu_to, __cu_len, get_fs())) \
742+ if (__cu_len > 0 && __cu_len <= INT_MAX && __access_ok(__cu_to, __cu_len, get_fs())) \
743 __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \
744 __cu_len; \
745 })
746@@ -269,7 +269,7 @@ __copy_from_user (void *to, const void _
747 long __cu_len = (n); \
748 \
749 __chk_user_ptr(__cu_from); \
750- if (__access_ok(__cu_from, __cu_len, get_fs())) \
751+ if (__cu_len > 0 && __cu_len <= INT_MAX && __access_ok(__cu_from, __cu_len, get_fs())) \
752 __cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len); \
753 __cu_len; \
754 })
017d2877
AM
755diff -urNp linux-2.6.30.4/arch/ia64/kernel/module.c linux-2.6.30.4/arch/ia64/kernel/module.c
756--- linux-2.6.30.4/arch/ia64/kernel/module.c 2009-07-24 17:47:51.000000000 -0400
757+++ linux-2.6.30.4/arch/ia64/kernel/module.c 2009-07-30 09:48:09.888412729 -0400
2380c486
JR
758@@ -312,8 +312,7 @@ module_alloc (unsigned long size)
759 void
760 module_free (struct module *mod, void *module_region)
761 {
762- if (mod && mod->arch.init_unw_table &&
763- module_region == mod->module_init) {
764+ if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
765 unw_remove_unwind_table(mod->arch.init_unw_table);
766 mod->arch.init_unw_table = NULL;
767 }
017d2877 768@@ -499,15 +498,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
2380c486
JR
769 }
770
771 static inline int
772+in_init_rx (const struct module *mod, uint64_t addr)
773+{
774+ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
775+}
776+
777+static inline int
778+in_init_rw (const struct module *mod, uint64_t addr)
779+{
780+ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
781+}
782+
783+static inline int
784 in_init (const struct module *mod, uint64_t addr)
785 {
786- return addr - (uint64_t) mod->module_init < mod->init_size;
787+ return in_init_rx(mod, addr) || in_init_rw(mod, addr);
788+}
789+
790+static inline int
791+in_core_rx (const struct module *mod, uint64_t addr)
792+{
793+ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
794+}
795+
796+static inline int
797+in_core_rw (const struct module *mod, uint64_t addr)
798+{
799+ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
800 }
801
802 static inline int
803 in_core (const struct module *mod, uint64_t addr)
804 {
805- return addr - (uint64_t) mod->module_core < mod->core_size;
806+ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
807 }
808
809 static inline int
017d2877 810@@ -690,7 +713,14 @@ do_reloc (struct module *mod, uint8_t r_
2380c486
JR
811 break;
812
813 case RV_BDREL:
814- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
815+ if (in_init_rx(mod, val))
816+ val -= (uint64_t) mod->module_init_rx;
817+ else if (in_init_rw(mod, val))
818+ val -= (uint64_t) mod->module_init_rw;
819+ else if (in_core_rx(mod, val))
820+ val -= (uint64_t) mod->module_core_rx;
821+ else if (in_core_rw(mod, val))
822+ val -= (uint64_t) mod->module_core_rw;
823 break;
824
825 case RV_LTV:
017d2877 826@@ -824,15 +854,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
2380c486
JR
827 * addresses have been selected...
828 */
829 uint64_t gp;
830- if (mod->core_size > MAX_LTOFF)
831+ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
832 /*
833 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
834 * at the end of the module.
835 */
836- gp = mod->core_size - MAX_LTOFF / 2;
837+ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
838 else
839- gp = mod->core_size / 2;
840- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
841+ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
842+ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
843 mod->arch.gp = gp;
844 DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
845 }
017d2877
AM
846diff -urNp linux-2.6.30.4/arch/ia64/kernel/sys_ia64.c linux-2.6.30.4/arch/ia64/kernel/sys_ia64.c
847--- linux-2.6.30.4/arch/ia64/kernel/sys_ia64.c 2009-07-24 17:47:51.000000000 -0400
848+++ linux-2.6.30.4/arch/ia64/kernel/sys_ia64.c 2009-07-30 09:48:09.888412729 -0400
2380c486
JR
849@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
850 if (REGION_NUMBER(addr) == RGN_HPAGE)
851 addr = 0;
852 #endif
853+
854+#ifdef CONFIG_PAX_RANDMMAP
855+ if (mm->pax_flags & MF_PAX_RANDMMAP)
856+ addr = mm->free_area_cache;
857+ else
858+#endif
859+
860 if (!addr)
861 addr = mm->free_area_cache;
862
863@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
864 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
865 /* At this point: (!vma || addr < vma->vm_end). */
866 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
867- if (start_addr != TASK_UNMAPPED_BASE) {
868+ if (start_addr != mm->mmap_base) {
869 /* Start a new search --- just in case we missed some holes. */
870- addr = TASK_UNMAPPED_BASE;
871+ addr = mm->mmap_base;
872 goto full_search;
873 }
874 return -ENOMEM;
017d2877
AM
875diff -urNp linux-2.6.30.4/arch/ia64/mm/fault.c linux-2.6.30.4/arch/ia64/mm/fault.c
876--- linux-2.6.30.4/arch/ia64/mm/fault.c 2009-07-24 17:47:51.000000000 -0400
877+++ linux-2.6.30.4/arch/ia64/mm/fault.c 2009-07-30 09:48:09.889484146 -0400
2380c486
JR
878@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
879 return pte_present(pte);
880 }
881
882+#ifdef CONFIG_PAX_PAGEEXEC
883+void pax_report_insns(void *pc, void *sp)
884+{
885+ unsigned long i;
886+
887+ printk(KERN_ERR "PAX: bytes at PC: ");
888+ for (i = 0; i < 8; i++) {
889+ unsigned int c;
890+ if (get_user(c, (unsigned int *)pc+i))
891+ printk(KERN_CONT "???????? ");
892+ else
893+ printk(KERN_CONT "%08x ", c);
894+ }
895+ printk("\n");
896+}
897+#endif
898+
899 void __kprobes
900 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
901 {
902@@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
903 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
904 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
905
906- if ((vma->vm_flags & mask) != mask)
907+ if ((vma->vm_flags & mask) != mask) {
908+
909+#ifdef CONFIG_PAX_PAGEEXEC
910+ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
911+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
912+ goto bad_area;
913+
914+ up_read(&mm->mmap_sem);
915+ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
916+ do_group_exit(SIGKILL);
917+ }
918+#endif
919+
920 goto bad_area;
921
922+ }
923+
924 survive:
925 /*
926 * If for any reason at all we couldn't handle the fault, make
017d2877
AM
927diff -urNp linux-2.6.30.4/arch/ia64/mm/init.c linux-2.6.30.4/arch/ia64/mm/init.c
928--- linux-2.6.30.4/arch/ia64/mm/init.c 2009-07-24 17:47:51.000000000 -0400
929+++ linux-2.6.30.4/arch/ia64/mm/init.c 2009-07-30 09:48:09.889484146 -0400
930@@ -122,6 +122,19 @@ ia64_init_addr_space (void)
2380c486
JR
931 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
932 vma->vm_end = vma->vm_start + PAGE_SIZE;
933 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
934+
935+#ifdef CONFIG_PAX_PAGEEXEC
936+ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
937+ vma->vm_flags &= ~VM_EXEC;
938+
939+#ifdef CONFIG_PAX_MPROTECT
940+ if (current->mm->pax_flags & MF_PAX_MPROTECT)
941+ vma->vm_flags &= ~VM_MAYEXEC;
942+#endif
943+
944+ }
945+#endif
946+
947 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
948 down_write(&current->mm->mmap_sem);
949 if (insert_vm_struct(current->mm, vma)) {
017d2877
AM
950diff -urNp linux-2.6.30.4/arch/m32r/include/asm/atomic.h linux-2.6.30.4/arch/m32r/include/asm/atomic.h
951--- linux-2.6.30.4/arch/m32r/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
952+++ linux-2.6.30.4/arch/m32r/include/asm/atomic.h 2009-07-30 09:48:09.889484146 -0400
953@@ -308,6 +308,10 @@ static __inline__ void atomic_set_mask(u
954 local_irq_restore(flags);
955 }
956
957+#define atomic_inc_unchecked(v) atomic_inc(v)
958+#define atomic_add_unchecked(i,v) atomic_add((i),(v))
959+#define atomic_sub_unchecked(i,v) atomic_sub((i),(v))
960+
961 /* Atomic operations are already serializing on m32r */
962 #define smp_mb__before_atomic_dec() barrier()
963 #define smp_mb__after_atomic_dec() barrier()
964diff -urNp linux-2.6.30.4/arch/m32r/include/asm/kmap_types.h linux-2.6.30.4/arch/m32r/include/asm/kmap_types.h
965--- linux-2.6.30.4/arch/m32r/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
966+++ linux-2.6.30.4/arch/m32r/include/asm/kmap_types.h 2009-07-30 09:48:09.890443797 -0400
967@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
968 D(10) KM_IRQ1,
969 D(11) KM_SOFTIRQ0,
970 D(12) KM_SOFTIRQ1,
971-D(13) KM_TYPE_NR
972+D(13) KM_CLEARPAGE,
973+D(14) KM_TYPE_NR
974 };
975
976 #undef D
977diff -urNp linux-2.6.30.4/arch/m32r/lib/usercopy.c linux-2.6.30.4/arch/m32r/lib/usercopy.c
978--- linux-2.6.30.4/arch/m32r/lib/usercopy.c 2009-07-24 17:47:51.000000000 -0400
979+++ linux-2.6.30.4/arch/m32r/lib/usercopy.c 2009-07-30 09:48:09.890443797 -0400
980@@ -14,6 +14,9 @@
981 unsigned long
982 __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
983 {
984+ if ((long)n < 0)
985+ return n;
986+
987 prefetch(from);
988 if (access_ok(VERIFY_WRITE, to, n))
989 __copy_user(to,from,n);
990@@ -23,6 +26,9 @@ __generic_copy_to_user(void __user *to,
991 unsigned long
992 __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
993 {
994+ if ((long)n < 0)
995+ return n;
996+
de855c5d
AM
997 prefetchw(to);
998 if (access_ok(VERIFY_READ, from, n))
999 __copy_user_zeroing(to,from,n);
017d2877
AM
1000diff -urNp linux-2.6.30.4/arch/m68k/include/asm/atomic_mm.h linux-2.6.30.4/arch/m68k/include/asm/atomic_mm.h
1001--- linux-2.6.30.4/arch/m68k/include/asm/atomic_mm.h 2009-07-24 17:47:51.000000000 -0400
1002+++ linux-2.6.30.4/arch/m68k/include/asm/atomic_mm.h 2009-07-30 09:48:09.890443797 -0400
de855c5d
AM
1003@@ -186,6 +186,10 @@ static __inline__ int atomic_add_unless(
1004
1005 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
1006
1007+#define atomic_inc_unchecked(v) atomic_inc((v))
1008+#define atomic_add_unchecked(i,v) atomic_add((i),(v))
1009+#define atomic_sub_unchecked(i,v) atomic_sub((i),(v))
1010+
1011 /* Atomic operations are already serializing */
1012 #define smp_mb__before_atomic_dec() barrier()
1013 #define smp_mb__after_atomic_dec() barrier()
017d2877
AM
1014diff -urNp linux-2.6.30.4/arch/m68k/include/asm/atomic_no.h linux-2.6.30.4/arch/m68k/include/asm/atomic_no.h
1015--- linux-2.6.30.4/arch/m68k/include/asm/atomic_no.h 2009-07-24 17:47:51.000000000 -0400
1016+++ linux-2.6.30.4/arch/m68k/include/asm/atomic_no.h 2009-07-30 09:48:09.890443797 -0400
de855c5d
AM
1017@@ -151,5 +151,9 @@ static __inline__ int atomic_add_unless(
1018 #define atomic_dec_return(v) atomic_sub_return(1,(v))
1019 #define atomic_inc_return(v) atomic_add_return(1,(v))
1020
1021+#define atomic_inc_unchecked(v) atomic_inc((v))
1022+#define atomic_add_unchecked(i,v) atomic_add((i),(v))
1023+#define atomic_sub_unchecked(i,v) atomic_sub((i),(v))
1024+
1025 #include <asm-generic/atomic.h>
1026 #endif /* __ARCH_M68KNOMMU_ATOMIC __ */
017d2877
AM
1027diff -urNp linux-2.6.30.4/arch/m68k/include/asm/kmap_types.h linux-2.6.30.4/arch/m68k/include/asm/kmap_types.h
1028--- linux-2.6.30.4/arch/m68k/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
1029+++ linux-2.6.30.4/arch/m68k/include/asm/kmap_types.h 2009-07-30 09:48:09.891413194 -0400
2380c486
JR
1030@@ -15,6 +15,7 @@ enum km_type {
1031 KM_IRQ1,
1032 KM_SOFTIRQ0,
1033 KM_SOFTIRQ1,
1034+ KM_CLEARPAGE,
1035 KM_TYPE_NR
1036 };
1037
017d2877
AM
1038diff -urNp linux-2.6.30.4/arch/mips/include/asm/atomic.h linux-2.6.30.4/arch/mips/include/asm/atomic.h
1039--- linux-2.6.30.4/arch/mips/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
1040+++ linux-2.6.30.4/arch/mips/include/asm/atomic.h 2009-07-30 09:48:09.891413194 -0400
de855c5d
AM
1041@@ -381,6 +381,9 @@ static __inline__ int atomic_add_unless(
1042 * Atomically increments @v by 1.
1043 */
1044 #define atomic_inc(v) atomic_add(1, (v))
1045+#define atomic_inc_unchecked(v) atomic_inc(v)
1046+#define atomic_add_unchecked(i, v) atomic_add((i), (v))
1047+#define atomic_sub_unchecked(i, v) atomic_sub((i), (v))
1048
1049 /*
1050 * atomic_dec - decrement and test
017d2877
AM
1051diff -urNp linux-2.6.30.4/arch/mips/include/asm/elf.h linux-2.6.30.4/arch/mips/include/asm/elf.h
1052--- linux-2.6.30.4/arch/mips/include/asm/elf.h 2009-07-24 17:47:51.000000000 -0400
1053+++ linux-2.6.30.4/arch/mips/include/asm/elf.h 2009-07-30 09:48:09.891413194 -0400
2380c486
JR
1054@@ -364,4 +364,11 @@ extern int dump_task_fpu(struct task_str
1055 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
1056 #endif
1057
1058+#ifdef CONFIG_PAX_ASLR
1059+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1060+
1061+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1062+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1063+#endif
1064+
1065 #endif /* _ASM_ELF_H */
017d2877
AM
1066diff -urNp linux-2.6.30.4/arch/mips/include/asm/kmap_types.h linux-2.6.30.4/arch/mips/include/asm/kmap_types.h
1067--- linux-2.6.30.4/arch/mips/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
1068+++ linux-2.6.30.4/arch/mips/include/asm/kmap_types.h 2009-07-30 09:48:09.892412592 -0400
2380c486
JR
1069@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
1070 D(10) KM_IRQ1,
1071 D(11) KM_SOFTIRQ0,
1072 D(12) KM_SOFTIRQ1,
1073-D(13) KM_TYPE_NR
1074+D(13) KM_CLEARPAGE,
1075+D(14) KM_TYPE_NR
1076 };
1077
1078 #undef D
017d2877
AM
1079diff -urNp linux-2.6.30.4/arch/mips/include/asm/page.h linux-2.6.30.4/arch/mips/include/asm/page.h
1080--- linux-2.6.30.4/arch/mips/include/asm/page.h 2009-07-24 17:47:51.000000000 -0400
1081+++ linux-2.6.30.4/arch/mips/include/asm/page.h 2009-07-30 09:48:09.892412592 -0400
1082@@ -85,7 +85,7 @@ extern void copy_user_highpage(struct pa
2380c486
JR
1083 #ifdef CONFIG_CPU_MIPS32
1084 typedef struct { unsigned long pte_low, pte_high; } pte_t;
1085 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
1086- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
1087+ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
1088 #else
1089 typedef struct { unsigned long long pte; } pte_t;
1090 #define pte_val(x) ((x).pte)
017d2877
AM
1091diff -urNp linux-2.6.30.4/arch/mips/include/asm/system.h linux-2.6.30.4/arch/mips/include/asm/system.h
1092--- linux-2.6.30.4/arch/mips/include/asm/system.h 2009-07-24 17:47:51.000000000 -0400
1093+++ linux-2.6.30.4/arch/mips/include/asm/system.h 2009-07-30 09:48:09.892412592 -0400
2380c486
JR
1094@@ -217,6 +217,6 @@ extern void per_cpu_trap_init(void);
1095 */
1096 #define __ARCH_WANT_UNLOCKED_CTXSW
1097
1098-extern unsigned long arch_align_stack(unsigned long sp);
1099+#define arch_align_stack(x) ((x) & ALMASK)
1100
1101 #endif /* _ASM_SYSTEM_H */
017d2877
AM
1102diff -urNp linux-2.6.30.4/arch/mips/kernel/binfmt_elfn32.c linux-2.6.30.4/arch/mips/kernel/binfmt_elfn32.c
1103--- linux-2.6.30.4/arch/mips/kernel/binfmt_elfn32.c 2009-07-24 17:47:51.000000000 -0400
1104+++ linux-2.6.30.4/arch/mips/kernel/binfmt_elfn32.c 2009-07-30 09:48:09.892412592 -0400
2380c486
JR
1105@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
1106 #undef ELF_ET_DYN_BASE
1107 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
1108
1109+#ifdef CONFIG_PAX_ASLR
1110+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1111+
1112+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1113+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1114+#endif
1115+
1116 #include <asm/processor.h>
1117 #include <linux/module.h>
1118 #include <linux/elfcore.h>
017d2877
AM
1119diff -urNp linux-2.6.30.4/arch/mips/kernel/binfmt_elfo32.c linux-2.6.30.4/arch/mips/kernel/binfmt_elfo32.c
1120--- linux-2.6.30.4/arch/mips/kernel/binfmt_elfo32.c 2009-07-24 17:47:51.000000000 -0400
1121+++ linux-2.6.30.4/arch/mips/kernel/binfmt_elfo32.c 2009-07-30 09:48:09.893444022 -0400
2380c486
JR
1122@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
1123 #undef ELF_ET_DYN_BASE
1124 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
1125
1126+#ifdef CONFIG_PAX_ASLR
1127+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1128+
1129+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1130+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1131+#endif
1132+
1133 #include <asm/processor.h>
1134 #include <linux/module.h>
1135 #include <linux/elfcore.h>
017d2877
AM
1136diff -urNp linux-2.6.30.4/arch/mips/kernel/process.c linux-2.6.30.4/arch/mips/kernel/process.c
1137--- linux-2.6.30.4/arch/mips/kernel/process.c 2009-07-24 17:47:51.000000000 -0400
1138+++ linux-2.6.30.4/arch/mips/kernel/process.c 2009-07-30 09:48:09.893444022 -0400
2380c486
JR
1139@@ -457,15 +457,3 @@ unsigned long get_wchan(struct task_stru
1140 out:
1141 return pc;
1142 }
1143-
1144-/*
1145- * Don't forget that the stack pointer must be aligned on a 8 bytes
1146- * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
1147- */
1148-unsigned long arch_align_stack(unsigned long sp)
1149-{
1150- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
1151- sp -= get_random_int() & ~PAGE_MASK;
1152-
1153- return sp & ALMASK;
1154-}
017d2877
AM
1155diff -urNp linux-2.6.30.4/arch/mips/kernel/syscall.c linux-2.6.30.4/arch/mips/kernel/syscall.c
1156--- linux-2.6.30.4/arch/mips/kernel/syscall.c 2009-07-24 17:47:51.000000000 -0400
1157+++ linux-2.6.30.4/arch/mips/kernel/syscall.c 2009-07-30 09:48:09.893444022 -0400
2380c486
JR
1158@@ -99,6 +99,11 @@ unsigned long arch_get_unmapped_area(str
1159 do_color_align = 0;
1160 if (filp || (flags & MAP_SHARED))
1161 do_color_align = 1;
1162+
1163+#ifdef CONFIG_PAX_RANDMMAP
1164+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
1165+#endif
1166+
1167 if (addr) {
1168 if (do_color_align)
1169 addr = COLOUR_ALIGN(addr, pgoff);
1170@@ -109,7 +114,7 @@ unsigned long arch_get_unmapped_area(str
1171 (!vmm || addr + len <= vmm->vm_start))
1172 return addr;
1173 }
1174- addr = TASK_UNMAPPED_BASE;
1175+ addr = current->mm->mmap_base;
1176 if (do_color_align)
1177 addr = COLOUR_ALIGN(addr, pgoff);
1178 else
017d2877
AM
1179diff -urNp linux-2.6.30.4/arch/mips/mm/fault.c linux-2.6.30.4/arch/mips/mm/fault.c
1180--- linux-2.6.30.4/arch/mips/mm/fault.c 2009-07-24 17:47:51.000000000 -0400
1181+++ linux-2.6.30.4/arch/mips/mm/fault.c 2009-07-30 09:48:09.896533953 -0400
2380c486
JR
1182@@ -26,6 +26,23 @@
1183 #include <asm/ptrace.h>
1184 #include <asm/highmem.h> /* For VMALLOC_END */
1185
1186+#ifdef CONFIG_PAX_PAGEEXEC
1187+void pax_report_insns(void *pc)
1188+{
1189+ unsigned long i;
1190+
1191+ printk(KERN_ERR "PAX: bytes at PC: ");
1192+ for (i = 0; i < 5; i++) {
1193+ unsigned int c;
1194+ if (get_user(c, (unsigned int *)pc+i))
1195+ printk(KERN_CONT "???????? ");
1196+ else
1197+ printk(KERN_CONT "%08x ", c);
1198+ }
1199+ printk("\n");
1200+}
1201+#endif
1202+
1203 /*
1204 * This routine handles page faults. It determines the address,
1205 * and the problem, and then passes it off to one of the appropriate
017d2877
AM
1206diff -urNp linux-2.6.30.4/arch/mn10300/include/asm/atomic.h linux-2.6.30.4/arch/mn10300/include/asm/atomic.h
1207--- linux-2.6.30.4/arch/mn10300/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
1208+++ linux-2.6.30.4/arch/mn10300/include/asm/atomic.h 2009-07-30 09:48:09.897612189 -0400
1209@@ -145,6 +145,10 @@ static inline void atomic_clear_mask(uns
1210 #define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v)))
1211 #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
1212
1213+#define atomic_inc_unchecked(v) atomic_inc(v)
1214+#define atomic_add_unchecked(i,v) atomic_add((i),(v))
1215+#define atomic_sub_unchecked(i,v) atomic_sub((i),(v))
1216+
1217 /* Atomic operations are already serializing on MN10300??? */
1218 #define smp_mb__before_atomic_dec() barrier()
1219 #define smp_mb__after_atomic_dec() barrier()
1220diff -urNp linux-2.6.30.4/arch/mn10300/include/asm/kmap_types.h linux-2.6.30.4/arch/mn10300/include/asm/kmap_types.h
1221--- linux-2.6.30.4/arch/mn10300/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
1222+++ linux-2.6.30.4/arch/mn10300/include/asm/kmap_types.h 2009-07-30 09:48:09.897612189 -0400
1223@@ -25,6 +25,7 @@ enum km_type {
1224 KM_IRQ1,
1225 KM_SOFTIRQ0,
1226 KM_SOFTIRQ1,
1227+ KM_CLEARPAGE,
1228 KM_TYPE_NR
1229 };
1230
1231diff -urNp linux-2.6.30.4/arch/mn10300/kernel/setup.c linux-2.6.30.4/arch/mn10300/kernel/setup.c
1232--- linux-2.6.30.4/arch/mn10300/kernel/setup.c 2009-07-24 17:47:51.000000000 -0400
1233+++ linux-2.6.30.4/arch/mn10300/kernel/setup.c 2009-07-30 09:48:09.897612189 -0400
1234@@ -285,7 +285,7 @@ static void c_stop(struct seq_file *m, v
1235 {
1236 }
1237
1238-struct seq_operations cpuinfo_op = {
1239+const struct seq_operations cpuinfo_op = {
1240 .start = c_start,
1241 .next = c_next,
1242 .stop = c_stop,
1243diff -urNp linux-2.6.30.4/arch/parisc/include/asm/atomic.h linux-2.6.30.4/arch/parisc/include/asm/atomic.h
1244--- linux-2.6.30.4/arch/parisc/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
1245+++ linux-2.6.30.4/arch/parisc/include/asm/atomic.h 2009-07-30 09:48:09.898625493 -0400
de855c5d
AM
1246@@ -223,8 +223,11 @@ static __inline__ int atomic_add_unless(
1247 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
1248
017d2877 1249 #define atomic_add(i,v) ((void)(__atomic_add_return( ((int)(i)),(v))))
de855c5d 1250+#define atomic_add_unchecked(i,v) atomic_add((i), (v))
017d2877 1251 #define atomic_sub(i,v) ((void)(__atomic_add_return(-((int)(i)),(v))))
de855c5d
AM
1252+#define atomic_sub_unchecked(i,v) atomic_sub((i), (v))
1253 #define atomic_inc(v) ((void)(__atomic_add_return( 1,(v))))
1254+#define atomic_inc_unchecked(v) atomic_inc(v)
1255 #define atomic_dec(v) ((void)(__atomic_add_return( -1,(v))))
1256
017d2877
AM
1257 #define atomic_add_return(i,v) (__atomic_add_return( ((int)(i)),(v)))
1258diff -urNp linux-2.6.30.4/arch/parisc/include/asm/elf.h linux-2.6.30.4/arch/parisc/include/asm/elf.h
1259--- linux-2.6.30.4/arch/parisc/include/asm/elf.h 2009-07-24 17:47:51.000000000 -0400
1260+++ linux-2.6.30.4/arch/parisc/include/asm/elf.h 2009-07-30 09:48:09.898625493 -0400
1261@@ -343,6 +343,13 @@ struct pt_regs; /* forward declaration..
2380c486
JR
1262
1263 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
1264
1265+#ifdef CONFIG_PAX_ASLR
1266+#define PAX_ELF_ET_DYN_BASE 0x10000UL
1267+
1268+#define PAX_DELTA_MMAP_LEN 16
1269+#define PAX_DELTA_STACK_LEN 16
1270+#endif
1271+
1272 /* This yields a mask that user programs can use to figure out what
1273 instruction set this CPU supports. This could be done in user space,
1274 but it's not easy, and we've already done it here. */
017d2877
AM
1275diff -urNp linux-2.6.30.4/arch/parisc/include/asm/kmap_types.h linux-2.6.30.4/arch/parisc/include/asm/kmap_types.h
1276--- linux-2.6.30.4/arch/parisc/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
1277+++ linux-2.6.30.4/arch/parisc/include/asm/kmap_types.h 2009-07-30 09:48:09.898625493 -0400
2380c486
JR
1278@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
1279 D(10) KM_IRQ1,
1280 D(11) KM_SOFTIRQ0,
1281 D(12) KM_SOFTIRQ1,
1282-D(13) KM_TYPE_NR
1283+D(13) KM_CLEARPAGE,
1284+D(14) KM_TYPE_NR
1285 };
1286
1287 #undef D
017d2877
AM
1288diff -urNp linux-2.6.30.4/arch/parisc/include/asm/pgtable.h linux-2.6.30.4/arch/parisc/include/asm/pgtable.h
1289--- linux-2.6.30.4/arch/parisc/include/asm/pgtable.h 2009-07-24 17:47:51.000000000 -0400
1290+++ linux-2.6.30.4/arch/parisc/include/asm/pgtable.h 2009-07-30 09:48:09.898625493 -0400
1291@@ -207,6 +207,17 @@
2380c486
JR
1292 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
1293 #define PAGE_COPY PAGE_EXECREAD
1294 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
1295+
1296+#ifdef CONFIG_PAX_PAGEEXEC
1297+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
1298+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
1299+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
1300+#else
1301+# define PAGE_SHARED_NOEXEC PAGE_SHARED
1302+# define PAGE_COPY_NOEXEC PAGE_COPY
1303+# define PAGE_READONLY_NOEXEC PAGE_READONLY
1304+#endif
1305+
1306 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
1307 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
1308 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
017d2877
AM
1309diff -urNp linux-2.6.30.4/arch/parisc/kernel/module.c linux-2.6.30.4/arch/parisc/kernel/module.c
1310--- linux-2.6.30.4/arch/parisc/kernel/module.c 2009-07-24 17:47:51.000000000 -0400
1311+++ linux-2.6.30.4/arch/parisc/kernel/module.c 2009-07-30 09:48:09.899565255 -0400
1312@@ -91,16 +91,38 @@
2380c486
JR
1313
1314 /* three functions to determine where in the module core
1315 * or init pieces the location is */
1316+static inline int in_init_rx(struct module *me, void *loc)
1317+{
1318+ return (loc >= me->module_init_rx &&
1319+ loc < (me->module_init_rx + me->init_size_rx));
1320+}
1321+
1322+static inline int in_init_rw(struct module *me, void *loc)
1323+{
1324+ return (loc >= me->module_init_rw &&
1325+ loc < (me->module_init_rw + me->init_size_rw));
1326+}
1327+
1328 static inline int in_init(struct module *me, void *loc)
1329 {
1330- return (loc >= me->module_init &&
1331- loc <= (me->module_init + me->init_size));
1332+ return in_init_rx(me, loc) || in_init_rw(me, loc);
1333+}
1334+
1335+static inline int in_core_rx(struct module *me, void *loc)
1336+{
1337+ return (loc >= me->module_core_rx &&
1338+ loc < (me->module_core_rx + me->core_size_rx));
1339+}
1340+
1341+static inline int in_core_rw(struct module *me, void *loc)
1342+{
1343+ return (loc >= me->module_core_rw &&
1344+ loc < (me->module_core_rw + me->core_size_rw));
1345 }
1346
1347 static inline int in_core(struct module *me, void *loc)
1348 {
1349- return (loc >= me->module_core &&
1350- loc <= (me->module_core + me->core_size));
1351+ return in_core_rx(me, loc) || in_core_rw(me, loc);
1352 }
1353
1354 static inline int in_local(struct module *me, void *loc)
017d2877 1355@@ -334,13 +356,13 @@ int module_frob_arch_sections(CONST Elf_
2380c486
JR
1356 }
1357
1358 /* align things a bit */
1359- me->core_size = ALIGN(me->core_size, 16);
1360- me->arch.got_offset = me->core_size;
1361- me->core_size += gots * sizeof(struct got_entry);
1362-
1363- me->core_size = ALIGN(me->core_size, 16);
1364- me->arch.fdesc_offset = me->core_size;
1365- me->core_size += fdescs * sizeof(Elf_Fdesc);
1366+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
1367+ me->arch.got_offset = me->core_size_rw;
1368+ me->core_size_rw += gots * sizeof(struct got_entry);
1369+
1370+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
1371+ me->arch.fdesc_offset = me->core_size_rw;
1372+ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
1373
1374 me->arch.got_max = gots;
1375 me->arch.fdesc_max = fdescs;
017d2877 1376@@ -358,7 +380,7 @@ static Elf64_Word get_got(struct module
2380c486
JR
1377
1378 BUG_ON(value == 0);
1379
1380- got = me->module_core + me->arch.got_offset;
1381+ got = me->module_core_rw + me->arch.got_offset;
1382 for (i = 0; got[i].addr; i++)
1383 if (got[i].addr == value)
1384 goto out;
017d2877 1385@@ -376,7 +398,7 @@ static Elf64_Word get_got(struct module
2380c486
JR
1386 #ifdef CONFIG_64BIT
1387 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
1388 {
1389- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
1390+ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
1391
1392 if (!value) {
1393 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
017d2877 1394@@ -394,7 +416,7 @@ static Elf_Addr get_fdesc(struct module
2380c486
JR
1395
1396 /* Create new one */
1397 fdesc->addr = value;
1398- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
1399+ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1400 return (Elf_Addr)fdesc;
1401 }
1402 #endif /* CONFIG_64BIT */
017d2877 1403@@ -810,7 +832,7 @@ register_unwind_table(struct module *me,
2380c486
JR
1404
1405 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
1406 end = table + sechdrs[me->arch.unwind_section].sh_size;
1407- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
1408+ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1409
1410 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
1411 me->arch.unwind_section, table, end, gp);
017d2877
AM
1412diff -urNp linux-2.6.30.4/arch/parisc/kernel/sys_parisc.c linux-2.6.30.4/arch/parisc/kernel/sys_parisc.c
1413--- linux-2.6.30.4/arch/parisc/kernel/sys_parisc.c 2009-07-24 17:47:51.000000000 -0400
1414+++ linux-2.6.30.4/arch/parisc/kernel/sys_parisc.c 2009-07-30 09:48:09.899565255 -0400
2380c486
JR
1415@@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
1416 if (flags & MAP_FIXED)
1417 return addr;
1418 if (!addr)
1419- addr = TASK_UNMAPPED_BASE;
1420+ addr = current->mm->mmap_base;
1421
1422 if (filp) {
1423 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
017d2877
AM
1424diff -urNp linux-2.6.30.4/arch/parisc/kernel/traps.c linux-2.6.30.4/arch/parisc/kernel/traps.c
1425--- linux-2.6.30.4/arch/parisc/kernel/traps.c 2009-07-24 17:47:51.000000000 -0400
1426+++ linux-2.6.30.4/arch/parisc/kernel/traps.c 2009-07-30 09:48:09.900676754 -0400
1427@@ -734,9 +734,7 @@ void notrace handle_interruption(int cod
2380c486
JR
1428
1429 down_read(&current->mm->mmap_sem);
1430 vma = find_vma(current->mm,regs->iaoq[0]);
1431- if (vma && (regs->iaoq[0] >= vma->vm_start)
1432- && (vma->vm_flags & VM_EXEC)) {
1433-
1434+ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
1435 fault_address = regs->iaoq[0];
1436 fault_space = regs->iasq[0];
1437
017d2877
AM
1438diff -urNp linux-2.6.30.4/arch/parisc/mm/fault.c linux-2.6.30.4/arch/parisc/mm/fault.c
1439--- linux-2.6.30.4/arch/parisc/mm/fault.c 2009-07-24 17:47:51.000000000 -0400
1440+++ linux-2.6.30.4/arch/parisc/mm/fault.c 2009-07-30 09:48:09.900676754 -0400
2380c486
JR
1441@@ -16,6 +16,7 @@
1442 #include <linux/sched.h>
1443 #include <linux/interrupt.h>
1444 #include <linux/module.h>
1445+#include <linux/unistd.h>
1446
1447 #include <asm/uaccess.h>
1448 #include <asm/traps.h>
1449@@ -53,7 +54,7 @@ DEFINE_PER_CPU(struct exception_data, ex
1450 static unsigned long
1451 parisc_acctyp(unsigned long code, unsigned int inst)
1452 {
1453- if (code == 6 || code == 16)
1454+ if (code == 6 || code == 7 || code == 16)
1455 return VM_EXEC;
1456
1457 switch (inst & 0xf0000000) {
1458@@ -139,6 +140,116 @@ parisc_acctyp(unsigned long code, unsign
1459 }
1460 #endif
1461
1462+#ifdef CONFIG_PAX_PAGEEXEC
1463+/*
1464+ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
1465+ *
1466+ * returns 1 when task should be killed
1467+ * 2 when rt_sigreturn trampoline was detected
1468+ * 3 when unpatched PLT trampoline was detected
1469+ */
1470+static int pax_handle_fetch_fault(struct pt_regs *regs)
1471+{
1472+
1473+#ifdef CONFIG_PAX_EMUPLT
1474+ int err;
1475+
1476+ do { /* PaX: unpatched PLT emulation */
1477+ unsigned int bl, depwi;
1478+
1479+ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
1480+ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
1481+
1482+ if (err)
1483+ break;
1484+
1485+ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
1486+ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
1487+
1488+ err = get_user(ldw, (unsigned int *)addr);
1489+ err |= get_user(bv, (unsigned int *)(addr+4));
1490+ err |= get_user(ldw2, (unsigned int *)(addr+8));
1491+
1492+ if (err)
1493+ break;
1494+
1495+ if (ldw == 0x0E801096U &&
1496+ bv == 0xEAC0C000U &&
1497+ ldw2 == 0x0E881095U)
1498+ {
1499+ unsigned int resolver, map;
1500+
1501+ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
1502+ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
1503+ if (err)
1504+ break;
1505+
1506+ regs->gr[20] = instruction_pointer(regs)+8;
1507+ regs->gr[21] = map;
1508+ regs->gr[22] = resolver;
1509+ regs->iaoq[0] = resolver | 3UL;
1510+ regs->iaoq[1] = regs->iaoq[0] + 4;
1511+ return 3;
1512+ }
1513+ }
1514+ } while (0);
1515+#endif
1516+
1517+#ifdef CONFIG_PAX_EMUTRAMP
1518+
1519+#ifndef CONFIG_PAX_EMUSIGRT
1520+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
1521+ return 1;
1522+#endif
1523+
1524+ do { /* PaX: rt_sigreturn emulation */
1525+ unsigned int ldi1, ldi2, bel, nop;
1526+
1527+ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
1528+ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
1529+ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
1530+ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
1531+
1532+ if (err)
1533+ break;
1534+
1535+ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
1536+ ldi2 == 0x3414015AU &&
1537+ bel == 0xE4008200U &&
1538+ nop == 0x08000240U)
1539+ {
1540+ regs->gr[25] = (ldi1 & 2) >> 1;
1541+ regs->gr[20] = __NR_rt_sigreturn;
1542+ regs->gr[31] = regs->iaoq[1] + 16;
1543+ regs->sr[0] = regs->iasq[1];
1544+ regs->iaoq[0] = 0x100UL;
1545+ regs->iaoq[1] = regs->iaoq[0] + 4;
1546+ regs->iasq[0] = regs->sr[2];
1547+ regs->iasq[1] = regs->sr[2];
1548+ return 2;
1549+ }
1550+ } while (0);
1551+#endif
1552+
1553+ return 1;
1554+}
1555+
1556+void pax_report_insns(void *pc, void *sp)
1557+{
1558+ unsigned long i;
1559+
1560+ printk(KERN_ERR "PAX: bytes at PC: ");
1561+ for (i = 0; i < 5; i++) {
1562+ unsigned int c;
1563+ if (get_user(c, (unsigned int *)pc+i))
1564+ printk(KERN_CONT "???????? ");
1565+ else
1566+ printk(KERN_CONT "%08x ", c);
1567+ }
1568+ printk("\n");
1569+}
1570+#endif
1571+
1572 int fixup_exception(struct pt_regs *regs)
1573 {
1574 const struct exception_table_entry *fix;
1575@@ -193,8 +304,33 @@ good_area:
1576
1577 acc_type = parisc_acctyp(code,regs->iir);
1578
1579- if ((vma->vm_flags & acc_type) != acc_type)
1580+ if ((vma->vm_flags & acc_type) != acc_type) {
1581+
1582+#ifdef CONFIG_PAX_PAGEEXEC
1583+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
1584+ (address & ~3UL) == instruction_pointer(regs))
1585+ {
1586+ up_read(&mm->mmap_sem);
1587+ switch (pax_handle_fetch_fault(regs)) {
1588+
1589+#ifdef CONFIG_PAX_EMUPLT
1590+ case 3:
1591+ return;
1592+#endif
1593+
1594+#ifdef CONFIG_PAX_EMUTRAMP
1595+ case 2:
1596+ return;
1597+#endif
1598+
1599+ }
1600+ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1601+ do_group_exit(SIGKILL);
1602+ }
1603+#endif
1604+
1605 goto bad_area;
1606+ }
1607
1608 /*
1609 * If for any reason at all we couldn't handle the fault, make
017d2877
AM
1610diff -urNp linux-2.6.30.4/arch/powerpc/include/asm/atomic.h linux-2.6.30.4/arch/powerpc/include/asm/atomic.h
1611--- linux-2.6.30.4/arch/powerpc/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
1612+++ linux-2.6.30.4/arch/powerpc/include/asm/atomic.h 2009-07-30 09:48:09.900676754 -0400
de855c5d
AM
1613@@ -244,6 +244,10 @@ static __inline__ int atomic_dec_if_posi
1614 return t;
1615 }
1616
1617+#define atomic_inc_unchecked(v) atomic_inc((v))
1618+#define atomic_add_unchecked(i,v) atomic_add((i),(v))
1619+#define atomic_sub_unchecked(i,v) atomic_sub((i),(v))
1620+
1621 #define smp_mb__before_atomic_dec() smp_mb()
1622 #define smp_mb__after_atomic_dec() smp_mb()
1623 #define smp_mb__before_atomic_inc() smp_mb()
017d2877
AM
1624diff -urNp linux-2.6.30.4/arch/powerpc/include/asm/elf.h linux-2.6.30.4/arch/powerpc/include/asm/elf.h
1625--- linux-2.6.30.4/arch/powerpc/include/asm/elf.h 2009-07-24 17:47:51.000000000 -0400
1626+++ linux-2.6.30.4/arch/powerpc/include/asm/elf.h 2009-07-30 09:48:09.901536944 -0400
1627@@ -179,8 +179,19 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
1628 the loader. We need to make sure that it is out of the way of the program
1629 that it will "exec", and that there is sufficient room for the brk. */
2380c486 1630
017d2877
AM
1631-extern unsigned long randomize_et_dyn(unsigned long base);
1632-#define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000))
1633+#define ELF_ET_DYN_BASE (0x20000000)
1634+
2380c486
JR
1635+#ifdef CONFIG_PAX_ASLR
1636+#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
1637+
1638+#ifdef __powerpc64__
1639+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
1640+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
1641+#else
1642+#define PAX_DELTA_MMAP_LEN 15
1643+#define PAX_DELTA_STACK_LEN 15
1644+#endif
1645+#endif
017d2877 1646
2380c486
JR
1647 /*
1648 * Our registers are always unsigned longs, whether we're a 32 bit
017d2877
AM
1649diff -urNp linux-2.6.30.4/arch/powerpc/include/asm/kmap_types.h linux-2.6.30.4/arch/powerpc/include/asm/kmap_types.h
1650--- linux-2.6.30.4/arch/powerpc/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
1651+++ linux-2.6.30.4/arch/powerpc/include/asm/kmap_types.h 2009-07-30 09:48:09.901536944 -0400
2380c486
JR
1652@@ -26,6 +26,7 @@ enum km_type {
1653 KM_SOFTIRQ1,
1654 KM_PPC_SYNC_PAGE,
1655 KM_PPC_SYNC_ICACHE,
1656+ KM_CLEARPAGE,
1657 KM_TYPE_NR
1658 };
1659
017d2877
AM
1660diff -urNp linux-2.6.30.4/arch/powerpc/include/asm/page_64.h linux-2.6.30.4/arch/powerpc/include/asm/page_64.h
1661--- linux-2.6.30.4/arch/powerpc/include/asm/page_64.h 2009-07-24 17:47:51.000000000 -0400
1662+++ linux-2.6.30.4/arch/powerpc/include/asm/page_64.h 2009-07-30 09:48:09.902599231 -0400
2380c486
JR
1663@@ -170,15 +170,18 @@ do { \
1664 * stack by default, so in the absense of a PT_GNU_STACK program header
1665 * we turn execute permission off.
1666 */
1667-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
1668- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1669+#define VM_STACK_DEFAULT_FLAGS32 \
1670+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1671+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1672
1673 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
1674 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1675
1676+#ifndef CONFIG_PAX_PAGEEXEC
1677 #define VM_STACK_DEFAULT_FLAGS \
1678 (test_thread_flag(TIF_32BIT) ? \
1679 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
1680+#endif
1681
1682 #include <asm-generic/page.h>
1683
017d2877
AM
1684diff -urNp linux-2.6.30.4/arch/powerpc/include/asm/page.h linux-2.6.30.4/arch/powerpc/include/asm/page.h
1685--- linux-2.6.30.4/arch/powerpc/include/asm/page.h 2009-07-24 17:47:51.000000000 -0400
1686+++ linux-2.6.30.4/arch/powerpc/include/asm/page.h 2009-07-30 09:48:09.902599231 -0400
1687@@ -116,8 +116,9 @@ extern phys_addr_t kernstart_addr;
2380c486
JR
1688 * and needs to be executable. This means the whole heap ends
1689 * up being executable.
1690 */
1691-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
1692- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1693+#define VM_DATA_DEFAULT_FLAGS32 \
1694+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1695+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1696
1697 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
1698 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
017d2877
AM
1699diff -urNp linux-2.6.30.4/arch/powerpc/include/asm/uaccess.h linux-2.6.30.4/arch/powerpc/include/asm/uaccess.h
1700--- linux-2.6.30.4/arch/powerpc/include/asm/uaccess.h 2009-07-24 17:47:51.000000000 -0400
1701+++ linux-2.6.30.4/arch/powerpc/include/asm/uaccess.h 2009-07-30 11:10:48.774534063 -0400
de855c5d
AM
1702@@ -334,6 +334,9 @@ static inline unsigned long copy_from_us
1703 {
1704 unsigned long over;
1705
1706+ if (((long)n < 0) || (n > INT_MAX))
1707+ return n;
1708+
1709 if (access_ok(VERIFY_READ, from, n))
1710 return __copy_tofrom_user((__force void __user *)to, from, n);
1711 if ((unsigned long)from < TASK_SIZE) {
1712@@ -349,6 +352,9 @@ static inline unsigned long copy_to_user
1713 {
1714 unsigned long over;
1715
1716+ if (((long)n < 0) || (n > INT_MAX))
1717+ return n;
1718+
1719 if (access_ok(VERIFY_WRITE, to, n))
1720 return __copy_tofrom_user(to, (__force void __user *)from, n);
1721 if ((unsigned long)to < TASK_SIZE) {
017d2877
AM
1722diff -urNp linux-2.6.30.4/arch/powerpc/kernel/module_32.c linux-2.6.30.4/arch/powerpc/kernel/module_32.c
1723--- linux-2.6.30.4/arch/powerpc/kernel/module_32.c 2009-07-24 17:47:51.000000000 -0400
1724+++ linux-2.6.30.4/arch/powerpc/kernel/module_32.c 2009-07-30 09:48:09.903567873 -0400
2380c486
JR
1725@@ -162,7 +162,7 @@ int module_frob_arch_sections(Elf32_Ehdr
1726 me->arch.core_plt_section = i;
1727 }
1728 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
1729- printk("Module doesn't contain .plt or .init.plt sections.\n");
1730+ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
1731 return -ENOEXEC;
1732 }
1733
1734@@ -203,11 +203,16 @@ static uint32_t do_plt_call(void *locati
1735
1736 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
1737 /* Init, or core PLT? */
1738- if (location >= mod->module_core
1739- && location < mod->module_core + mod->core_size)
1740+ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
1741+ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
1742 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
1743- else
1744+ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
1745+ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
1746 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
1747+ else {
1748+ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1749+ return ~0UL;
1750+ }
1751
1752 /* Find this entry, or if that fails, the next avail. entry */
1753 while (entry->jump[0]) {
017d2877
AM
1754diff -urNp linux-2.6.30.4/arch/powerpc/kernel/process.c linux-2.6.30.4/arch/powerpc/kernel/process.c
1755--- linux-2.6.30.4/arch/powerpc/kernel/process.c 2009-07-24 17:47:51.000000000 -0400
1756+++ linux-2.6.30.4/arch/powerpc/kernel/process.c 2009-07-30 09:48:09.903567873 -0400
1757@@ -1147,36 +1147,3 @@ unsigned long arch_align_stack(unsigned
1758 sp -= get_random_int() & ~PAGE_MASK;
1759 return sp & ~0xf;
1760 }
1761-
1762-static inline unsigned long brk_rnd(void)
1763-{
1764- unsigned long rnd = 0;
1765-
1766- /* 8MB for 32bit, 1GB for 64bit */
1767- if (is_32bit_task())
1768- rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
1769- else
1770- rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
1771-
1772- return rnd << PAGE_SHIFT;
1773-}
1774-
1775-unsigned long arch_randomize_brk(struct mm_struct *mm)
1776-{
1777- unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
1778-
1779- if (ret < mm->brk)
1780- return mm->brk;
1781-
1782- return ret;
1783-}
1784-
1785-unsigned long randomize_et_dyn(unsigned long base)
1786-{
1787- unsigned long ret = PAGE_ALIGN(base + brk_rnd());
1788-
1789- if (ret < base)
1790- return base;
1791-
1792- return ret;
1793-}
1794diff -urNp linux-2.6.30.4/arch/powerpc/kernel/setup-common.c linux-2.6.30.4/arch/powerpc/kernel/setup-common.c
1795--- linux-2.6.30.4/arch/powerpc/kernel/setup-common.c 2009-07-24 17:47:51.000000000 -0400
1796+++ linux-2.6.30.4/arch/powerpc/kernel/setup-common.c 2009-07-30 09:48:09.903567873 -0400
1797@@ -328,7 +328,7 @@ static void c_stop(struct seq_file *m, v
1798 {
1799 }
1800
1801-struct seq_operations cpuinfo_op = {
1802+const struct seq_operations cpuinfo_op = {
1803 .start =c_start,
1804 .next = c_next,
1805 .stop = c_stop,
1806diff -urNp linux-2.6.30.4/arch/powerpc/kernel/signal_32.c linux-2.6.30.4/arch/powerpc/kernel/signal_32.c
1807--- linux-2.6.30.4/arch/powerpc/kernel/signal_32.c 2009-07-24 17:47:51.000000000 -0400
1808+++ linux-2.6.30.4/arch/powerpc/kernel/signal_32.c 2009-07-30 09:48:09.903567873 -0400
2380c486
JR
1809@@ -857,7 +857,7 @@ int handle_rt_signal32(unsigned long sig
1810 /* Save user registers on the stack */
1811 frame = &rt_sf->uc.uc_mcontext;
1812 addr = frame;
1813- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1814+ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1815 if (save_user_regs(regs, frame, 0, 1))
1816 goto badframe;
1817 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
017d2877
AM
1818diff -urNp linux-2.6.30.4/arch/powerpc/kernel/signal_64.c linux-2.6.30.4/arch/powerpc/kernel/signal_64.c
1819--- linux-2.6.30.4/arch/powerpc/kernel/signal_64.c 2009-07-24 17:47:51.000000000 -0400
1820+++ linux-2.6.30.4/arch/powerpc/kernel/signal_64.c 2009-07-30 09:48:09.905069777 -0400
2380c486
JR
1821@@ -429,7 +429,7 @@ int handle_rt_signal64(int signr, struct
1822 current->thread.fpscr.val = 0;
1823
1824 /* Set up to return from userspace. */
1825- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1826+ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1827 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1828 } else {
1829 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
017d2877
AM
1830diff -urNp linux-2.6.30.4/arch/powerpc/kernel/vdso.c linux-2.6.30.4/arch/powerpc/kernel/vdso.c
1831--- linux-2.6.30.4/arch/powerpc/kernel/vdso.c 2009-07-24 17:47:51.000000000 -0400
1832+++ linux-2.6.30.4/arch/powerpc/kernel/vdso.c 2009-07-30 09:48:09.905069777 -0400
2380c486
JR
1833@@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
1834 vdso_base = VDSO32_MBASE;
1835 #endif
1836
1837- current->mm->context.vdso_base = 0;
1838+ current->mm->context.vdso_base = ~0UL;
1839
1840 /* vDSO has a problem and was disabled, just don't "enable" it for the
1841 * process
1842@@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
1843 */
1844 down_write(&mm->mmap_sem);
1845 vdso_base = get_unmapped_area(NULL, vdso_base,
1846- vdso_pages << PAGE_SHIFT, 0, 0);
1847+ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1848 if (IS_ERR_VALUE(vdso_base)) {
1849 rc = vdso_base;
1850 goto fail_mmapsem;
017d2877
AM
1851diff -urNp linux-2.6.30.4/arch/powerpc/kvm/timing.c linux-2.6.30.4/arch/powerpc/kvm/timing.c
1852--- linux-2.6.30.4/arch/powerpc/kvm/timing.c 2009-07-24 17:47:51.000000000 -0400
1853+++ linux-2.6.30.4/arch/powerpc/kvm/timing.c 2009-07-30 09:48:09.905069777 -0400
1854@@ -201,7 +201,7 @@ static int kvmppc_exit_timing_open(struc
1855 return single_open(file, kvmppc_exit_timing_show, inode->i_private);
1856 }
1857
1858-static struct file_operations kvmppc_exit_timing_fops = {
1859+static const struct file_operations kvmppc_exit_timing_fops = {
1860 .owner = THIS_MODULE,
1861 .open = kvmppc_exit_timing_open,
1862 .read = seq_read,
1863diff -urNp linux-2.6.30.4/arch/powerpc/lib/usercopy_64.c linux-2.6.30.4/arch/powerpc/lib/usercopy_64.c
1864--- linux-2.6.30.4/arch/powerpc/lib/usercopy_64.c 2009-07-24 17:47:51.000000000 -0400
1865+++ linux-2.6.30.4/arch/powerpc/lib/usercopy_64.c 2009-07-30 11:10:48.798471204 -0400
de855c5d
AM
1866@@ -11,6 +11,9 @@
1867
1868 unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
1869 {
1870+ if (unlikely(((long)n < 0) || (n > INT_MAX)))
1871+ return n;
1872+
1873 if (likely(access_ok(VERIFY_READ, from, n)))
1874 n = __copy_from_user(to, from, n);
1875 else
1876@@ -20,6 +23,9 @@ unsigned long copy_from_user(void *to, c
1877
1878 unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
1879 {
1880+ if (unlikely(((long)n < 0) || (n > INT_MAX)))
1881+ return n;
1882+
1883 if (likely(access_ok(VERIFY_WRITE, to, n)))
1884 n = __copy_to_user(to, from, n);
1885 return n;
017d2877
AM
1886diff -urNp linux-2.6.30.4/arch/powerpc/mm/fault.c linux-2.6.30.4/arch/powerpc/mm/fault.c
1887--- linux-2.6.30.4/arch/powerpc/mm/fault.c 2009-07-24 17:47:51.000000000 -0400
1888+++ linux-2.6.30.4/arch/powerpc/mm/fault.c 2009-07-30 09:48:09.905534132 -0400
2380c486
JR
1889@@ -29,6 +29,10 @@
1890 #include <linux/module.h>
1891 #include <linux/kprobes.h>
1892 #include <linux/kdebug.h>
1893+#include <linux/slab.h>
1894+#include <linux/pagemap.h>
1895+#include <linux/compiler.h>
1896+#include <linux/unistd.h>
1897
1898 #include <asm/firmware.h>
1899 #include <asm/page.h>
1900@@ -63,6 +67,363 @@ static inline int notify_page_fault(stru
1901 }
1902 #endif
1903
1904+#ifdef CONFIG_PAX_EMUSIGRT
1905+void pax_syscall_close(struct vm_area_struct *vma)
1906+{
1907+ vma->vm_mm->call_syscall = 0UL;
1908+}
1909+
1910+static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1911+{
1912+ unsigned int *kaddr;
1913+
1914+ vmf->page = alloc_page(GFP_HIGHUSER);
1915+ if (!vmf->page)
1916+ return VM_FAULT_OOM;
1917+
1918+ kaddr = kmap(vmf->page);
1919+ memset(kaddr, 0, PAGE_SIZE);
1920+ kaddr[0] = 0x44000002U; /* sc */
1921+ __flush_dcache_icache(kaddr);
1922+ kunmap(vmf->page);
1923+ return VM_FAULT_MAJOR;
1924+}
1925+
017d2877 1926+static const struct vm_operations_struct pax_vm_ops = {
2380c486
JR
1927+ .close = pax_syscall_close,
1928+ .fault = pax_syscall_fault
1929+};
1930+
1931+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1932+{
1933+ int ret;
1934+
1935+ vma->vm_mm = current->mm;
1936+ vma->vm_start = addr;
1937+ vma->vm_end = addr + PAGE_SIZE;
1938+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1939+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1940+ vma->vm_ops = &pax_vm_ops;
1941+
1942+ ret = insert_vm_struct(current->mm, vma);
1943+ if (ret)
1944+ return ret;
1945+
1946+ ++current->mm->total_vm;
1947+ return 0;
1948+}
1949+#endif
1950+
1951+#ifdef CONFIG_PAX_PAGEEXEC
1952+/*
1953+ * PaX: decide what to do with offenders (regs->nip = fault address)
1954+ *
1955+ * returns 1 when task should be killed
1956+ * 2 when patched GOT trampoline was detected
1957+ * 3 when patched PLT trampoline was detected
1958+ * 4 when unpatched PLT trampoline was detected
1959+ * 5 when sigreturn trampoline was detected
1960+ * 6 when rt_sigreturn trampoline was detected
1961+ */
1962+static int pax_handle_fetch_fault(struct pt_regs *regs)
1963+{
1964+
1965+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1966+ int err;
1967+#endif
1968+
1969+#ifdef CONFIG_PAX_EMUPLT
1970+ do { /* PaX: patched GOT emulation */
1971+ unsigned int blrl;
1972+
1973+ err = get_user(blrl, (unsigned int *)regs->nip);
1974+
1975+ if (!err && blrl == 0x4E800021U) {
1976+ unsigned long temp = regs->nip;
1977+
1978+ regs->nip = regs->link & 0xFFFFFFFCUL;
1979+ regs->link = temp + 4UL;
1980+ return 2;
1981+ }
1982+ } while (0);
1983+
1984+ do { /* PaX: patched PLT emulation #1 */
1985+ unsigned int b;
1986+
1987+ err = get_user(b, (unsigned int *)regs->nip);
1988+
1989+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
1990+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1991+ return 3;
1992+ }
1993+ } while (0);
1994+
1995+ do { /* PaX: unpatched PLT emulation #1 */
1996+ unsigned int li, b;
1997+
1998+ err = get_user(li, (unsigned int *)regs->nip);
1999+ err |= get_user(b, (unsigned int *)(regs->nip+4));
2000+
2001+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2002+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2003+ unsigned long addr = b | 0xFC000000UL;
2004+
2005+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2006+ err = get_user(rlwinm, (unsigned int *)addr);
2007+ err |= get_user(add, (unsigned int *)(addr+4));
2008+ err |= get_user(li2, (unsigned int *)(addr+8));
2009+ err |= get_user(addis2, (unsigned int *)(addr+12));
2010+ err |= get_user(mtctr, (unsigned int *)(addr+16));
2011+ err |= get_user(li3, (unsigned int *)(addr+20));
2012+ err |= get_user(addis3, (unsigned int *)(addr+24));
2013+ err |= get_user(bctr, (unsigned int *)(addr+28));
2014+
2015+ if (err)
2016+ break;
2017+
2018+ if (rlwinm == 0x556C083CU &&
2019+ add == 0x7D6C5A14U &&
2020+ (li2 & 0xFFFF0000U) == 0x39800000U &&
2021+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2022+ mtctr == 0x7D8903A6U &&
2023+ (li3 & 0xFFFF0000U) == 0x39800000U &&
2024+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2025+ bctr == 0x4E800420U)
2026+ {
2027+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2028+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2029+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2030+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2031+ regs->ctr += (addis2 & 0xFFFFU) << 16;
2032+ regs->nip = regs->ctr;
2033+ return 4;
2034+ }
2035+ }
2036+ } while (0);
2037+
2038+#if 0
2039+ do { /* PaX: unpatched PLT emulation #2 */
2040+ unsigned int lis, lwzu, b, bctr;
2041+
2042+ err = get_user(lis, (unsigned int *)regs->nip);
2043+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
2044+ err |= get_user(b, (unsigned int *)(regs->nip+8));
2045+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
2046+
2047+ if (err)
2048+ break;
2049+
2050+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
2051+ (lwzu & 0xU) == 0xU &&
2052+ (b & 0xFC000003U) == 0x48000000U &&
2053+ bctr == 0x4E800420U)
2054+ {
2055+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
2056+ unsigned long addr = b | 0xFC000000UL;
2057+
2058+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2059+ err = get_user(addis, (unsigned int *)addr);
2060+ err |= get_user(addi, (unsigned int *)(addr+4));
2061+ err |= get_user(rlwinm, (unsigned int *)(addr+8));
2062+ err |= get_user(add, (unsigned int *)(addr+12));
2063+ err |= get_user(li2, (unsigned int *)(addr+16));
2064+ err |= get_user(addis2, (unsigned int *)(addr+20));
2065+ err |= get_user(mtctr, (unsigned int *)(addr+24));
2066+ err |= get_user(li3, (unsigned int *)(addr+28));
2067+ err |= get_user(addis3, (unsigned int *)(addr+32));
2068+ err |= get_user(bctr, (unsigned int *)(addr+36));
2069+
2070+ if (err)
2071+ break;
2072+
2073+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2074+ (addi & 0xFFFF0000U) == 0x396B0000U &&
2075+ rlwinm == 0x556C083CU &&
2076+ add == 0x7D6C5A14U &&
2077+ (li2 & 0xFFFF0000U) == 0x39800000U &&
2078+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
2079+ mtctr == 0x7D8903A6U &&
2080+ (li3 & 0xFFFF0000U) == 0x39800000U &&
2081+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
2082+ bctr == 0x4E800420U)
2083+ {
2084+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2085+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2086+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
2087+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2088+ regs->ctr += (addis2 & 0xFFFFU) << 16;
2089+ regs->nip = regs->ctr;
2090+ return 4;
2091+ }
2092+ }
2093+ } while (0);
2094+#endif
2095+
2096+ do { /* PaX: unpatched PLT emulation #3 */
2097+ unsigned int li, b;
2098+
2099+ err = get_user(li, (unsigned int *)regs->nip);
2100+ err |= get_user(b, (unsigned int *)(regs->nip+4));
2101+
2102+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
2103+ unsigned int addis, lwz, mtctr, bctr;
2104+ unsigned long addr = b | 0xFC000000UL;
2105+
2106+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
2107+ err = get_user(addis, (unsigned int *)addr);
2108+ err |= get_user(lwz, (unsigned int *)(addr+4));
2109+ err |= get_user(mtctr, (unsigned int *)(addr+8));
2110+ err |= get_user(bctr, (unsigned int *)(addr+12));
2111+
2112+ if (err)
2113+ break;
2114+
2115+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
2116+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
2117+ mtctr == 0x7D6903A6U &&
2118+ bctr == 0x4E800420U)
2119+ {
2120+ unsigned int r11;
2121+
2122+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2123+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
2124+
2125+ err = get_user(r11, (unsigned int *)addr);
2126+ if (err)
2127+ break;
2128+
2129+ regs->gpr[PT_R11] = r11;
2130+ regs->ctr = r11;
2131+ regs->nip = r11;
2132+ return 4;
2133+ }
2134+ }
2135+ } while (0);
2136+#endif
2137+
2138+#ifdef CONFIG_PAX_EMUSIGRT
2139+ do { /* PaX: sigreturn emulation */
2140+ unsigned int li, sc;
2141+
2142+ err = get_user(li, (unsigned int *)regs->nip);
2143+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
2144+
2145+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
2146+ struct vm_area_struct *vma;
2147+ unsigned long call_syscall;
2148+
2149+ down_read(&current->mm->mmap_sem);
2150+ call_syscall = current->mm->call_syscall;
2151+ up_read(&current->mm->mmap_sem);
2152+ if (likely(call_syscall))
2153+ goto emulate;
2154+
2155+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2156+
2157+ down_write(&current->mm->mmap_sem);
2158+ if (current->mm->call_syscall) {
2159+ call_syscall = current->mm->call_syscall;
2160+ up_write(&current->mm->mmap_sem);
2161+ if (vma)
2162+ kmem_cache_free(vm_area_cachep, vma);
2163+ goto emulate;
2164+ }
2165+
2166+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2167+ if (!vma || (call_syscall & ~PAGE_MASK)) {
2168+ up_write(&current->mm->mmap_sem);
2169+ if (vma)
2170+ kmem_cache_free(vm_area_cachep, vma);
2171+ return 1;
2172+ }
2173+
2174+ if (pax_insert_vma(vma, call_syscall)) {
2175+ up_write(&current->mm->mmap_sem);
2176+ kmem_cache_free(vm_area_cachep, vma);
2177+ return 1;
2178+ }
2179+
2180+ current->mm->call_syscall = call_syscall;
2181+ up_write(&current->mm->mmap_sem);
2182+
2183+emulate:
2184+ regs->gpr[PT_R0] = __NR_sigreturn;
2185+ regs->nip = call_syscall;
2186+ return 5;
2187+ }
2188+ } while (0);
2189+
2190+ do { /* PaX: rt_sigreturn emulation */
2191+ unsigned int li, sc;
2192+
2193+ err = get_user(li, (unsigned int *)regs->nip);
2194+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
2195+
2196+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
2197+ struct vm_area_struct *vma;
2198+ unsigned int call_syscall;
2199+
2200+ down_read(&current->mm->mmap_sem);
2201+ call_syscall = current->mm->call_syscall;
2202+ up_read(&current->mm->mmap_sem);
2203+ if (likely(call_syscall))
2204+ goto rt_emulate;
2205+
2206+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2207+
2208+ down_write(&current->mm->mmap_sem);
2209+ if (current->mm->call_syscall) {
2210+ call_syscall = current->mm->call_syscall;
2211+ up_write(&current->mm->mmap_sem);
2212+ if (vma)
2213+ kmem_cache_free(vm_area_cachep, vma);
2214+ goto rt_emulate;
2215+ }
2216+
2217+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2218+ if (!vma || (call_syscall & ~PAGE_MASK)) {
2219+ up_write(&current->mm->mmap_sem);
2220+ if (vma)
2221+ kmem_cache_free(vm_area_cachep, vma);
2222+ return 1;
2223+ }
2224+
2225+ if (pax_insert_vma(vma, call_syscall)) {
2226+ up_write(&current->mm->mmap_sem);
2227+ kmem_cache_free(vm_area_cachep, vma);
2228+ return 1;
2229+ }
2230+
2231+ current->mm->call_syscall = call_syscall;
2232+ up_write(&current->mm->mmap_sem);
2233+
2234+rt_emulate:
2235+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
2236+ regs->nip = call_syscall;
2237+ return 6;
2238+ }
2239+ } while (0);
2240+#endif
2241+
2242+ return 1;
2243+}
2244+
2245+void pax_report_insns(void *pc, void *sp)
2246+{
2247+ unsigned long i;
2248+
2249+ printk(KERN_ERR "PAX: bytes at PC: ");
2250+ for (i = 0; i < 5; i++) {
2251+ unsigned int c;
2252+ if (get_user(c, (unsigned int *)pc+i))
2253+ printk(KERN_CONT "???????? ");
2254+ else
2255+ printk(KERN_CONT "%08x ", c);
2256+ }
2257+ printk("\n");
2258+}
2259+#endif
2260+
2261 /*
2262 * Check whether the instruction at regs->nip is a store using
2263 * an update addressing form which will update r1.
2264@@ -133,7 +494,7 @@ int __kprobes do_page_fault(struct pt_re
2265 * indicate errors in DSISR but can validly be set in SRR1.
2266 */
2267 if (trap == 0x400)
2268- error_code &= 0x48200000;
2269+ error_code &= 0x58200000;
2270 else
2271 is_write = error_code & DSISR_ISSTORE;
2272 #else
017d2877 2273@@ -327,6 +688,37 @@ bad_area:
2380c486
JR
2274 bad_area_nosemaphore:
2275 /* User mode accesses cause a SIGSEGV */
2276 if (user_mode(regs)) {
2277+
2278+#ifdef CONFIG_PAX_PAGEEXEC
2279+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
2280+#ifdef CONFIG_PPC64
2281+ if (is_exec && (error_code & DSISR_PROTFAULT)) {
2282+#else
2283+ if (is_exec && regs->nip == address) {
2284+#endif
2285+ switch (pax_handle_fetch_fault(regs)) {
2286+
2287+#ifdef CONFIG_PAX_EMUPLT
2288+ case 2:
2289+ case 3:
2290+ case 4:
2291+ return 0;
2292+#endif
2293+
2294+#ifdef CONFIG_PAX_EMUSIGRT
2295+ case 5:
2296+ case 6:
2297+ return 0;
2298+#endif
2299+
2300+ }
2301+
2302+ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
2303+ do_group_exit(SIGKILL);
2304+ }
2305+ }
2306+#endif
2307+
2308 _exception(SIGSEGV, regs, code, address);
2309 return 0;
2310 }
017d2877
AM
2311diff -urNp linux-2.6.30.4/arch/powerpc/mm/mmap_64.c linux-2.6.30.4/arch/powerpc/mm/mmap_64.c
2312--- linux-2.6.30.4/arch/powerpc/mm/mmap_64.c 2009-07-24 17:47:51.000000000 -0400
2313+++ linux-2.6.30.4/arch/powerpc/mm/mmap_64.c 2009-07-30 09:48:09.905534132 -0400
2314@@ -99,10 +99,22 @@ void arch_pick_mmap_layout(struct mm_str
2380c486
JR
2315 */
2316 if (mmap_is_legacy()) {
2317 mm->mmap_base = TASK_UNMAPPED_BASE;
2318+
2319+#ifdef CONFIG_PAX_RANDMMAP
2320+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2321+ mm->mmap_base += mm->delta_mmap;
2322+#endif
2323+
2324 mm->get_unmapped_area = arch_get_unmapped_area;
2325 mm->unmap_area = arch_unmap_area;
2326 } else {
2327 mm->mmap_base = mmap_base();
2328+
2329+#ifdef CONFIG_PAX_RANDMMAP
2330+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2331+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2332+#endif
2333+
2334 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2335 mm->unmap_area = arch_unmap_area_topdown;
2336 }
017d2877
AM
2337diff -urNp linux-2.6.30.4/arch/powerpc/platforms/cell/spufs/file.c linux-2.6.30.4/arch/powerpc/platforms/cell/spufs/file.c
2338--- linux-2.6.30.4/arch/powerpc/platforms/cell/spufs/file.c 2009-07-24 17:47:51.000000000 -0400
2339+++ linux-2.6.30.4/arch/powerpc/platforms/cell/spufs/file.c 2009-07-30 09:48:09.906622773 -0400
2340@@ -147,7 +147,7 @@ static int __fops ## _open(struct inode
2341 __simple_attr_check_format(__fmt, 0ull); \
2342 return spufs_attr_open(inode, file, __get, __set, __fmt); \
2343 } \
2344-static struct file_operations __fops = { \
2345+static const struct file_operations __fops = { \
2346 .owner = THIS_MODULE, \
2347 .open = __fops ## _open, \
2348 .release = spufs_attr_release, \
2349@@ -309,7 +309,7 @@ static int spufs_mem_mmap_access(struct
2350 return len;
2351 }
2352
2353-static struct vm_operations_struct spufs_mem_mmap_vmops = {
2354+static const struct vm_operations_struct spufs_mem_mmap_vmops = {
2355 .fault = spufs_mem_mmap_fault,
2356 .access = spufs_mem_mmap_access,
2357 };
2358@@ -436,7 +436,7 @@ static int spufs_cntl_mmap_fault(struct
2359 return spufs_ps_fault(vma, vmf, 0x4000, SPUFS_CNTL_MAP_SIZE);
2360 }
2361
2362-static struct vm_operations_struct spufs_cntl_mmap_vmops = {
2363+static const struct vm_operations_struct spufs_cntl_mmap_vmops = {
2364 .fault = spufs_cntl_mmap_fault,
2365 };
2366
2367@@ -1143,7 +1143,7 @@ spufs_signal1_mmap_fault(struct vm_area_
2368 #endif
2369 }
2370
2371-static struct vm_operations_struct spufs_signal1_mmap_vmops = {
2372+static const struct vm_operations_struct spufs_signal1_mmap_vmops = {
2373 .fault = spufs_signal1_mmap_fault,
2374 };
2375
2376@@ -1279,7 +1279,7 @@ spufs_signal2_mmap_fault(struct vm_area_
2377 #endif
2378 }
2379
2380-static struct vm_operations_struct spufs_signal2_mmap_vmops = {
2381+static const struct vm_operations_struct spufs_signal2_mmap_vmops = {
2382 .fault = spufs_signal2_mmap_fault,
2383 };
2384
2385@@ -1397,7 +1397,7 @@ spufs_mss_mmap_fault(struct vm_area_stru
2386 return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_MSS_MAP_SIZE);
2387 }
2388
2389-static struct vm_operations_struct spufs_mss_mmap_vmops = {
2390+static const struct vm_operations_struct spufs_mss_mmap_vmops = {
2391 .fault = spufs_mss_mmap_fault,
2392 };
2393
2394@@ -1458,7 +1458,7 @@ spufs_psmap_mmap_fault(struct vm_area_st
2395 return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_PS_MAP_SIZE);
2396 }
2397
2398-static struct vm_operations_struct spufs_psmap_mmap_vmops = {
2399+static const struct vm_operations_struct spufs_psmap_mmap_vmops = {
2400 .fault = spufs_psmap_mmap_fault,
2401 };
2402
2403@@ -1517,7 +1517,7 @@ spufs_mfc_mmap_fault(struct vm_area_stru
2404 return spufs_ps_fault(vma, vmf, 0x3000, SPUFS_MFC_MAP_SIZE);
2405 }
2406
2407-static struct vm_operations_struct spufs_mfc_mmap_vmops = {
2408+static const struct vm_operations_struct spufs_mfc_mmap_vmops = {
2409 .fault = spufs_mfc_mmap_fault,
2410 };
2411
2412diff -urNp linux-2.6.30.4/arch/powerpc/platforms/pseries/dtl.c linux-2.6.30.4/arch/powerpc/platforms/pseries/dtl.c
2413--- linux-2.6.30.4/arch/powerpc/platforms/pseries/dtl.c 2009-07-24 17:47:51.000000000 -0400
2414+++ linux-2.6.30.4/arch/powerpc/platforms/pseries/dtl.c 2009-07-30 12:06:52.084821916 -0400
2415@@ -209,7 +209,7 @@ static ssize_t dtl_file_read(struct file
2416 return n_read * sizeof(struct dtl_entry);
2417 }
2418
2419-static struct file_operations dtl_fops = {
2420+static const struct file_operations dtl_fops = {
2421 .open = dtl_file_open,
2422 .release = dtl_file_release,
2423 .read = dtl_file_read,
2424diff -urNp linux-2.6.30.4/arch/powerpc/platforms/pseries/hvCall_inst.c linux-2.6.30.4/arch/powerpc/platforms/pseries/hvCall_inst.c
2425--- linux-2.6.30.4/arch/powerpc/platforms/pseries/hvCall_inst.c 2009-07-24 17:47:51.000000000 -0400
2426+++ linux-2.6.30.4/arch/powerpc/platforms/pseries/hvCall_inst.c 2009-07-30 09:48:09.906622773 -0400
2427@@ -71,7 +71,7 @@ static int hc_show(struct seq_file *m, v
2428 return 0;
2429 }
2430
2431-static struct seq_operations hcall_inst_seq_ops = {
2432+static const struct seq_operations hcall_inst_seq_ops = {
2433 .start = hc_start,
2434 .next = hc_next,
2435 .stop = hc_stop,
2436diff -urNp linux-2.6.30.4/arch/s390/hypfs/inode.c linux-2.6.30.4/arch/s390/hypfs/inode.c
2437--- linux-2.6.30.4/arch/s390/hypfs/inode.c 2009-07-24 17:47:51.000000000 -0400
2438+++ linux-2.6.30.4/arch/s390/hypfs/inode.c 2009-07-30 09:48:09.907613298 -0400
2439@@ -41,7 +41,7 @@ struct hypfs_sb_info {
2440
2441 static const struct file_operations hypfs_file_ops;
2442 static struct file_system_type hypfs_type;
2443-static struct super_operations hypfs_s_ops;
2444+static const struct super_operations hypfs_s_ops;
2445
2446 /* start of list of all dentries, which have to be deleted on update */
2447 static struct dentry *hypfs_last_dentry;
2448@@ -476,7 +476,7 @@ static struct file_system_type hypfs_typ
2449 .kill_sb = hypfs_kill_super
2450 };
2451
2452-static struct super_operations hypfs_s_ops = {
2453+static const struct super_operations hypfs_s_ops = {
2454 .statfs = simple_statfs,
2455 .drop_inode = hypfs_drop_inode,
2456 .show_options = hypfs_show_options,
2457diff -urNp linux-2.6.30.4/arch/s390/include/asm/atomic.h linux-2.6.30.4/arch/s390/include/asm/atomic.h
2458--- linux-2.6.30.4/arch/s390/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
2459+++ linux-2.6.30.4/arch/s390/include/asm/atomic.h 2009-07-30 09:48:09.908552392 -0400
de855c5d
AM
2460@@ -82,8 +82,10 @@ static __inline__ int atomic_add_return(
2461 return __CS_LOOP(v, i, "ar");
2462 }
2463 #define atomic_add(_i, _v) atomic_add_return(_i, _v)
2464+#define atomic_add_unchecked(_i, _v) atomic_add((_i), (_v))
2465 #define atomic_add_negative(_i, _v) (atomic_add_return(_i, _v) < 0)
2466 #define atomic_inc(_v) atomic_add_return(1, _v)
2467+#define atomic_inc_unchecked(_v) atomic_inc(_v)
2468 #define atomic_inc_return(_v) atomic_add_return(1, _v)
2469 #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0)
2470
2471@@ -92,6 +94,7 @@ static __inline__ int atomic_sub_return(
2472 return __CS_LOOP(v, i, "sr");
2473 }
2474 #define atomic_sub(_i, _v) atomic_sub_return(_i, _v)
2475+#define atomic_sub_unchecked(_i, _v) atomic_sub((_i), (_v))
2476 #define atomic_sub_and_test(_i, _v) (atomic_sub_return(_i, _v) == 0)
2477 #define atomic_dec(_v) atomic_sub_return(1, _v)
2478 #define atomic_dec_return(_v) atomic_sub_return(1, _v)
017d2877
AM
2479diff -urNp linux-2.6.30.4/arch/s390/include/asm/kmap_types.h linux-2.6.30.4/arch/s390/include/asm/kmap_types.h
2480--- linux-2.6.30.4/arch/s390/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
2481+++ linux-2.6.30.4/arch/s390/include/asm/kmap_types.h 2009-07-30 09:48:09.908552392 -0400
2380c486
JR
2482@@ -16,6 +16,7 @@ enum km_type {
2483 KM_IRQ1,
2484 KM_SOFTIRQ0,
2485 KM_SOFTIRQ1,
2486+ KM_CLEARPAGE,
2487 KM_TYPE_NR
2488 };
2489
017d2877
AM
2490diff -urNp linux-2.6.30.4/arch/s390/include/asm/uaccess.h linux-2.6.30.4/arch/s390/include/asm/uaccess.h
2491--- linux-2.6.30.4/arch/s390/include/asm/uaccess.h 2009-07-24 17:47:51.000000000 -0400
2492+++ linux-2.6.30.4/arch/s390/include/asm/uaccess.h 2009-07-30 09:48:09.908552392 -0400
2493@@ -232,6 +232,10 @@ static inline unsigned long __must_check
2494 copy_to_user(void __user *to, const void *from, unsigned long n)
2495 {
de855c5d 2496 might_sleep();
017d2877
AM
2497+
2498+ if ((long)n < 0)
2499+ return n;
2500+
2501 if (access_ok(VERIFY_WRITE, to, n))
2502 n = __copy_to_user(to, from, n);
2503 return n;
2504@@ -257,6 +261,9 @@ copy_to_user(void __user *to, const void
2505 static inline unsigned long __must_check
2506 __copy_from_user(void *to, const void __user *from, unsigned long n)
2507 {
2508+ if ((long)n < 0)
2509+ return n;
2510+
2511 if (__builtin_constant_p(n) && (n <= 256))
2512 return uaccess.copy_from_user_small(n, from, to);
2513 else
2514@@ -283,6 +290,10 @@ static inline unsigned long __must_check
2515 copy_from_user(void *to, const void __user *from, unsigned long n)
2516 {
2517 might_sleep();
2518+
2519+ if ((long)n < 0)
2520+ return n;
2521+
de855c5d
AM
2522 if (access_ok(VERIFY_READ, from, n))
2523 n = __copy_from_user(to, from, n);
017d2877
AM
2524 else
2525diff -urNp linux-2.6.30.4/arch/s390/kernel/module.c linux-2.6.30.4/arch/s390/kernel/module.c
2526--- linux-2.6.30.4/arch/s390/kernel/module.c 2009-07-24 17:47:51.000000000 -0400
2527+++ linux-2.6.30.4/arch/s390/kernel/module.c 2009-07-30 09:48:09.908552392 -0400
2380c486
JR
2528@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
2529
2530 /* Increase core size by size of got & plt and set start
2531 offsets for got and plt. */
2532- me->core_size = ALIGN(me->core_size, 4);
2533- me->arch.got_offset = me->core_size;
2534- me->core_size += me->arch.got_size;
2535- me->arch.plt_offset = me->core_size;
2536- me->core_size += me->arch.plt_size;
2537+ me->core_size_rw = ALIGN(me->core_size_rw, 4);
2538+ me->arch.got_offset = me->core_size_rw;
2539+ me->core_size_rw += me->arch.got_size;
2540+ me->arch.plt_offset = me->core_size_rx;
2541+ me->core_size_rx += me->arch.plt_size;
2542 return 0;
2543 }
2544
2545@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2546 if (info->got_initialized == 0) {
2547 Elf_Addr *gotent;
2548
2549- gotent = me->module_core + me->arch.got_offset +
2550+ gotent = me->module_core_rw + me->arch.got_offset +
2551 info->got_offset;
2552 *gotent = val;
2553 info->got_initialized = 1;
2554@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2555 else if (r_type == R_390_GOTENT ||
2556 r_type == R_390_GOTPLTENT)
2557 *(unsigned int *) loc =
2558- (val + (Elf_Addr) me->module_core - loc) >> 1;
2559+ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
2560 else if (r_type == R_390_GOT64 ||
2561 r_type == R_390_GOTPLT64)
2562 *(unsigned long *) loc = val;
2563@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2564 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
2565 if (info->plt_initialized == 0) {
2566 unsigned int *ip;
2567- ip = me->module_core + me->arch.plt_offset +
2568+ ip = me->module_core_rx + me->arch.plt_offset +
2569 info->plt_offset;
2570 #ifndef CONFIG_64BIT
2571 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
017d2877
AM
2572@@ -319,7 +319,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2573 val - loc + 0xffffUL < 0x1ffffeUL) ||
2574 (r_type == R_390_PLT32DBL &&
2575 val - loc + 0xffffffffULL < 0x1fffffffeULL)))
2576- val = (Elf_Addr) me->module_core +
2577+ val = (Elf_Addr) me->module_core_rx +
2578 me->arch.plt_offset +
2579 info->plt_offset;
2580 val += rela->r_addend - loc;
2581@@ -341,7 +341,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2380c486
JR
2582 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
2583 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
2584 val = val + rela->r_addend -
2585- ((Elf_Addr) me->module_core + me->arch.got_offset);
2586+ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
2587 if (r_type == R_390_GOTOFF16)
2588 *(unsigned short *) loc = val;
2589 else if (r_type == R_390_GOTOFF32)
017d2877 2590@@ -351,7 +351,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2380c486
JR
2591 break;
2592 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
2593 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
2594- val = (Elf_Addr) me->module_core + me->arch.got_offset +
2595+ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
2596 rela->r_addend - loc;
2597 if (r_type == R_390_GOTPC)
2598 *(unsigned int *) loc = val;
017d2877
AM
2599diff -urNp linux-2.6.30.4/arch/sh/include/asm/atomic.h linux-2.6.30.4/arch/sh/include/asm/atomic.h
2600--- linux-2.6.30.4/arch/sh/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
2601+++ linux-2.6.30.4/arch/sh/include/asm/atomic.h 2009-07-30 09:48:09.909647067 -0400
de855c5d
AM
2602@@ -43,6 +43,9 @@
2603 #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
2604
2605 #define atomic_inc(v) atomic_add(1,(v))
2606+#define atomic_inc_unchecked(v) atomic_inc(v)
2607+#define atomic_add_unchecked(i,v) atomic_add((i),(v))
2608+#define atomic_sub_unchecked(i,v) atomic_sub((i),(v))
2609 #define atomic_dec(v) atomic_sub(1,(v))
2610
2611 #ifndef CONFIG_GUSA_RB
017d2877
AM
2612diff -urNp linux-2.6.30.4/arch/sh/include/asm/kmap_types.h linux-2.6.30.4/arch/sh/include/asm/kmap_types.h
2613--- linux-2.6.30.4/arch/sh/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
2614+++ linux-2.6.30.4/arch/sh/include/asm/kmap_types.h 2009-07-30 09:48:09.909647067 -0400
2380c486
JR
2615@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
2616 D(10) KM_IRQ1,
2617 D(11) KM_SOFTIRQ0,
2618 D(12) KM_SOFTIRQ1,
2619-D(13) KM_TYPE_NR
2620+D(13) KM_CLEARPAGE,
2621+D(14) KM_TYPE_NR
2622 };
2623
2624 #undef D
017d2877
AM
2625diff -urNp linux-2.6.30.4/arch/sparc/include/asm/atomic_32.h linux-2.6.30.4/arch/sparc/include/asm/atomic_32.h
2626--- linux-2.6.30.4/arch/sparc/include/asm/atomic_32.h 2009-07-24 17:47:51.000000000 -0400
2627+++ linux-2.6.30.4/arch/sparc/include/asm/atomic_32.h 2009-07-30 09:48:09.910522181 -0400
2628@@ -28,8 +28,11 @@ extern void atomic_set(atomic_t *, int);
de855c5d
AM
2629 #define atomic_read(v) ((v)->counter)
2630
2631 #define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v)))
2632+#define atomic_add_unchecked(i, v) atomic_add((i), (v))
2633 #define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v)))
2634+#define atomic_sub_unchecked(i, v) atomic_sub((i), (v))
2635 #define atomic_inc(v) ((void)__atomic_add_return( 1, (v)))
2636+#define atomic_inc_unchecked(v) atomic_inc(v)
2637 #define atomic_dec(v) ((void)__atomic_add_return( -1, (v)))
2638
2639 #define atomic_add_return(i, v) (__atomic_add_return( (int)(i), (v)))
017d2877
AM
2640diff -urNp linux-2.6.30.4/arch/sparc/include/asm/atomic_64.h linux-2.6.30.4/arch/sparc/include/asm/atomic_64.h
2641--- linux-2.6.30.4/arch/sparc/include/asm/atomic_64.h 2009-07-24 17:47:51.000000000 -0400
2642+++ linux-2.6.30.4/arch/sparc/include/asm/atomic_64.h 2009-07-30 09:48:09.910522181 -0400
de855c5d
AM
2643@@ -20,8 +20,10 @@
2644 #define atomic64_set(v, i) (((v)->counter) = i)
2645
2646 extern void atomic_add(int, atomic_t *);
2647+#define atomic_add_unchecked(i, v) atomic_add((i), (v))
2648 extern void atomic64_add(int, atomic64_t *);
2649 extern void atomic_sub(int, atomic_t *);
2650+#define atomic_sub_unchecked(i, v) atomic_sub((i), (v))
2651 extern void atomic64_sub(int, atomic64_t *);
2652
2653 extern int atomic_add_ret(int, atomic_t *);
2654@@ -59,6 +61,7 @@ extern int atomic64_sub_ret(int, atomic6
2655 #define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0)
2656
2657 #define atomic_inc(v) atomic_add(1, v)
2658+#define atomic_inc_unchecked(v) atomic_inc(v)
2659 #define atomic64_inc(v) atomic64_add(1, v)
2660
2661 #define atomic_dec(v) atomic_sub(1, v)
017d2877
AM
2662diff -urNp linux-2.6.30.4/arch/sparc/include/asm/elf_32.h linux-2.6.30.4/arch/sparc/include/asm/elf_32.h
2663--- linux-2.6.30.4/arch/sparc/include/asm/elf_32.h 2009-07-24 17:47:51.000000000 -0400
2664+++ linux-2.6.30.4/arch/sparc/include/asm/elf_32.h 2009-07-30 09:48:09.910522181 -0400
2380c486
JR
2665@@ -116,6 +116,13 @@ typedef struct {
2666
2667 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
2668
2669+#ifdef CONFIG_PAX_ASLR
2670+#define PAX_ELF_ET_DYN_BASE 0x10000UL
2671+
2672+#define PAX_DELTA_MMAP_LEN 16
2673+#define PAX_DELTA_STACK_LEN 16
2674+#endif
2675+
2676 /* This yields a mask that user programs can use to figure out what
2677 instruction set this cpu supports. This can NOT be done in userspace
2678 on Sparc. */
017d2877
AM
2679diff -urNp linux-2.6.30.4/arch/sparc/include/asm/elf_64.h linux-2.6.30.4/arch/sparc/include/asm/elf_64.h
2680--- linux-2.6.30.4/arch/sparc/include/asm/elf_64.h 2009-07-24 17:47:51.000000000 -0400
2681+++ linux-2.6.30.4/arch/sparc/include/asm/elf_64.h 2009-07-30 09:48:09.910522181 -0400
2380c486
JR
2682@@ -163,6 +163,12 @@ typedef struct {
2683 #define ELF_ET_DYN_BASE 0x0000010000000000UL
2684 #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
2685
2686+#ifdef CONFIG_PAX_ASLR
2687+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
2688+
2689+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
2690+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
2691+#endif
2692
2693 /* This yields a mask that user programs can use to figure out what
2694 instruction set this cpu supports. */
017d2877
AM
2695diff -urNp linux-2.6.30.4/arch/sparc/include/asm/kmap_types.h linux-2.6.30.4/arch/sparc/include/asm/kmap_types.h
2696--- linux-2.6.30.4/arch/sparc/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
2697+++ linux-2.6.30.4/arch/sparc/include/asm/kmap_types.h 2009-07-30 09:48:09.910522181 -0400
2380c486
JR
2698@@ -19,6 +19,7 @@ enum km_type {
2699 KM_IRQ1,
2700 KM_SOFTIRQ0,
2701 KM_SOFTIRQ1,
2702+ KM_CLEARPAGE,
2703 KM_TYPE_NR
2704 };
2705
017d2877
AM
2706diff -urNp linux-2.6.30.4/arch/sparc/include/asm/pgtable_32.h linux-2.6.30.4/arch/sparc/include/asm/pgtable_32.h
2707--- linux-2.6.30.4/arch/sparc/include/asm/pgtable_32.h 2009-07-24 17:47:51.000000000 -0400
2708+++ linux-2.6.30.4/arch/sparc/include/asm/pgtable_32.h 2009-07-30 09:48:09.910522181 -0400
2380c486
JR
2709@@ -43,6 +43,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
2710 BTFIXUPDEF_INT(page_none)
2711 BTFIXUPDEF_INT(page_copy)
2712 BTFIXUPDEF_INT(page_readonly)
2713+
2714+#ifdef CONFIG_PAX_PAGEEXEC
2715+BTFIXUPDEF_INT(page_shared_noexec)
2716+BTFIXUPDEF_INT(page_copy_noexec)
2717+BTFIXUPDEF_INT(page_readonly_noexec)
2718+#endif
2719+
2720 BTFIXUPDEF_INT(page_kernel)
2721
2722 #define PMD_SHIFT SUN4C_PMD_SHIFT
2723@@ -64,6 +71,16 @@ extern pgprot_t PAGE_SHARED;
2724 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
2725 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
2726
2727+#ifdef CONFIG_PAX_PAGEEXEC
2728+extern pgprot_t PAGE_SHARED_NOEXEC;
2729+# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
2730+# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
2731+#else
2732+# define PAGE_SHARED_NOEXEC PAGE_SHARED
2733+# define PAGE_COPY_NOEXEC PAGE_COPY
2734+# define PAGE_READONLY_NOEXEC PAGE_READONLY
2735+#endif
2736+
2737 extern unsigned long page_kernel;
2738
2739 #ifdef MODULE
017d2877
AM
2740diff -urNp linux-2.6.30.4/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.30.4/arch/sparc/include/asm/pgtsrmmu.h
2741--- linux-2.6.30.4/arch/sparc/include/asm/pgtsrmmu.h 2009-07-24 17:47:51.000000000 -0400
2742+++ linux-2.6.30.4/arch/sparc/include/asm/pgtsrmmu.h 2009-07-30 09:48:09.911921584 -0400
2380c486
JR
2743@@ -115,6 +115,13 @@
2744 SRMMU_EXEC | SRMMU_REF)
2745 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
2746 SRMMU_EXEC | SRMMU_REF)
2747+
2748+#ifdef CONFIG_PAX_PAGEEXEC
2749+#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
2750+#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
2751+#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
2752+#endif
2753+
2754 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
2755 SRMMU_DIRTY | SRMMU_REF)
2756
017d2877
AM
2757diff -urNp linux-2.6.30.4/arch/sparc/include/asm/uaccess_32.h linux-2.6.30.4/arch/sparc/include/asm/uaccess_32.h
2758--- linux-2.6.30.4/arch/sparc/include/asm/uaccess_32.h 2009-07-24 17:47:51.000000000 -0400
2759+++ linux-2.6.30.4/arch/sparc/include/asm/uaccess_32.h 2009-07-30 09:48:09.911921584 -0400
2760@@ -246,6 +246,9 @@ extern unsigned long __copy_user(void __
de855c5d
AM
2761
2762 static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
2763 {
017d2877
AM
2764+ if ((long)n < 0)
2765+ return n;
2766+
2767 if (n && __access_ok((unsigned long) to, n))
de855c5d
AM
2768 return __copy_user(to, (__force void __user *) from, n);
2769 else
017d2877 2770@@ -259,6 +262,9 @@ static inline unsigned long __copy_to_us
de855c5d
AM
2771
2772 static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
2773 {
017d2877
AM
2774+ if ((long)n < 0)
2775+ return n;
2776+
2777 if (n && __access_ok((unsigned long) from, n))
de855c5d
AM
2778 return __copy_user((__force void __user *) to, from, n);
2779 else
017d2877
AM
2780@@ -267,6 +273,9 @@ static inline unsigned long copy_from_us
2781
2782 static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
2783 {
2784+ if ((long)n < 0)
2785+ return n;
2786+
2787 return __copy_user((__force void __user *) to, from, n);
2788 }
2789
2790diff -urNp linux-2.6.30.4/arch/sparc/include/asm/uaccess_64.h linux-2.6.30.4/arch/sparc/include/asm/uaccess_64.h
2791--- linux-2.6.30.4/arch/sparc/include/asm/uaccess_64.h 2009-07-24 17:47:51.000000000 -0400
2792+++ linux-2.6.30.4/arch/sparc/include/asm/uaccess_64.h 2009-07-30 11:10:48.823569054 -0400
de855c5d
AM
2793@@ -212,7 +212,12 @@ extern unsigned long copy_from_user_fixu
2794 static inline unsigned long __must_check
2795 copy_from_user(void *to, const void __user *from, unsigned long size)
2796 {
2797- unsigned long ret = ___copy_from_user(to, from, size);
2798+ unsigned long ret;
2799+
2800+ if (unlikely(((long)size > INT_MAX) || ((long)size < 0)))
2801+ return size;
2802+
2803+ ret = ___copy_from_user(to, from, size);
2804
2805 if (unlikely(ret))
2806 ret = copy_from_user_fixup(to, from, size);
2807@@ -228,7 +233,12 @@ extern unsigned long copy_to_user_fixup(
2808 static inline unsigned long __must_check
2809 copy_to_user(void __user *to, const void *from, unsigned long size)
2810 {
2811- unsigned long ret = ___copy_to_user(to, from, size);
2812+ unsigned long ret;
2813+
2814+ if (unlikely(((long)size > INT_MAX) || ((long)size < 0)))
2815+ return size;
2816+
2817+ ret = ___copy_to_user(to, from, size);
2818
2819 if (unlikely(ret))
2820 ret = copy_to_user_fixup(to, from, size);
017d2877
AM
2821diff -urNp linux-2.6.30.4/arch/sparc/kernel/Makefile linux-2.6.30.4/arch/sparc/kernel/Makefile
2822--- linux-2.6.30.4/arch/sparc/kernel/Makefile 2009-07-24 17:47:51.000000000 -0400
2823+++ linux-2.6.30.4/arch/sparc/kernel/Makefile 2009-07-30 09:48:09.911921584 -0400
2380c486
JR
2824@@ -3,7 +3,7 @@
2825 #
2826
2827 asflags-y := -ansi
2828-ccflags-y := -Werror
2829+#ccflags-y := -Werror
2830
2831 extra-y := head_$(BITS).o
2832 extra-y += init_task.o
017d2877
AM
2833diff -urNp linux-2.6.30.4/arch/sparc/kernel/sys_sparc_32.c linux-2.6.30.4/arch/sparc/kernel/sys_sparc_32.c
2834--- linux-2.6.30.4/arch/sparc/kernel/sys_sparc_32.c 2009-07-24 17:47:51.000000000 -0400
2835+++ linux-2.6.30.4/arch/sparc/kernel/sys_sparc_32.c 2009-07-30 09:48:09.912653453 -0400
2380c486
JR
2836@@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
2837 if (ARCH_SUN4C && len > 0x20000000)
2838 return -ENOMEM;
2839 if (!addr)
2840- addr = TASK_UNMAPPED_BASE;
2841+ addr = current->mm->mmap_base;
2842
2843 if (flags & MAP_SHARED)
2844 addr = COLOUR_ALIGN(addr);
017d2877
AM
2845diff -urNp linux-2.6.30.4/arch/sparc/kernel/sys_sparc_64.c linux-2.6.30.4/arch/sparc/kernel/sys_sparc_64.c
2846--- linux-2.6.30.4/arch/sparc/kernel/sys_sparc_64.c 2009-07-24 17:47:51.000000000 -0400
2847+++ linux-2.6.30.4/arch/sparc/kernel/sys_sparc_64.c 2009-07-30 09:48:09.912653453 -0400
2380c486
JR
2848@@ -125,7 +125,7 @@ unsigned long arch_get_unmapped_area(str
2849 /* We do not accept a shared mapping if it would violate
2850 * cache aliasing constraints.
2851 */
2852- if ((flags & MAP_SHARED) &&
2853+ if ((filp || (flags & MAP_SHARED)) &&
2854 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2855 return -EINVAL;
2856 return addr;
2857@@ -140,6 +140,10 @@ unsigned long arch_get_unmapped_area(str
2858 if (filp || (flags & MAP_SHARED))
2859 do_color_align = 1;
2860
2861+#ifdef CONFIG_PAX_RANDMMAP
2862+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
2863+#endif
2864+
2865 if (addr) {
2866 if (do_color_align)
2867 addr = COLOUR_ALIGN(addr, pgoff);
2868@@ -153,9 +157,9 @@ unsigned long arch_get_unmapped_area(str
2869 }
2870
2871 if (len > mm->cached_hole_size) {
2872- start_addr = addr = mm->free_area_cache;
2873+ start_addr = addr = mm->free_area_cache;
2874 } else {
2875- start_addr = addr = TASK_UNMAPPED_BASE;
2876++ start_addr = addr = mm->mmap_base;
2877 mm->cached_hole_size = 0;
2878 }
2879
2880@@ -175,8 +179,8 @@ full_search:
2881 vma = find_vma(mm, VA_EXCLUDE_END);
2882 }
2883 if (unlikely(task_size < addr)) {
2884- if (start_addr != TASK_UNMAPPED_BASE) {
2885- start_addr = addr = TASK_UNMAPPED_BASE;
2886+ if (start_addr != mm->mmap_base) {
2887+ start_addr = addr = mm->mmap_base;
2888 mm->cached_hole_size = 0;
2889 goto full_search;
2890 }
2891@@ -216,7 +220,7 @@ arch_get_unmapped_area_topdown(struct fi
2892 /* We do not accept a shared mapping if it would violate
2893 * cache aliasing constraints.
2894 */
2895- if ((flags & MAP_SHARED) &&
2896+ if ((filp || (flags & MAP_SHARED)) &&
2897 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2898 return -EINVAL;
2899 return addr;
2900@@ -380,6 +384,12 @@ void arch_pick_mmap_layout(struct mm_str
2901 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2902 sysctl_legacy_va_layout) {
2903 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2904+
2905+#ifdef CONFIG_PAX_RANDMMAP
2906+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2907+ mm->mmap_base += mm->delta_mmap;
2908+#endif
2909+
2910 mm->get_unmapped_area = arch_get_unmapped_area;
2911 mm->unmap_area = arch_unmap_area;
2912 } else {
2913@@ -394,6 +404,12 @@ void arch_pick_mmap_layout(struct mm_str
2914 gap = (task_size / 6 * 5);
2915
2916 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2917+
2918+#ifdef CONFIG_PAX_RANDMMAP
2919+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2920+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2921+#endif
2922+
2923 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2924 mm->unmap_area = arch_unmap_area_topdown;
2925 }
017d2877
AM
2926diff -urNp linux-2.6.30.4/arch/sparc/Makefile linux-2.6.30.4/arch/sparc/Makefile
2927--- linux-2.6.30.4/arch/sparc/Makefile 2009-07-24 17:47:51.000000000 -0400
2928+++ linux-2.6.30.4/arch/sparc/Makefile 2009-07-30 11:10:48.852135371 -0400
2380c486
JR
2929@@ -81,7 +81,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
2930 # Export what is needed by arch/sparc/boot/Makefile
2931 export VMLINUX_INIT VMLINUX_MAIN
2932 VMLINUX_INIT := $(head-y) $(init-y)
2933-VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/
2934+VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
2935 VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
2936 VMLINUX_MAIN += $(drivers-y) $(net-y)
2937
017d2877
AM
2938diff -urNp linux-2.6.30.4/arch/sparc/mm/fault_32.c linux-2.6.30.4/arch/sparc/mm/fault_32.c
2939--- linux-2.6.30.4/arch/sparc/mm/fault_32.c 2009-07-24 17:47:51.000000000 -0400
2940+++ linux-2.6.30.4/arch/sparc/mm/fault_32.c 2009-07-30 09:48:09.913853340 -0400
2380c486
JR
2941@@ -21,6 +21,9 @@
2942 #include <linux/interrupt.h>
2943 #include <linux/module.h>
2944 #include <linux/kdebug.h>
2945+#include <linux/slab.h>
2946+#include <linux/pagemap.h>
2947+#include <linux/compiler.h>
2948
2949 #include <asm/system.h>
2950 #include <asm/page.h>
2951@@ -167,6 +170,249 @@ static unsigned long compute_si_addr(str
2952 return safe_compute_effective_address(regs, insn);
2953 }
2954
2955+#ifdef CONFIG_PAX_PAGEEXEC
2956+void pax_emuplt_close(struct vm_area_struct *vma)
2957+{
2958+ vma->vm_mm->call_dl_resolve = 0UL;
2959+}
2960+
2961+static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2962+{
2963+ unsigned int *kaddr;
2964+
2965+ vmf->page = alloc_page(GFP_HIGHUSER);
2966+ if (!vmf->page)
2967+ return VM_FAULT_OOM;
2968+
2969+ kaddr = kmap(vmf->page);
2970+ memset(kaddr, 0, PAGE_SIZE);
2971+ kaddr[0] = 0x9DE3BFA8U; /* save */
2972+ flush_dcache_page(vmf->page);
2973+ kunmap(vmf->page);
2974+ return VM_FAULT_MAJOR;
2975+}
2976+
017d2877 2977+static const struct vm_operations_struct pax_vm_ops = {
2380c486
JR
2978+ .close = pax_emuplt_close,
2979+ .fault = pax_emuplt_fault
2980+};
2981+
2982+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2983+{
2984+ int ret;
2985+
2986+ vma->vm_mm = current->mm;
2987+ vma->vm_start = addr;
2988+ vma->vm_end = addr + PAGE_SIZE;
2989+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2990+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2991+ vma->vm_ops = &pax_vm_ops;
2992+
2993+ ret = insert_vm_struct(current->mm, vma);
2994+ if (ret)
2995+ return ret;
2996+
2997+ ++current->mm->total_vm;
2998+ return 0;
2999+}
3000+
3001+/*
3002+ * PaX: decide what to do with offenders (regs->pc = fault address)
3003+ *
3004+ * returns 1 when task should be killed
3005+ * 2 when patched PLT trampoline was detected
3006+ * 3 when unpatched PLT trampoline was detected
3007+ */
3008+static int pax_handle_fetch_fault(struct pt_regs *regs)
3009+{
3010+
3011+#ifdef CONFIG_PAX_EMUPLT
3012+ int err;
3013+
3014+ do { /* PaX: patched PLT emulation #1 */
3015+ unsigned int sethi1, sethi2, jmpl;
3016+
3017+ err = get_user(sethi1, (unsigned int *)regs->pc);
3018+ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
3019+ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
3020+
3021+ if (err)
3022+ break;
3023+
3024+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3025+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
3026+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
3027+ {
3028+ unsigned int addr;
3029+
3030+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3031+ addr = regs->u_regs[UREG_G1];
3032+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3033+ regs->pc = addr;
3034+ regs->npc = addr+4;
3035+ return 2;
3036+ }
3037+ } while (0);
3038+
3039+ { /* PaX: patched PLT emulation #2 */
3040+ unsigned int ba;
3041+
3042+ err = get_user(ba, (unsigned int *)regs->pc);
3043+
3044+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3045+ unsigned int addr;
3046+
3047+ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
3048+ regs->pc = addr;
3049+ regs->npc = addr+4;
3050+ return 2;
3051+ }
3052+ }
3053+
3054+ do { /* PaX: patched PLT emulation #3 */
3055+ unsigned int sethi, jmpl, nop;
3056+
3057+ err = get_user(sethi, (unsigned int *)regs->pc);
3058+ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
3059+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
3060+
3061+ if (err)
3062+ break;
3063+
3064+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
3065+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3066+ nop == 0x01000000U)
3067+ {
3068+ unsigned int addr;
3069+
3070+ addr = (sethi & 0x003FFFFFU) << 10;
3071+ regs->u_regs[UREG_G1] = addr;
3072+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
3073+ regs->pc = addr;
3074+ regs->npc = addr+4;
3075+ return 2;
3076+ }
3077+ } while (0);
3078+
3079+ do { /* PaX: unpatched PLT emulation step 1 */
3080+ unsigned int sethi, ba, nop;
3081+
3082+ err = get_user(sethi, (unsigned int *)regs->pc);
3083+ err |= get_user(ba, (unsigned int *)(regs->pc+4));
3084+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
3085+
3086+ if (err)
3087+ break;
3088+
3089+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
3090+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
3091+ nop == 0x01000000U)
3092+ {
3093+ unsigned int addr, save, call;
3094+
3095+ if ((ba & 0xFFC00000U) == 0x30800000U)
3096+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
3097+ else
3098+ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
3099+
3100+ err = get_user(save, (unsigned int *)addr);
3101+ err |= get_user(call, (unsigned int *)(addr+4));
3102+ err |= get_user(nop, (unsigned int *)(addr+8));
3103+ if (err)
3104+ break;
3105+
3106+ if (save == 0x9DE3BFA8U &&
3107+ (call & 0xC0000000U) == 0x40000000U &&
3108+ nop == 0x01000000U)
3109+ {
3110+ struct vm_area_struct *vma;
3111+ unsigned long call_dl_resolve;
3112+
3113+ down_read(&current->mm->mmap_sem);
3114+ call_dl_resolve = current->mm->call_dl_resolve;
3115+ up_read(&current->mm->mmap_sem);
3116+ if (likely(call_dl_resolve))
3117+ goto emulate;
3118+
3119+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3120+
3121+ down_write(&current->mm->mmap_sem);
3122+ if (current->mm->call_dl_resolve) {
3123+ call_dl_resolve = current->mm->call_dl_resolve;
3124+ up_write(&current->mm->mmap_sem);
3125+ if (vma)
3126+ kmem_cache_free(vm_area_cachep, vma);
3127+ goto emulate;
3128+ }
3129+
3130+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3131+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
3132+ up_write(&current->mm->mmap_sem);
3133+ if (vma)
3134+ kmem_cache_free(vm_area_cachep, vma);
3135+ return 1;
3136+ }
3137+
3138+ if (pax_insert_vma(vma, call_dl_resolve)) {
3139+ up_write(&current->mm->mmap_sem);
3140+ kmem_cache_free(vm_area_cachep, vma);
3141+ return 1;
3142+ }
3143+
3144+ current->mm->call_dl_resolve = call_dl_resolve;
3145+ up_write(&current->mm->mmap_sem);
3146+
3147+emulate:
3148+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
3149+ regs->pc = call_dl_resolve;
3150+ regs->npc = addr+4;
3151+ return 3;
3152+ }
3153+ }
3154+ } while (0);
3155+
3156+ do { /* PaX: unpatched PLT emulation step 2 */
3157+ unsigned int save, call, nop;
3158+
3159+ err = get_user(save, (unsigned int *)(regs->pc-4));
3160+ err |= get_user(call, (unsigned int *)regs->pc);
3161+ err |= get_user(nop, (unsigned int *)(regs->pc+4));
3162+ if (err)
3163+ break;
3164+
3165+ if (save == 0x9DE3BFA8U &&
3166+ (call & 0xC0000000U) == 0x40000000U &&
3167+ nop == 0x01000000U)
3168+ {
3169+ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
3170+
3171+ regs->u_regs[UREG_RETPC] = regs->pc;
3172+ regs->pc = dl_resolve;
3173+ regs->npc = dl_resolve+4;
3174+ return 3;
3175+ }
3176+ } while (0);
3177+#endif
3178+
3179+ return 1;
3180+}
3181+
3182+void pax_report_insns(void *pc, void *sp)
3183+{
3184+ unsigned long i;
3185+
3186+ printk(KERN_ERR "PAX: bytes at PC: ");
3187+ for (i = 0; i < 5; i++) {
3188+ unsigned int c;
3189+ if (get_user(c, (unsigned int *)pc+i))
3190+ printk(KERN_CONT "???????? ");
3191+ else
3192+ printk(KERN_CONT "%08x ", c);
3193+ }
3194+ printk("\n");
3195+}
3196+#endif
3197+
3198 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
3199 unsigned long address)
3200 {
3201@@ -231,6 +477,24 @@ good_area:
3202 if(!(vma->vm_flags & VM_WRITE))
3203 goto bad_area;
3204 } else {
3205+
3206+#ifdef CONFIG_PAX_PAGEEXEC
3207+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
3208+ up_read(&mm->mmap_sem);
3209+ switch (pax_handle_fetch_fault(regs)) {
3210+
3211+#ifdef CONFIG_PAX_EMUPLT
3212+ case 2:
3213+ case 3:
3214+ return;
3215+#endif
3216+
3217+ }
3218+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
3219+ do_group_exit(SIGKILL);
3220+ }
3221+#endif
3222+
3223 /* Allow reads even for write-only mappings */
3224 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
3225 goto bad_area;
017d2877
AM
3226diff -urNp linux-2.6.30.4/arch/sparc/mm/fault_64.c linux-2.6.30.4/arch/sparc/mm/fault_64.c
3227--- linux-2.6.30.4/arch/sparc/mm/fault_64.c 2009-07-24 17:47:51.000000000 -0400
3228+++ linux-2.6.30.4/arch/sparc/mm/fault_64.c 2009-07-30 09:48:09.913853340 -0400
2380c486
JR
3229@@ -20,6 +20,9 @@
3230 #include <linux/kprobes.h>
3231 #include <linux/kdebug.h>
3232 #include <linux/percpu.h>
3233+#include <linux/slab.h>
3234+#include <linux/pagemap.h>
3235+#include <linux/compiler.h>
3236
3237 #include <asm/page.h>
3238 #include <asm/pgtable.h>
3239@@ -249,6 +252,367 @@ static void noinline bogus_32bit_fault_a
3240 show_regs(regs);
3241 }
3242
3243+#ifdef CONFIG_PAX_PAGEEXEC
3244+#ifdef CONFIG_PAX_EMUPLT
3245+static void pax_emuplt_close(struct vm_area_struct *vma)
3246+{
3247+ vma->vm_mm->call_dl_resolve = 0UL;
3248+}
3249+
3250+static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
3251+{
3252+ unsigned int *kaddr;
3253+
3254+ vmf->page = alloc_page(GFP_HIGHUSER);
3255+ if (!vmf->page)
3256+ return VM_FAULT_OOM;
3257+
3258+ kaddr = kmap(vmf->page);
3259+ memset(kaddr, 0, PAGE_SIZE);
3260+ kaddr[0] = 0x9DE3BFA8U; /* save */
3261+ flush_dcache_page(vmf->page);
3262+ kunmap(vmf->page);
3263+ return VM_FAULT_MAJOR;
3264+}
3265+
017d2877 3266+static const struct vm_operations_struct pax_vm_ops = {
2380c486
JR
3267+ .close = pax_emuplt_close,
3268+ .fault = pax_emuplt_fault
3269+};
3270+
3271+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3272+{
3273+ int ret;
3274+
3275+ vma->vm_mm = current->mm;
3276+ vma->vm_start = addr;
3277+ vma->vm_end = addr + PAGE_SIZE;
3278+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3279+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
3280+ vma->vm_ops = &pax_vm_ops;
3281+
3282+ ret = insert_vm_struct(current->mm, vma);
3283+ if (ret)
3284+ return ret;
3285+
3286+ ++current->mm->total_vm;
3287+ return 0;
3288+}
3289+#endif
3290+
3291+/*
3292+ * PaX: decide what to do with offenders (regs->tpc = fault address)
3293+ *
3294+ * returns 1 when task should be killed
3295+ * 2 when patched PLT trampoline was detected
3296+ * 3 when unpatched PLT trampoline was detected
3297+ */
3298+static int pax_handle_fetch_fault(struct pt_regs *regs)
3299+{
3300+
3301+#ifdef CONFIG_PAX_EMUPLT
3302+ int err;
3303+
3304+ do { /* PaX: patched PLT emulation #1 */
3305+ unsigned int sethi1, sethi2, jmpl;
3306+
3307+ err = get_user(sethi1, (unsigned int *)regs->tpc);
3308+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
3309+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
3310+
3311+ if (err)
3312+ break;
3313+
3314+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3315+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
3316+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
3317+ {
3318+ unsigned long addr;
3319+
3320+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
3321+ addr = regs->u_regs[UREG_G1];
3322+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3323+ regs->tpc = addr;
3324+ regs->tnpc = addr+4;
3325+ return 2;
3326+ }
3327+ } while (0);
3328+
3329+ { /* PaX: patched PLT emulation #2 */
3330+ unsigned int ba;
3331+
3332+ err = get_user(ba, (unsigned int *)regs->tpc);
3333+
3334+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
3335+ unsigned long addr;
3336+
3337+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
3338+ regs->tpc = addr;
3339+ regs->tnpc = addr+4;
3340+ return 2;
3341+ }
3342+ }
3343+
3344+ do { /* PaX: patched PLT emulation #3 */
3345+ unsigned int sethi, jmpl, nop;
3346+
3347+ err = get_user(sethi, (unsigned int *)regs->tpc);
3348+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
3349+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
3350+
3351+ if (err)
3352+ break;
3353+
3354+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
3355+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
3356+ nop == 0x01000000U)
3357+ {
3358+ unsigned long addr;
3359+
3360+ addr = (sethi & 0x003FFFFFU) << 10;
3361+ regs->u_regs[UREG_G1] = addr;
3362+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
3363+ regs->tpc = addr;
3364+ regs->tnpc = addr+4;
3365+ return 2;
3366+ }
3367+ } while (0);
3368+
3369+ do { /* PaX: patched PLT emulation #4 */
3370+ unsigned int mov1, call, mov2;
3371+
3372+ err = get_user(mov1, (unsigned int *)regs->tpc);
3373+ err |= get_user(call, (unsigned int *)(regs->tpc+4));
3374+ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
3375+
3376+ if (err)
3377+ break;
3378+
3379+ if (mov1 == 0x8210000FU &&
3380+ (call & 0xC0000000U) == 0x40000000U &&
3381+ mov2 == 0x9E100001U)
3382+ {
3383+ unsigned long addr;
3384+
3385+ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
3386+ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
3387+ regs->tpc = addr;
3388+ regs->tnpc = addr+4;
3389+ return 2;
3390+ }
3391+ } while (0);
3392+
3393+ do { /* PaX: patched PLT emulation #5 */
3394+ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
3395+
3396+ err = get_user(sethi1, (unsigned int *)regs->tpc);
3397+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
3398+ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
3399+ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
3400+ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
3401+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
3402+ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
3403+
3404+ if (err)
3405+ break;
3406+
3407+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3408+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
3409+ (or1 & 0xFFFFE000U) == 0x82106000U &&
3410+ (or2 & 0xFFFFE000U) == 0x8A116000U &&
3411+ sllx == 0x83287020 &&
3412+ jmpl == 0x81C04005U &&
3413+ nop == 0x01000000U)
3414+ {
3415+ unsigned long addr;
3416+
3417+ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
3418+ regs->u_regs[UREG_G1] <<= 32;
3419+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
3420+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
3421+ regs->tpc = addr;
3422+ regs->tnpc = addr+4;
3423+ return 2;
3424+ }
3425+ } while (0);
3426+
3427+ do { /* PaX: patched PLT emulation #6 */
3428+ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
3429+
3430+ err = get_user(sethi1, (unsigned int *)regs->tpc);
3431+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
3432+ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
3433+ err |= get_user(or, (unsigned int *)(regs->tpc+12));
3434+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
3435+ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
3436+
3437+ if (err)
3438+ break;
3439+
3440+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
3441+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
3442+ sllx == 0x83287020 &&
3443+ (or & 0xFFFFE000U) == 0x8A116000U &&
3444+ jmpl == 0x81C04005U &&
3445+ nop == 0x01000000U)
3446+ {
3447+ unsigned long addr;
3448+
3449+ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
3450+ regs->u_regs[UREG_G1] <<= 32;
3451+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
3452+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
3453+ regs->tpc = addr;
3454+ regs->tnpc = addr+4;
3455+ return 2;
3456+ }
3457+ } while (0);
3458+
3459+ do { /* PaX: patched PLT emulation #7 */
3460+ unsigned int sethi, ba, nop;
3461+
3462+ err = get_user(sethi, (unsigned int *)regs->tpc);
3463+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
3464+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
3465+
3466+ if (err)
3467+ break;
3468+
3469+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
3470+ (ba & 0xFFF00000U) == 0x30600000U &&
3471+ nop == 0x01000000U)
3472+ {
3473+ unsigned long addr;
3474+
3475+ addr = (sethi & 0x003FFFFFU) << 10;
3476+ regs->u_regs[UREG_G1] = addr;
3477+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
3478+ regs->tpc = addr;
3479+ regs->tnpc = addr+4;
3480+ return 2;
3481+ }
3482+ } while (0);
3483+
3484+ do { /* PaX: unpatched PLT emulation step 1 */
3485+ unsigned int sethi, ba, nop;
3486+
3487+ err = get_user(sethi, (unsigned int *)regs->tpc);
3488+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
3489+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
3490+
3491+ if (err)
3492+ break;
3493+
3494+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
3495+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
3496+ nop == 0x01000000U)
3497+ {
3498+ unsigned long addr;
3499+ unsigned int save, call;
3500+
3501+ if ((ba & 0xFFC00000U) == 0x30800000U)
3502+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
3503+ else
3504+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
3505+
3506+ err = get_user(save, (unsigned int *)addr);
3507+ err |= get_user(call, (unsigned int *)(addr+4));
3508+ err |= get_user(nop, (unsigned int *)(addr+8));
3509+ if (err)
3510+ break;
3511+
3512+ if (save == 0x9DE3BFA8U &&
3513+ (call & 0xC0000000U) == 0x40000000U &&
3514+ nop == 0x01000000U)
3515+ {
3516+ struct vm_area_struct *vma;
3517+ unsigned long call_dl_resolve;
3518+
3519+ down_read(&current->mm->mmap_sem);
3520+ call_dl_resolve = current->mm->call_dl_resolve;
3521+ up_read(&current->mm->mmap_sem);
3522+ if (likely(call_dl_resolve))
3523+ goto emulate;
3524+
3525+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3526+
3527+ down_write(&current->mm->mmap_sem);
3528+ if (current->mm->call_dl_resolve) {
3529+ call_dl_resolve = current->mm->call_dl_resolve;
3530+ up_write(&current->mm->mmap_sem);
3531+ if (vma)
3532+ kmem_cache_free(vm_area_cachep, vma);
3533+ goto emulate;
3534+ }
3535+
3536+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3537+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
3538+ up_write(&current->mm->mmap_sem);
3539+ if (vma)
3540+ kmem_cache_free(vm_area_cachep, vma);
3541+ return 1;
3542+ }
3543+
3544+ if (pax_insert_vma(vma, call_dl_resolve)) {
3545+ up_write(&current->mm->mmap_sem);
3546+ kmem_cache_free(vm_area_cachep, vma);
3547+ return 1;
3548+ }
3549+
3550+ current->mm->call_dl_resolve = call_dl_resolve;
3551+ up_write(&current->mm->mmap_sem);
3552+
3553+emulate:
3554+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
3555+ regs->tpc = call_dl_resolve;
3556+ regs->tnpc = addr+4;
3557+ return 3;
3558+ }
3559+ }
3560+ } while (0);
3561+
3562+ do { /* PaX: unpatched PLT emulation step 2 */
3563+ unsigned int save, call, nop;
3564+
3565+ err = get_user(save, (unsigned int *)(regs->tpc-4));
3566+ err |= get_user(call, (unsigned int *)regs->tpc);
3567+ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
3568+ if (err)
3569+ break;
3570+
3571+ if (save == 0x9DE3BFA8U &&
3572+ (call & 0xC0000000U) == 0x40000000U &&
3573+ nop == 0x01000000U)
3574+ {
3575+ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
3576+
3577+ regs->u_regs[UREG_RETPC] = regs->tpc;
3578+ regs->tpc = dl_resolve;
3579+ regs->tnpc = dl_resolve+4;
3580+ return 3;
3581+ }
3582+ } while (0);
3583+#endif
3584+
3585+ return 1;
3586+}
3587+
3588+void pax_report_insns(void *pc, void *sp)
3589+{
3590+ unsigned long i;
3591+
3592+ printk(KERN_ERR "PAX: bytes at PC: ");
3593+ for (i = 0; i < 5; i++) {
3594+ unsigned int c;
3595+ if (get_user(c, (unsigned int *)pc+i))
3596+ printk(KERN_CONT "???????? ");
3597+ else
3598+ printk(KERN_CONT "%08x ", c);
3599+ }
3600+ printk("\n");
3601+}
3602+#endif
3603+
3604 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
3605 {
3606 struct mm_struct *mm = current->mm;
3607@@ -315,6 +679,29 @@ asmlinkage void __kprobes do_sparc64_fau
3608 if (!vma)
3609 goto bad_area;
3610
3611+#ifdef CONFIG_PAX_PAGEEXEC
3612+ /* PaX: detect ITLB misses on non-exec pages */
3613+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
3614+ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
3615+ {
3616+ if (address != regs->tpc)
3617+ goto good_area;
3618+
3619+ up_read(&mm->mmap_sem);
3620+ switch (pax_handle_fetch_fault(regs)) {
3621+
3622+#ifdef CONFIG_PAX_EMUPLT
3623+ case 2:
3624+ case 3:
3625+ return;
3626+#endif
3627+
3628+ }
3629+ pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
3630+ do_group_exit(SIGKILL);
3631+ }
3632+#endif
3633+
3634 /* Pure DTLB misses do not tell us whether the fault causing
3635 * load/store/atomic was a write or not, it only says that there
3636 * was no match. So in such a case we (carefully) read the
017d2877
AM
3637diff -urNp linux-2.6.30.4/arch/sparc/mm/init_32.c linux-2.6.30.4/arch/sparc/mm/init_32.c
3638--- linux-2.6.30.4/arch/sparc/mm/init_32.c 2009-07-24 17:47:51.000000000 -0400
3639+++ linux-2.6.30.4/arch/sparc/mm/init_32.c 2009-07-30 09:48:09.914627627 -0400
2380c486
JR
3640@@ -316,6 +316,9 @@ extern void device_scan(void);
3641 pgprot_t PAGE_SHARED __read_mostly;
3642 EXPORT_SYMBOL(PAGE_SHARED);
3643
3644+pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
3645+EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
3646+
3647 void __init paging_init(void)
3648 {
3649 switch(sparc_cpu_model) {
3650@@ -341,17 +344,17 @@ void __init paging_init(void)
3651
3652 /* Initialize the protection map with non-constant, MMU dependent values. */
3653 protection_map[0] = PAGE_NONE;
3654- protection_map[1] = PAGE_READONLY;
3655- protection_map[2] = PAGE_COPY;
3656- protection_map[3] = PAGE_COPY;
3657+ protection_map[1] = PAGE_READONLY_NOEXEC;
3658+ protection_map[2] = PAGE_COPY_NOEXEC;
3659+ protection_map[3] = PAGE_COPY_NOEXEC;
3660 protection_map[4] = PAGE_READONLY;
3661 protection_map[5] = PAGE_READONLY;
3662 protection_map[6] = PAGE_COPY;
3663 protection_map[7] = PAGE_COPY;
3664 protection_map[8] = PAGE_NONE;
3665- protection_map[9] = PAGE_READONLY;
3666- protection_map[10] = PAGE_SHARED;
3667- protection_map[11] = PAGE_SHARED;
3668+ protection_map[9] = PAGE_READONLY_NOEXEC;
3669+ protection_map[10] = PAGE_SHARED_NOEXEC;
3670+ protection_map[11] = PAGE_SHARED_NOEXEC;
3671 protection_map[12] = PAGE_READONLY;
3672 protection_map[13] = PAGE_READONLY;
3673 protection_map[14] = PAGE_SHARED;
017d2877
AM
3674diff -urNp linux-2.6.30.4/arch/sparc/mm/Makefile linux-2.6.30.4/arch/sparc/mm/Makefile
3675--- linux-2.6.30.4/arch/sparc/mm/Makefile 2009-07-24 17:47:51.000000000 -0400
3676+++ linux-2.6.30.4/arch/sparc/mm/Makefile 2009-07-30 09:48:09.912653453 -0400
2380c486
JR
3677@@ -2,7 +2,7 @@
3678 #
3679
3680 asflags-y := -ansi
3681-ccflags-y := -Werror
3682+#ccflags-y := -Werror
3683
3684 obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o
3685 obj-y += fault_$(BITS).o
017d2877
AM
3686diff -urNp linux-2.6.30.4/arch/sparc/mm/srmmu.c linux-2.6.30.4/arch/sparc/mm/srmmu.c
3687--- linux-2.6.30.4/arch/sparc/mm/srmmu.c 2009-07-24 17:47:51.000000000 -0400
3688+++ linux-2.6.30.4/arch/sparc/mm/srmmu.c 2009-07-30 09:48:09.914627627 -0400
2380c486
JR
3689@@ -2148,6 +2148,13 @@ void __init ld_mmu_srmmu(void)
3690 PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
3691 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
3692 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
3693+
3694+#ifdef CONFIG_PAX_PAGEEXEC
3695+ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
3696+ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
3697+ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
3698+#endif
3699+
3700 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
3701 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
3702
017d2877
AM
3703diff -urNp linux-2.6.30.4/arch/um/include/asm/kmap_types.h linux-2.6.30.4/arch/um/include/asm/kmap_types.h
3704--- linux-2.6.30.4/arch/um/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
3705+++ linux-2.6.30.4/arch/um/include/asm/kmap_types.h 2009-07-30 09:48:09.914627627 -0400
2380c486
JR
3706@@ -23,6 +23,7 @@ enum km_type {
3707 KM_IRQ1,
3708 KM_SOFTIRQ0,
3709 KM_SOFTIRQ1,
3710+ KM_CLEARPAGE,
3711 KM_TYPE_NR
3712 };
3713
017d2877
AM
3714diff -urNp linux-2.6.30.4/arch/um/include/asm/page.h linux-2.6.30.4/arch/um/include/asm/page.h
3715--- linux-2.6.30.4/arch/um/include/asm/page.h 2009-07-24 17:47:51.000000000 -0400
3716+++ linux-2.6.30.4/arch/um/include/asm/page.h 2009-07-30 09:48:09.915798567 -0400
2380c486
JR
3717@@ -14,6 +14,9 @@
3718 #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
3719 #define PAGE_MASK (~(PAGE_SIZE-1))
3720
3721+#define ktla_ktva(addr) (addr)
3722+#define ktva_ktla(addr) (addr)
3723+
3724 #ifndef __ASSEMBLY__
3725
3726 struct page;
017d2877
AM
3727diff -urNp linux-2.6.30.4/arch/um/sys-i386/syscalls.c linux-2.6.30.4/arch/um/sys-i386/syscalls.c
3728--- linux-2.6.30.4/arch/um/sys-i386/syscalls.c 2009-07-24 17:47:51.000000000 -0400
3729+++ linux-2.6.30.4/arch/um/sys-i386/syscalls.c 2009-07-30 09:48:09.915798567 -0400
2380c486
JR
3730@@ -11,6 +11,21 @@
3731 #include "asm/uaccess.h"
3732 #include "asm/unistd.h"
3733
3734+int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
3735+{
3736+ unsigned long pax_task_size = TASK_SIZE;
3737+
3738+#ifdef CONFIG_PAX_SEGMEXEC
3739+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
3740+ pax_task_size = SEGMEXEC_TASK_SIZE;
3741+#endif
3742+
3743+ if (len > pax_task_size || addr > pax_task_size - len)
3744+ return -EINVAL;
3745+
3746+ return 0;
3747+}
3748+
3749 /*
3750 * Perform the select(nd, in, out, ex, tv) and mmap() system
3751 * calls. Linux/i386 didn't use to be able to handle more than
017d2877
AM
3752diff -urNp linux-2.6.30.4/arch/x86/boot/bitops.h linux-2.6.30.4/arch/x86/boot/bitops.h
3753--- linux-2.6.30.4/arch/x86/boot/bitops.h 2009-07-24 17:47:51.000000000 -0400
3754+++ linux-2.6.30.4/arch/x86/boot/bitops.h 2009-07-30 09:48:09.917626356 -0400
2380c486
JR
3755@@ -26,7 +26,7 @@ static inline int variable_test_bit(int
3756 u8 v;
3757 const u32 *p = (const u32 *)addr;
3758
3759- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
3760+ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
3761 return v;
3762 }
3763
3764@@ -37,7 +37,7 @@ static inline int variable_test_bit(int
3765
3766 static inline void set_bit(int nr, void *addr)
3767 {
3768- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3769+ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3770 }
3771
3772 #endif /* BOOT_BITOPS_H */
017d2877
AM
3773diff -urNp linux-2.6.30.4/arch/x86/boot/boot.h linux-2.6.30.4/arch/x86/boot/boot.h
3774--- linux-2.6.30.4/arch/x86/boot/boot.h 2009-07-24 17:47:51.000000000 -0400
3775+++ linux-2.6.30.4/arch/x86/boot/boot.h 2009-07-30 09:48:09.917626356 -0400
2380c486
JR
3776@@ -80,7 +80,7 @@ static inline void io_delay(void)
3777 static inline u16 ds(void)
3778 {
3779 u16 seg;
3780- asm("movw %%ds,%0" : "=rm" (seg));
3781+ asm volatile("movw %%ds,%0" : "=rm" (seg));
3782 return seg;
3783 }
3784
3785@@ -176,7 +176,7 @@ static inline void wrgs32(u32 v, addr_t
3786 static inline int memcmp(const void *s1, const void *s2, size_t len)
3787 {
3788 u8 diff;
3789- asm("repe; cmpsb; setnz %0"
3790+ asm volatile("repe; cmpsb; setnz %0"
3791 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
3792 return diff;
3793 }
017d2877
AM
3794diff -urNp linux-2.6.30.4/arch/x86/boot/compressed/head_32.S linux-2.6.30.4/arch/x86/boot/compressed/head_32.S
3795--- linux-2.6.30.4/arch/x86/boot/compressed/head_32.S 2009-07-24 17:47:51.000000000 -0400
3796+++ linux-2.6.30.4/arch/x86/boot/compressed/head_32.S 2009-07-30 09:48:09.917626356 -0400
3797@@ -68,7 +68,7 @@ ENTRY(startup_32)
2380c486
JR
3798 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
3799 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
3800 #else
3801- movl $LOAD_PHYSICAL_ADDR, %ebx
3802+ movl $____LOAD_PHYSICAL_ADDR, %ebx
3803 #endif
3804
3805 /* Replace the compressed data size with the uncompressed size */
017d2877 3806@@ -78,8 +78,8 @@ ENTRY(startup_32)
2380c486
JR
3807 /* Add 8 bytes for every 32K input block */
3808 shrl $12, %eax
3809 addl %eax, %ebx
3810- /* Add 32K + 18 bytes of extra slack */
3811- addl $(32768 + 18), %ebx
3812+ /* Add 64K of extra slack */
3813+ addl $65536, %ebx
3814 /* Align on a 4K boundary */
3815 addl $4095, %ebx
3816 andl $~4095, %ebx
017d2877 3817@@ -103,7 +103,7 @@ ENTRY(startup_32)
2380c486
JR
3818 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
3819 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
3820 #else
3821- movl $LOAD_PHYSICAL_ADDR, %ebp
3822+ movl $____LOAD_PHYSICAL_ADDR, %ebp
3823 #endif
3824
3825 /*
3826@@ -160,16 +160,15 @@ relocated:
3827 * and where it was actually loaded.
3828 */
3829 movl %ebp, %ebx
3830- subl $LOAD_PHYSICAL_ADDR, %ebx
3831+ subl $____LOAD_PHYSICAL_ADDR, %ebx
3832 jz 2f /* Nothing to be done if loaded at compiled addr. */
3833 /*
3834 * Process relocations.
3835 */
3836
3837 1: subl $4, %edi
3838- movl 0(%edi), %ecx
3839- testl %ecx, %ecx
3840- jz 2f
3841+ movl (%edi), %ecx
3842+ jecxz 2f
3843 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
3844 jmp 1b
3845 2:
017d2877
AM
3846diff -urNp linux-2.6.30.4/arch/x86/boot/compressed/misc.c linux-2.6.30.4/arch/x86/boot/compressed/misc.c
3847--- linux-2.6.30.4/arch/x86/boot/compressed/misc.c 2009-07-24 17:47:51.000000000 -0400
3848+++ linux-2.6.30.4/arch/x86/boot/compressed/misc.c 2009-07-30 09:48:09.917626356 -0400
3849@@ -288,7 +288,7 @@ static void parse_elf(void *output)
2380c486
JR
3850 case PT_LOAD:
3851 #ifdef CONFIG_RELOCATABLE
3852 dest = output;
3853- dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
3854+ dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
3855 #else
3856 dest = (void *)(phdr->p_paddr);
3857 #endif
017d2877 3858@@ -336,7 +336,7 @@ asmlinkage void decompress_kernel(void *
2380c486
JR
3859 if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
3860 error("Destination address too large");
3861 #ifndef CONFIG_RELOCATABLE
3862- if ((u32)output != LOAD_PHYSICAL_ADDR)
3863+ if ((u32)output != ____LOAD_PHYSICAL_ADDR)
3864 error("Wrong destination address");
3865 #endif
3866 #endif
017d2877
AM
3867diff -urNp linux-2.6.30.4/arch/x86/boot/compressed/relocs.c linux-2.6.30.4/arch/x86/boot/compressed/relocs.c
3868--- linux-2.6.30.4/arch/x86/boot/compressed/relocs.c 2009-07-24 17:47:51.000000000 -0400
3869+++ linux-2.6.30.4/arch/x86/boot/compressed/relocs.c 2009-07-30 09:48:09.918715361 -0400
2380c486
JR
3870@@ -10,8 +10,11 @@
3871 #define USE_BSD
3872 #include <endian.h>
3873
3874+#include "../../../../include/linux/autoconf.h"
3875+
3876 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3877 static Elf32_Ehdr ehdr;
3878+static Elf32_Phdr *phdr;
3879 static unsigned long reloc_count, reloc_idx;
3880 static unsigned long *relocs;
3881
3882@@ -245,6 +248,36 @@ static void read_ehdr(FILE *fp)
3883 }
3884 }
3885
3886+static void read_phdrs(FILE *fp)
3887+{
3888+ int i;
3889+
3890+ phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
3891+ if (!phdr) {
3892+ die("Unable to allocate %d program headers\n",
3893+ ehdr.e_phnum);
3894+ }
3895+ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3896+ die("Seek to %d failed: %s\n",
3897+ ehdr.e_phoff, strerror(errno));
3898+ }
3899+ if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3900+ die("Cannot read ELF program headers: %s\n",
3901+ strerror(errno));
3902+ }
3903+ for(i = 0; i < ehdr.e_phnum; i++) {
3904+ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
3905+ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
3906+ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
3907+ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
3908+ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
3909+ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
3910+ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
3911+ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
3912+ }
3913+
3914+}
3915+
3916 static void read_shdrs(FILE *fp)
3917 {
3918 int i;
3919@@ -341,6 +374,8 @@ static void read_symtabs(FILE *fp)
3920 static void read_relocs(FILE *fp)
3921 {
3922 int i,j;
3923+ uint32_t base;
3924+
3925 for (i = 0; i < ehdr.e_shnum; i++) {
3926 struct section *sec = &secs[i];
3927 if (sec->shdr.sh_type != SHT_REL) {
3928@@ -360,9 +395,18 @@ static void read_relocs(FILE *fp)
3929 die("Cannot read symbol table: %s\n",
3930 strerror(errno));
3931 }
3932+ base = 0;
3933+ for (j = 0; j < ehdr.e_phnum; j++) {
3934+ if (phdr[j].p_type != PT_LOAD )
3935+ continue;
3936+ 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)
3937+ continue;
3938+ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
3939+ break;
3940+ }
3941 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
3942 Elf32_Rel *rel = &sec->reltab[j];
3943- rel->r_offset = elf32_to_cpu(rel->r_offset);
3944+ rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
3945 rel->r_info = elf32_to_cpu(rel->r_info);
3946 }
3947 }
3948@@ -504,6 +548,23 @@ static void walk_relocs(void (*visit)(El
3949 if (sym->st_shndx == SHN_ABS) {
3950 continue;
3951 }
3952+ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
017d2877 3953+ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strcmp(sym_name(sym_strtab, sym), "__per_cpu_load"))
2380c486
JR
3954+ continue;
3955+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
3956+ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
3957+ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
3958+ continue;
3959+ if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
3960+ continue;
3961+ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
3962+ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
3963+ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
3964+ continue;
3965+ }
3966+ if (!strcmp(sec_name(sym->st_shndx), ".text"))
3967+ continue;
3968+#endif
017d2877
AM
3969 if (r_type == R_386_NONE || r_type == R_386_PC32) {
3970 /*
3971 * NONE can be ignored and and PC relative
3972@@ -634,6 +695,7 @@ int main(int argc, char **argv)
2380c486
JR
3973 fname, strerror(errno));
3974 }
3975 read_ehdr(fp);
3976+ read_phdrs(fp);
3977 read_shdrs(fp);
3978 read_strtabs(fp);
3979 read_symtabs(fp);
017d2877
AM
3980diff -urNp linux-2.6.30.4/arch/x86/boot/cpucheck.c linux-2.6.30.4/arch/x86/boot/cpucheck.c
3981--- linux-2.6.30.4/arch/x86/boot/cpucheck.c 2009-07-24 17:47:51.000000000 -0400
3982+++ linux-2.6.30.4/arch/x86/boot/cpucheck.c 2009-07-30 09:48:09.918715361 -0400
2380c486
JR
3983@@ -74,7 +74,7 @@ static int has_fpu(void)
3984 u16 fcw = -1, fsw = -1;
3985 u32 cr0;
3986
3987- asm("movl %%cr0,%0" : "=r" (cr0));
3988+ asm volatile("movl %%cr0,%0" : "=r" (cr0));
3989 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
3990 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
3991 asm volatile("movl %0,%%cr0" : : "r" (cr0));
3992@@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
3993 {
3994 u32 f0, f1;
3995
3996- asm("pushfl ; "
3997+ asm volatile("pushfl ; "
3998 "pushfl ; "
3999 "popl %0 ; "
4000 "movl %0,%1 ; "
4001@@ -115,7 +115,7 @@ static void get_flags(void)
4002 set_bit(X86_FEATURE_FPU, cpu.flags);
4003
4004 if (has_eflag(X86_EFLAGS_ID)) {
4005- asm("cpuid"
4006+ asm volatile("cpuid"
4007 : "=a" (max_intel_level),
4008 "=b" (cpu_vendor[0]),
4009 "=d" (cpu_vendor[1]),
4010@@ -124,7 +124,7 @@ static void get_flags(void)
4011
4012 if (max_intel_level >= 0x00000001 &&
4013 max_intel_level <= 0x0000ffff) {
4014- asm("cpuid"
4015+ asm volatile("cpuid"
4016 : "=a" (tfms),
4017 "=c" (cpu.flags[4]),
4018 "=d" (cpu.flags[0])
4019@@ -136,7 +136,7 @@ static void get_flags(void)
4020 cpu.model += ((tfms >> 16) & 0xf) << 4;
4021 }
4022
4023- asm("cpuid"
4024+ asm volatile("cpuid"
4025 : "=a" (max_amd_level)
4026 : "a" (0x80000000)
4027 : "ebx", "ecx", "edx");
4028@@ -144,7 +144,7 @@ static void get_flags(void)
4029 if (max_amd_level >= 0x80000001 &&
4030 max_amd_level <= 0x8000ffff) {
4031 u32 eax = 0x80000001;
4032- asm("cpuid"
4033+ asm volatile("cpuid"
4034 : "+a" (eax),
4035 "=c" (cpu.flags[6]),
4036 "=d" (cpu.flags[1])
4037@@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
4038 u32 ecx = MSR_K7_HWCR;
4039 u32 eax, edx;
4040
4041- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
4042+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
4043 eax &= ~(1 << 15);
4044- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
4045+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
4046
4047 get_flags(); /* Make sure it really did something */
4048 err = check_flags();
4049@@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
4050 u32 ecx = MSR_VIA_FCR;
4051 u32 eax, edx;
4052
4053- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
4054+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
4055 eax |= (1<<1)|(1<<7);
4056- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
4057+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
4058
4059 set_bit(X86_FEATURE_CX8, cpu.flags);
4060 err = check_flags();
4061@@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
4062 u32 eax, edx;
4063 u32 level = 1;
4064
4065- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
4066- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
4067- asm("cpuid"
4068+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
4069+ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
4070+ asm volatile("cpuid"
4071 : "+a" (level), "=d" (cpu.flags[0])
4072 : : "ecx", "ebx");
4073- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
4074+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
4075
4076 err = check_flags();
4077 }
017d2877
AM
4078diff -urNp linux-2.6.30.4/arch/x86/boot/edd.c linux-2.6.30.4/arch/x86/boot/edd.c
4079--- linux-2.6.30.4/arch/x86/boot/edd.c 2009-07-24 17:47:51.000000000 -0400
4080+++ linux-2.6.30.4/arch/x86/boot/edd.c 2009-07-30 09:48:09.919627263 -0400
2380c486
JR
4081@@ -81,7 +81,7 @@ static int get_edd_info(u8 devno, struct
4082 ax = 0x4100;
4083 bx = EDDMAGIC1;
4084 dx = devno;
4085- asm("pushfl; stc; int $0x13; setc %%al; popfl"
4086+ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
4087 : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
4088 : : "esi", "edi");
4089
4090@@ -100,7 +100,7 @@ static int get_edd_info(u8 devno, struct
4091 ei->params.length = sizeof(ei->params);
4092 ax = 0x4800;
4093 dx = devno;
4094- asm("pushfl; int $0x13; popfl"
4095+ asm volatile("pushfl; int $0x13; popfl"
4096 : "+a" (ax), "+d" (dx), "=m" (ei->params)
4097 : "S" (&ei->params)
4098 : "ebx", "ecx", "edi");
4099@@ -111,7 +111,7 @@ static int get_edd_info(u8 devno, struct
4100 ax = 0x0800;
4101 dx = devno;
4102 di = 0;
4103- asm("pushw %%es; "
4104+ asm volatile("pushw %%es; "
4105 "movw %%di,%%es; "
4106 "pushfl; stc; int $0x13; setc %%al; popfl; "
4107 "popw %%es"
017d2877
AM
4108diff -urNp linux-2.6.30.4/arch/x86/boot/main.c linux-2.6.30.4/arch/x86/boot/main.c
4109--- linux-2.6.30.4/arch/x86/boot/main.c 2009-07-24 17:47:51.000000000 -0400
4110+++ linux-2.6.30.4/arch/x86/boot/main.c 2009-07-30 09:48:09.919627263 -0400
2380c486
JR
4111@@ -78,7 +78,7 @@ static void query_ist(void)
4112 if (cpu.level < 6)
4113 return;
4114
4115- asm("int $0x15"
4116+ asm volatile("int $0x15"
4117 : "=a" (boot_params.ist_info.signature),
4118 "=b" (boot_params.ist_info.command),
4119 "=c" (boot_params.ist_info.event),
017d2877
AM
4120diff -urNp linux-2.6.30.4/arch/x86/boot/mca.c linux-2.6.30.4/arch/x86/boot/mca.c
4121--- linux-2.6.30.4/arch/x86/boot/mca.c 2009-07-24 17:47:51.000000000 -0400
4122+++ linux-2.6.30.4/arch/x86/boot/mca.c 2009-07-30 09:48:09.919627263 -0400
2380c486
JR
4123@@ -19,7 +19,7 @@ int query_mca(void)
4124 u8 err;
4125 u16 es, bx, len;
4126
4127- asm("pushw %%es ; "
4128+ asm volatile("pushw %%es ; "
4129 "int $0x15 ; "
4130 "setc %0 ; "
4131 "movw %%es, %1 ; "
017d2877
AM
4132diff -urNp linux-2.6.30.4/arch/x86/boot/memory.c linux-2.6.30.4/arch/x86/boot/memory.c
4133--- linux-2.6.30.4/arch/x86/boot/memory.c 2009-07-24 17:47:51.000000000 -0400
4134+++ linux-2.6.30.4/arch/x86/boot/memory.c 2009-07-30 09:48:09.919627263 -0400
4135@@ -47,7 +47,7 @@ static int detect_memory_e820(void)
de855c5d 4136 so they must be either used for the error output
017d2877
AM
4137 or explicitly marked clobbered. Given that, assume there
4138 is something out there clobbering %ebp and %edi, too. */
4139- asm("pushl %%ebp; int $0x15; popl %%ebp; setc %0"
4140+ asm volatile("pushl %%ebp; int $0x15; popl %%ebp; setc %0"
2380c486 4141 : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
017d2877
AM
4142 "=D" (edi), "+m" (buf)
4143 : "D" (&buf), "d" (SMAP), "a" (0xe820)
4144@@ -83,7 +83,7 @@ static int detect_memory_e801(void)
2380c486
JR
4145
4146 bx = cx = dx = 0;
4147 ax = 0xe801;
4148- asm("stc; int $0x15; setc %0"
4149+ asm volatile("stc; int $0x15; setc %0"
4150 : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
4151
4152 if (err)
017d2877 4153@@ -113,7 +113,7 @@ static int detect_memory_88(void)
2380c486
JR
4154 u8 err;
4155
4156 ax = 0x8800;
4157- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
4158+ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
4159
4160 boot_params.screen_info.ext_mem_k = ax;
4161
017d2877
AM
4162diff -urNp linux-2.6.30.4/arch/x86/boot/video.c linux-2.6.30.4/arch/x86/boot/video.c
4163--- linux-2.6.30.4/arch/x86/boot/video.c 2009-07-24 17:47:51.000000000 -0400
4164+++ linux-2.6.30.4/arch/x86/boot/video.c 2009-07-30 09:48:09.920627513 -0400
2380c486
JR
4165@@ -23,7 +23,7 @@ static void store_cursor_position(void)
4166
4167 ax = 0x0300;
4168 bx = 0;
4169- asm(INT10
4170+ asm volatile(INT10
4171 : "=d" (curpos), "+a" (ax), "+b" (bx)
4172 : : "ecx", "esi", "edi");
4173
4174@@ -38,7 +38,7 @@ static void store_video_mode(void)
4175 /* N.B.: the saving of the video page here is a bit silly,
4176 since we pretty much assume page 0 everywhere. */
4177 ax = 0x0f00;
4178- asm(INT10
4179+ asm volatile(INT10
4180 : "+a" (ax), "=b" (page)
4181 : : "ecx", "edx", "esi", "edi");
4182
017d2877
AM
4183diff -urNp linux-2.6.30.4/arch/x86/boot/video-vesa.c linux-2.6.30.4/arch/x86/boot/video-vesa.c
4184--- linux-2.6.30.4/arch/x86/boot/video-vesa.c 2009-07-24 17:47:51.000000000 -0400
4185+++ linux-2.6.30.4/arch/x86/boot/video-vesa.c 2009-07-30 09:48:09.920627513 -0400
2380c486
JR
4186@@ -41,7 +41,7 @@ static int vesa_probe(void)
4187
4188 ax = 0x4f00;
4189 di = (size_t)&vginfo;
4190- asm(INT10
4191+ asm volatile(INT10
4192 : "+a" (ax), "+D" (di), "=m" (vginfo)
4193 : : "ebx", "ecx", "edx", "esi");
4194
4195@@ -68,7 +68,7 @@ static int vesa_probe(void)
4196 ax = 0x4f01;
4197 cx = mode;
4198 di = (size_t)&vminfo;
4199- asm(INT10
4200+ asm volatile(INT10
4201 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
4202 : : "ebx", "edx", "esi");
4203
4204@@ -120,7 +120,7 @@ static int vesa_set_mode(struct mode_inf
4205 ax = 0x4f01;
4206 cx = vesa_mode;
4207 di = (size_t)&vminfo;
4208- asm(INT10
4209+ asm volatile(INT10
4210 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
4211 : : "ebx", "edx", "esi");
4212
4213@@ -202,19 +202,20 @@ static void vesa_dac_set_8bits(void)
4214 /* Save the VESA protected mode info */
4215 static void vesa_store_pm_info(void)
4216 {
4217- u16 ax, bx, di, es;
4218+ u16 ax, bx, cx, di, es;
4219
4220 ax = 0x4f0a;
4221- bx = di = 0;
4222- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
4223- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
4224- : : "ecx", "esi");
4225+ bx = cx = di = 0;
4226+ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
4227+ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
4228+ : : "esi");
4229
4230 if (ax != 0x004f)
4231 return;
4232
4233 boot_params.screen_info.vesapm_seg = es;
4234 boot_params.screen_info.vesapm_off = di;
4235+ boot_params.screen_info.vesapm_size = cx;
4236 }
4237
4238 /*
4239@@ -268,7 +269,7 @@ void vesa_store_edid(void)
4240 /* Note: The VBE DDC spec is different from the main VESA spec;
4241 we genuinely have to assume all registers are destroyed here. */
4242
4243- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
4244+ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
4245 : "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
4246 : : "esi", "edx");
4247
4248@@ -283,7 +284,7 @@ void vesa_store_edid(void)
4249 cx = 0; /* Controller 0 */
4250 dx = 0; /* EDID block number */
4251 di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
4252- asm(INT10
4253+ asm volatile(INT10
4254 : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info),
4255 "+c" (cx), "+D" (di)
4256 : : "esi");
017d2877
AM
4257diff -urNp linux-2.6.30.4/arch/x86/boot/video-vga.c linux-2.6.30.4/arch/x86/boot/video-vga.c
4258--- linux-2.6.30.4/arch/x86/boot/video-vga.c 2009-07-30 20:32:40.362766121 -0400
4259+++ linux-2.6.30.4/arch/x86/boot/video-vga.c 2009-07-30 20:35:05.409914191 -0400
4260@@ -260,7 +260,7 @@ static int vga_probe(void)
2380c486
JR
4261 u8 vga_flag;
4262
017d2877 4263 ax = 0x1200;
2380c486
JR
4264- asm(INT10
4265+ asm volatile(INT10
017d2877
AM
4266 : "+a" (ax), "=b" (ega_bx)
4267 : "b" (0x10) /* Check EGA/VGA */
2380c486 4268 : "ecx", "edx", "esi", "edi");
017d2877 4269@@ -272,7 +272,7 @@ static int vga_probe(void)
2380c486
JR
4270 /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
4271 if ((u8)ega_bx != 0x10) {
4272 /* EGA/VGA */
4273- asm(INT10
4274+ asm volatile(INT10
4275 : "=a" (vga_flag)
4276 : "a" (0x1a00)
4277 : "ebx", "ecx", "edx", "esi", "edi");
017d2877
AM
4278diff -urNp linux-2.6.30.4/arch/x86/ia32/ia32_signal.c linux-2.6.30.4/arch/x86/ia32/ia32_signal.c
4279--- linux-2.6.30.4/arch/x86/ia32/ia32_signal.c 2009-07-24 17:47:51.000000000 -0400
4280+++ linux-2.6.30.4/arch/x86/ia32/ia32_signal.c 2009-07-30 09:48:09.921498916 -0400
4281@@ -403,7 +403,7 @@ static void __user *get_sigframe(struct
de855c5d
AM
4282 sp -= frame_size;
4283 /* Align the stack pointer according to the i386 ABI,
4284 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
4285- sp = ((sp + 4) & -16ul) - 4;
4286+ sp = ((sp - 12) & -16ul) - 4;
4287 return (void __user *) sp;
4288 }
4289
017d2877 4290@@ -503,7 +503,7 @@ int ia32_setup_rt_frame(int sig, struct
de855c5d 4291 0xb8,
2380c486
JR
4292 __NR_ia32_rt_sigreturn,
4293 0x80cd,
de855c5d 4294- 0,
2380c486
JR
4295+ 0
4296 };
4297
4298 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
017d2877
AM
4299diff -urNp linux-2.6.30.4/arch/x86/include/asm/alternative.h linux-2.6.30.4/arch/x86/include/asm/alternative.h
4300--- linux-2.6.30.4/arch/x86/include/asm/alternative.h 2009-07-24 17:47:51.000000000 -0400
4301+++ linux-2.6.30.4/arch/x86/include/asm/alternative.h 2009-07-30 09:48:09.921498916 -0400
2380c486
JR
4302@@ -96,7 +96,7 @@ const unsigned char *const *find_nop_tab
4303 " .byte 662b-661b\n" /* sourcelen */ \
4304 " .byte 664f-663f\n" /* replacementlen */ \
4305 ".previous\n" \
4306- ".section .altinstr_replacement,\"ax\"\n" \
4307+ ".section .altinstr_replacement,\"a\"\n" \
4308 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
4309 ".previous" :: "i" (feature) : "memory")
4310
4311@@ -120,7 +120,7 @@ const unsigned char *const *find_nop_tab
4312 " .byte 662b-661b\n" /* sourcelen */ \
4313 " .byte 664f-663f\n" /* replacementlen */ \
4314 ".previous\n" \
4315- ".section .altinstr_replacement,\"ax\"\n" \
4316+ ".section .altinstr_replacement,\"a\"\n" \
4317 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
4318 ".previous" :: "i" (feature), ##input)
4319
4320@@ -135,7 +135,7 @@ const unsigned char *const *find_nop_tab
4321 " .byte 662b-661b\n" /* sourcelen */ \
4322 " .byte 664f-663f\n" /* replacementlen */ \
4323 ".previous\n" \
4324- ".section .altinstr_replacement,\"ax\"\n" \
4325+ ".section .altinstr_replacement,\"a\"\n" \
4326 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
4327 ".previous" : output : [feat] "i" (feature), ##input)
4328
017d2877
AM
4329diff -urNp linux-2.6.30.4/arch/x86/include/asm/apm.h linux-2.6.30.4/arch/x86/include/asm/apm.h
4330--- linux-2.6.30.4/arch/x86/include/asm/apm.h 2009-07-24 17:47:51.000000000 -0400
4331+++ linux-2.6.30.4/arch/x86/include/asm/apm.h 2009-07-30 09:48:09.921498916 -0400
4332@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
4333 __asm__ __volatile__(APM_DO_ZERO_SEGS
4334 "pushl %%edi\n\t"
4335 "pushl %%ebp\n\t"
4336- "lcall *%%cs:apm_bios_entry\n\t"
4337+ "lcall *%%ss:apm_bios_entry\n\t"
4338 "setc %%al\n\t"
4339 "popl %%ebp\n\t"
4340 "popl %%edi\n\t"
4341@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
4342 __asm__ __volatile__(APM_DO_ZERO_SEGS
4343 "pushl %%edi\n\t"
4344 "pushl %%ebp\n\t"
4345- "lcall *%%cs:apm_bios_entry\n\t"
4346+ "lcall *%%ss:apm_bios_entry\n\t"
4347 "setc %%bl\n\t"
4348 "popl %%ebp\n\t"
4349 "popl %%edi\n\t"
4350diff -urNp linux-2.6.30.4/arch/x86/include/asm/atomic_32.h linux-2.6.30.4/arch/x86/include/asm/atomic_32.h
4351--- linux-2.6.30.4/arch/x86/include/asm/atomic_32.h 2009-07-24 17:47:51.000000000 -0400
4352+++ linux-2.6.30.4/arch/x86/include/asm/atomic_32.h 2009-07-30 09:48:09.921498916 -0400
2380c486
JR
4353@@ -39,7 +39,29 @@
4354 */
4355 static inline void atomic_add(int i, atomic_t *v)
4356 {
4357- asm volatile(LOCK_PREFIX "addl %1,%0"
4358+ asm volatile(LOCK_PREFIX "addl %1,%0\n"
4359+
4360+#ifdef CONFIG_PAX_REFCOUNT
4361+ "jno 0f\n"
4362+ LOCK_PREFIX "subl %1,%0\n"
4363+ "into\n0:\n"
4364+ _ASM_EXTABLE(0b, 0b)
4365+#endif
4366+
4367+ : "+m" (v->counter)
4368+ : "ir" (i));
4369+}
4370+
4371+/**
4372+ * atomic_add_unchecked - add integer to atomic variable
4373+ * @i: integer value to add
4374+ * @v: pointer of type atomic_t
4375+ *
4376+ * Atomically adds @i to @v.
4377+ */
de855c5d 4378+static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
2380c486
JR
4379+{
4380+ asm volatile(LOCK_PREFIX "addl %1,%0\n"
4381 : "+m" (v->counter)
4382 : "ir" (i));
4383 }
de855c5d 4384@@ -53,7 +75,29 @@ static inline void atomic_add(int i, ato
2380c486
JR
4385 */
4386 static inline void atomic_sub(int i, atomic_t *v)
4387 {
4388- asm volatile(LOCK_PREFIX "subl %1,%0"
4389+ asm volatile(LOCK_PREFIX "subl %1,%0\n"
4390+
4391+#ifdef CONFIG_PAX_REFCOUNT
4392+ "jno 0f\n"
4393+ LOCK_PREFIX "addl %1,%0\n"
4394+ "into\n0:\n"
4395+ _ASM_EXTABLE(0b, 0b)
4396+#endif
4397+
de855c5d
AM
4398+ : "+m" (v->counter)
4399+ : "ir" (i));
4400+}
4401+
4402+/**
4403+ * atomic_sub_unchecked - subtract integer from atomic variable
4404+ * @i: integer value to subtract
4405+ * @v: pointer of type atomic_t
4406+ *
4407+ * Atomically subtracts @i from @v.
4408+ */
4409+static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
4410+{
4411+ asm volatile(LOCK_PREFIX "subl %1,%0\n"
2380c486
JR
4412 : "+m" (v->counter)
4413 : "ir" (i));
4414 }
de855c5d 4415@@ -71,7 +115,16 @@ static inline int atomic_sub_and_test(in
2380c486
JR
4416 {
4417 unsigned char c;
4418
4419- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
4420+ asm volatile(LOCK_PREFIX "subl %2,%0\n"
4421+
4422+#ifdef CONFIG_PAX_REFCOUNT
4423+ "jno 0f\n"
4424+ LOCK_PREFIX "addl %2,%0\n"
4425+ "into\n0:\n"
4426+ _ASM_EXTABLE(0b, 0b)
4427+#endif
4428+
4429+ "sete %1\n"
4430 : "+m" (v->counter), "=qm" (c)
4431 : "ir" (i) : "memory");
4432 return c;
de855c5d 4433@@ -85,7 +138,30 @@ static inline int atomic_sub_and_test(in
2380c486
JR
4434 */
4435 static inline void atomic_inc(atomic_t *v)
4436 {
4437- asm volatile(LOCK_PREFIX "incl %0"
4438+ asm volatile(LOCK_PREFIX "incl %0\n"
4439+
4440+#ifdef CONFIG_PAX_REFCOUNT
4441+ "into\n0:\n"
4442+ ".pushsection .fixup,\"ax\"\n"
4443+ "1:\n"
4444+ LOCK_PREFIX "decl %0\n"
4445+ "jmp 0b\n"
4446+ ".popsection\n"
4447+ _ASM_EXTABLE(0b, 1b)
4448+#endif
4449+
de855c5d
AM
4450+ : "+m" (v->counter));
4451+}
4452+
4453+/**
4454+ * atomic_inc_unchecked - increment atomic variable
4455+ * @v: pointer of type atomic_t
4456+ *
4457+ * Atomically increments @v by 1.
4458+ */
4459+static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
4460+{
4461+ asm volatile(LOCK_PREFIX "incl %0\n"
2380c486
JR
4462 : "+m" (v->counter));
4463 }
4464
de855c5d 4465@@ -97,7 +173,18 @@ static inline void atomic_inc(atomic_t *
2380c486
JR
4466 */
4467 static inline void atomic_dec(atomic_t *v)
4468 {
4469- asm volatile(LOCK_PREFIX "decl %0"
4470+ asm volatile(LOCK_PREFIX "decl %0\n"
4471+
4472+#ifdef CONFIG_PAX_REFCOUNT
4473+ "into\n0:\n"
4474+ ".pushsection .fixup,\"ax\"\n"
4475+ "1: \n"
4476+ LOCK_PREFIX "incl %0\n"
4477+ "jmp 0b\n"
4478+ ".popsection\n"
4479+ _ASM_EXTABLE(0b, 1b)
4480+#endif
4481+
4482 : "+m" (v->counter));
4483 }
4484
de855c5d 4485@@ -113,7 +200,19 @@ static inline int atomic_dec_and_test(at
2380c486
JR
4486 {
4487 unsigned char c;
4488
4489- asm volatile(LOCK_PREFIX "decl %0; sete %1"
4490+ asm volatile(LOCK_PREFIX "decl %0\n"
4491+
4492+#ifdef CONFIG_PAX_REFCOUNT
4493+ "into\n0:\n"
4494+ ".pushsection .fixup,\"ax\"\n"
4495+ "1: \n"
4496+ LOCK_PREFIX "incl %0\n"
4497+ "jmp 0b\n"
4498+ ".popsection\n"
4499+ _ASM_EXTABLE(0b, 1b)
4500+#endif
4501+
4502+ "sete %1\n"
4503 : "+m" (v->counter), "=qm" (c)
4504 : : "memory");
4505 return c != 0;
de855c5d 4506@@ -131,7 +230,19 @@ static inline int atomic_inc_and_test(at
2380c486
JR
4507 {
4508 unsigned char c;
4509
4510- asm volatile(LOCK_PREFIX "incl %0; sete %1"
4511+ asm volatile(LOCK_PREFIX "incl %0\n"
4512+
4513+#ifdef CONFIG_PAX_REFCOUNT
4514+ "into\n0:\n"
4515+ ".pushsection .fixup,\"ax\"\n"
4516+ "1: \n"
4517+ LOCK_PREFIX "decl %0\n"
4518+ "jmp 0b\n"
4519+ ".popsection\n"
4520+ _ASM_EXTABLE(0b, 1b)
4521+#endif
4522+
4523+ "sete %1\n"
4524 : "+m" (v->counter), "=qm" (c)
4525 : : "memory");
4526 return c != 0;
de855c5d 4527@@ -150,7 +261,16 @@ static inline int atomic_add_negative(in
2380c486
JR
4528 {
4529 unsigned char c;
4530
4531- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
4532+ asm volatile(LOCK_PREFIX "addl %2,%0\n"
4533+
4534+#ifdef CONFIG_PAX_REFCOUNT
4535+ "jno 0f\n"
4536+ LOCK_PREFIX "subl %2,%0\n"
4537+ "into\n0:\n"
4538+ _ASM_EXTABLE(0b, 0b)
4539+#endif
4540+
4541+ "sets %1\n"
4542 : "+m" (v->counter), "=qm" (c)
4543 : "ir" (i) : "memory");
4544 return c;
de855c5d 4545@@ -173,7 +293,15 @@ static inline int atomic_add_return(int
2380c486
JR
4546 #endif
4547 /* Modern 486+ processor */
4548 __i = i;
4549- asm volatile(LOCK_PREFIX "xaddl %0, %1"
4550+ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
4551+
4552+#ifdef CONFIG_PAX_REFCOUNT
4553+ "jno 0f\n"
4554+ "movl %0, %1\n"
4555+ "into\n0:\n"
4556+ _ASM_EXTABLE(0b, 0b)
4557+#endif
4558+
4559 : "+r" (i), "+m" (v->counter)
4560 : : "memory");
4561 return i + __i;
de855c5d 4562@@ -214,17 +342,28 @@ static inline int atomic_sub_return(int
2380c486
JR
4563 */
4564 static inline int atomic_add_unless(atomic_t *v, int a, int u)
4565 {
4566- int c, old;
4567+ int c, old, new;
4568 c = atomic_read(v);
4569 for (;;) {
4570- if (unlikely(c == (u)))
4571+ if (unlikely(c == u))
4572 break;
4573- old = atomic_cmpxchg((v), c, c + (a));
4574+
4575+ asm volatile("addl %2,%0\n"
4576+
4577+#ifdef CONFIG_PAX_REFCOUNT
4578+ "into\n0:\n"
4579+ _ASM_EXTABLE(0b, 0b)
4580+#endif
4581+
4582+ : "=r" (new)
4583+ : "0" (c), "ir" (a));
4584+
4585+ old = atomic_cmpxchg(v, c, new);
4586 if (likely(old == c))
4587 break;
4588 c = old;
4589 }
4590- return c != (u);
4591+ return c != u;
4592 }
4593
4594 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
017d2877
AM
4595diff -urNp linux-2.6.30.4/arch/x86/include/asm/atomic_64.h linux-2.6.30.4/arch/x86/include/asm/atomic_64.h
4596--- linux-2.6.30.4/arch/x86/include/asm/atomic_64.h 2009-07-24 17:47:51.000000000 -0400
4597+++ linux-2.6.30.4/arch/x86/include/asm/atomic_64.h 2009-07-30 09:48:09.922664908 -0400
2380c486
JR
4598@@ -38,7 +38,29 @@
4599 */
4600 static inline void atomic_add(int i, atomic_t *v)
4601 {
4602- asm volatile(LOCK_PREFIX "addl %1,%0"
4603+ asm volatile(LOCK_PREFIX "addl %1,%0\n"
4604+
4605+#ifdef CONFIG_PAX_REFCOUNT
4606+ "jno 0f\n"
4607+ LOCK_PREFIX "subl %1,%0\n"
4608+ "int $4\n0:\n"
4609+ _ASM_EXTABLE(0b, 0b)
4610+#endif
4611+
4612+ : "=m" (v->counter)
4613+ : "ir" (i), "m" (v->counter));
4614+}
4615+
4616+/**
4617+ * atomic_add_unchecked - add integer to atomic variable
4618+ * @i: integer value to add
4619+ * @v: pointer of type atomic_t
4620+ *
4621+ * Atomically adds @i to @v.
4622+ */
de855c5d 4623+static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
2380c486
JR
4624+{
4625+ asm volatile(LOCK_PREFIX "addl %1,%0\n"
4626 : "=m" (v->counter)
4627 : "ir" (i), "m" (v->counter));
4628 }
de855c5d 4629@@ -52,7 +74,29 @@ static inline void atomic_add(int i, ato
2380c486
JR
4630 */
4631 static inline void atomic_sub(int i, atomic_t *v)
4632 {
4633- asm volatile(LOCK_PREFIX "subl %1,%0"
4634+ asm volatile(LOCK_PREFIX "subl %1,%0\n"
4635+
4636+#ifdef CONFIG_PAX_REFCOUNT
4637+ "jno 0f\n"
4638+ LOCK_PREFIX "addl %1,%0\n"
4639+ "int $4\n0:\n"
4640+ _ASM_EXTABLE(0b, 0b)
4641+#endif
4642+
de855c5d
AM
4643+ : "=m" (v->counter)
4644+ : "ir" (i), "m" (v->counter));
4645+}
4646+
4647+/**
4648+ * atomic_sub_unchecked - subtract the atomic variable
4649+ * @i: integer value to subtract
4650+ * @v: pointer of type atomic_t
4651+ *
4652+ * Atomically subtracts @i from @v.
4653+ */
4654+static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
4655+{
4656+ asm volatile(LOCK_PREFIX "subl %1,%0\n"
2380c486
JR
4657 : "=m" (v->counter)
4658 : "ir" (i), "m" (v->counter));
4659 }
de855c5d 4660@@ -70,7 +114,16 @@ static inline int atomic_sub_and_test(in
2380c486
JR
4661 {
4662 unsigned char c;
4663
4664- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
4665+ asm volatile(LOCK_PREFIX "subl %2,%0\n"
4666+
4667+#ifdef CONFIG_PAX_REFCOUNT
4668+ "jno 0f\n"
4669+ LOCK_PREFIX "addl %2,%0\n"
4670+ "int $4\n0:\n"
4671+ _ASM_EXTABLE(0b, 0b)
4672+#endif
4673+
4674+ "sete %1\n"
4675 : "=m" (v->counter), "=qm" (c)
4676 : "ir" (i), "m" (v->counter) : "memory");
4677 return c;
de855c5d 4678@@ -84,7 +137,32 @@ static inline int atomic_sub_and_test(in
2380c486
JR
4679 */
4680 static inline void atomic_inc(atomic_t *v)
4681 {
4682- asm volatile(LOCK_PREFIX "incl %0"
4683+ asm volatile(LOCK_PREFIX "incl %0\n"
4684+
4685+#ifdef CONFIG_PAX_REFCOUNT
4686+ "jno 0f\n"
4687+ "int $4\n0:\n"
4688+ ".pushsection .fixup,\"ax\"\n"
4689+ "1:\n"
4690+ LOCK_PREFIX "decl %0\n"
4691+ "jmp 0b\n"
4692+ ".popsection\n"
4693+ _ASM_EXTABLE(0b, 1b)
4694+#endif
4695+
de855c5d
AM
4696+ : "=m" (v->counter)
4697+ : "m" (v->counter));
4698+}
4699+
4700+/**
4701+ * atomic_inc_unchecked - increment atomic variable
4702+ * @v: pointer of type atomic_t
4703+ *
4704+ * Atomically increments @v by 1.
4705+ */
4706+static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
4707+{
4708+ asm volatile(LOCK_PREFIX "incl %0\n"
2380c486
JR
4709 : "=m" (v->counter)
4710 : "m" (v->counter));
4711 }
de855c5d 4712@@ -97,7 +175,19 @@ static inline void atomic_inc(atomic_t *
2380c486
JR
4713 */
4714 static inline void atomic_dec(atomic_t *v)
4715 {
4716- asm volatile(LOCK_PREFIX "decl %0"
4717+ asm volatile(LOCK_PREFIX "decl %0\n"
4718+
4719+#ifdef CONFIG_PAX_REFCOUNT
4720+ "jno 0f\n"
4721+ "int $4\n0:\n"
4722+ ".pushsection .fixup,\"ax\"\n"
4723+ "1: \n"
4724+ LOCK_PREFIX "incl %0\n"
4725+ "jmp 0b\n"
4726+ ".popsection\n"
4727+ _ASM_EXTABLE(0b, 1b)
4728+#endif
4729+
4730 : "=m" (v->counter)
4731 : "m" (v->counter));
4732 }
de855c5d 4733@@ -114,7 +204,20 @@ static inline int atomic_dec_and_test(at
2380c486
JR
4734 {
4735 unsigned char c;
4736
4737- asm volatile(LOCK_PREFIX "decl %0; sete %1"
4738+ asm volatile(LOCK_PREFIX "decl %0\n"
4739+
4740+#ifdef CONFIG_PAX_REFCOUNT
4741+ "jno 0f\n"
4742+ "int $4\n0:\n"
4743+ ".pushsection .fixup,\"ax\"\n"
4744+ "1: \n"
4745+ LOCK_PREFIX "incl %0\n"
4746+ "jmp 0b\n"
4747+ ".popsection\n"
4748+ _ASM_EXTABLE(0b, 1b)
4749+#endif
4750+
4751+ "sete %1\n"
4752 : "=m" (v->counter), "=qm" (c)
4753 : "m" (v->counter) : "memory");
4754 return c != 0;
de855c5d 4755@@ -132,7 +235,20 @@ static inline int atomic_inc_and_test(at
2380c486
JR
4756 {
4757 unsigned char c;
4758
4759- asm volatile(LOCK_PREFIX "incl %0; sete %1"
4760+ asm volatile(LOCK_PREFIX "incl %0\n"
4761+
4762+#ifdef CONFIG_PAX_REFCOUNT
4763+ "jno 0f\n"
4764+ "int $4\n0:\n"
4765+ ".pushsection .fixup,\"ax\"\n"
4766+ "1: \n"
4767+ LOCK_PREFIX "decl %0\n"
4768+ "jmp 0b\n"
4769+ ".popsection\n"
4770+ _ASM_EXTABLE(0b, 1b)
4771+#endif
4772+
4773+ "sete %1\n"
4774 : "=m" (v->counter), "=qm" (c)
4775 : "m" (v->counter) : "memory");
4776 return c != 0;
de855c5d 4777@@ -151,7 +267,16 @@ static inline int atomic_add_negative(in
2380c486
JR
4778 {
4779 unsigned char c;
4780
4781- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
4782+ asm volatile(LOCK_PREFIX "addl %2,%0\n"
4783+
4784+#ifdef CONFIG_PAX_REFCOUNT
4785+ "jno 0f\n"
4786+ LOCK_PREFIX "subl %2,%0\n"
4787+ "int $4\n0:\n"
4788+ _ASM_EXTABLE(0b, 0b)
4789+#endif
4790+
4791+ "sets %1\n"
4792 : "=m" (v->counter), "=qm" (c)
4793 : "ir" (i), "m" (v->counter) : "memory");
4794 return c;
de855c5d 4795@@ -167,7 +292,15 @@ static inline int atomic_add_negative(in
2380c486
JR
4796 static inline int atomic_add_return(int i, atomic_t *v)
4797 {
4798 int __i = i;
4799- asm volatile(LOCK_PREFIX "xaddl %0, %1"
4800+ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
4801+
4802+#ifdef CONFIG_PAX_REFCOUNT
4803+ "jno 0f\n"
4804+ "movl %0, %1\n"
4805+ "int $4\n0:\n"
4806+ _ASM_EXTABLE(0b, 0b)
4807+#endif
4808+
4809 : "+r" (i), "+m" (v->counter)
4810 : : "memory");
4811 return i + __i;
de855c5d 4812@@ -212,7 +345,15 @@ static inline int atomic_sub_return(int
2380c486
JR
4813 */
4814 static inline void atomic64_add(long i, atomic64_t *v)
4815 {
4816- asm volatile(LOCK_PREFIX "addq %1,%0"
4817+ asm volatile(LOCK_PREFIX "addq %1,%0\n"
4818+
4819+#ifdef CONFIG_PAX_REFCOUNT
4820+ "jno 0f\n"
4821+ LOCK_PREFIX "subq %1,%0\n"
4822+ "int $4\n0:\n"
4823+ _ASM_EXTABLE(0b, 0b)
4824+#endif
4825+
4826 : "=m" (v->counter)
4827 : "er" (i), "m" (v->counter));
4828 }
de855c5d 4829@@ -226,7 +367,15 @@ static inline void atomic64_add(long i,
2380c486
JR
4830 */
4831 static inline void atomic64_sub(long i, atomic64_t *v)
4832 {
4833- asm volatile(LOCK_PREFIX "subq %1,%0"
4834+ asm volatile(LOCK_PREFIX "subq %1,%0\n"
4835+
4836+#ifdef CONFIG_PAX_REFCOUNT
4837+ "jno 0f\n"
4838+ LOCK_PREFIX "addq %1,%0\n"
4839+ "int $4\n0:\n"
4840+ _ASM_EXTABLE(0b, 0b)
4841+#endif
4842+
4843 : "=m" (v->counter)
4844 : "er" (i), "m" (v->counter));
4845 }
de855c5d 4846@@ -244,7 +393,16 @@ static inline int atomic64_sub_and_test(
2380c486
JR
4847 {
4848 unsigned char c;
4849
4850- asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
4851+ asm volatile(LOCK_PREFIX "subq %2,%0\n"
4852+
4853+#ifdef CONFIG_PAX_REFCOUNT
4854+ "jno 0f\n"
4855+ LOCK_PREFIX "addq %2,%0\n"
4856+ "int $4\n0:\n"
4857+ _ASM_EXTABLE(0b, 0b)
4858+#endif
4859+
4860+ "sete %1\n"
4861 : "=m" (v->counter), "=qm" (c)
4862 : "er" (i), "m" (v->counter) : "memory");
4863 return c;
de855c5d 4864@@ -258,7 +416,19 @@ static inline int atomic64_sub_and_test(
2380c486
JR
4865 */
4866 static inline void atomic64_inc(atomic64_t *v)
4867 {
4868- asm volatile(LOCK_PREFIX "incq %0"
4869+ asm volatile(LOCK_PREFIX "incq %0\n"
4870+
4871+#ifdef CONFIG_PAX_REFCOUNT
4872+ "jno 0f\n"
4873+ "int $4\n0:\n"
4874+ ".pushsection .fixup,\"ax\"\n"
4875+ "1:\n"
4876+ LOCK_PREFIX "decq %0\n"
4877+ "jmp 0b\n"
4878+ ".popsection\n"
4879+ _ASM_EXTABLE(0b, 1b)
4880+#endif
4881+
4882 : "=m" (v->counter)
4883 : "m" (v->counter));
4884 }
de855c5d 4885@@ -271,7 +441,19 @@ static inline void atomic64_inc(atomic64
2380c486
JR
4886 */
4887 static inline void atomic64_dec(atomic64_t *v)
4888 {
4889- asm volatile(LOCK_PREFIX "decq %0"
4890+ asm volatile(LOCK_PREFIX "decq %0\n"
4891+
4892+#ifdef CONFIG_PAX_REFCOUNT
4893+ "jno 0f\n"
4894+ "int $4\n0:\n"
4895+ ".pushsection .fixup,\"ax\"\n"
4896+ "1: \n"
4897+ LOCK_PREFIX "incq %0\n"
4898+ "jmp 0b\n"
4899+ ".popsection\n"
4900+ _ASM_EXTABLE(0b, 1b)
4901+#endif
4902+
4903 : "=m" (v->counter)
4904 : "m" (v->counter));
4905 }
de855c5d 4906@@ -288,7 +470,20 @@ static inline int atomic64_dec_and_test(
2380c486
JR
4907 {
4908 unsigned char c;
4909
4910- asm volatile(LOCK_PREFIX "decq %0; sete %1"
4911+ asm volatile(LOCK_PREFIX "decq %0\n"
4912+
4913+#ifdef CONFIG_PAX_REFCOUNT
4914+ "jno 0f\n"
4915+ "int $4\n0:\n"
4916+ ".pushsection .fixup,\"ax\"\n"
4917+ "1: \n"
4918+ LOCK_PREFIX "incq %0\n"
4919+ "jmp 0b\n"
4920+ ".popsection\n"
4921+ _ASM_EXTABLE(0b, 1b)
4922+#endif
4923+
4924+ "sete %1\n"
4925 : "=m" (v->counter), "=qm" (c)
4926 : "m" (v->counter) : "memory");
4927 return c != 0;
de855c5d 4928@@ -306,7 +501,20 @@ static inline int atomic64_inc_and_test(
2380c486
JR
4929 {
4930 unsigned char c;
4931
4932- asm volatile(LOCK_PREFIX "incq %0; sete %1"
4933+ asm volatile(LOCK_PREFIX "incq %0\n"
4934+
4935+#ifdef CONFIG_PAX_REFCOUNT
4936+ "jno 0f\n"
4937+ "int $4\n0:\n"
4938+ ".pushsection .fixup,\"ax\"\n"
4939+ "1: \n"
4940+ LOCK_PREFIX "decq %0\n"
4941+ "jmp 0b\n"
4942+ ".popsection\n"
4943+ _ASM_EXTABLE(0b, 1b)
4944+#endif
4945+
4946+ "sete %1\n"
4947 : "=m" (v->counter), "=qm" (c)
4948 : "m" (v->counter) : "memory");
4949 return c != 0;
de855c5d 4950@@ -325,7 +533,16 @@ static inline int atomic64_add_negative(
2380c486
JR
4951 {
4952 unsigned char c;
4953
4954- asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
4955+ asm volatile(LOCK_PREFIX "addq %2,%0\n"
4956+
4957+#ifdef CONFIG_PAX_REFCOUNT
4958+ "jno 0f\n"
4959+ LOCK_PREFIX "subq %2,%0\n"
4960+ "int $4\n0:\n"
4961+ _ASM_EXTABLE(0b, 0b)
4962+#endif
4963+
4964+ "sets %1\n"
4965 : "=m" (v->counter), "=qm" (c)
4966 : "er" (i), "m" (v->counter) : "memory");
4967 return c;
de855c5d 4968@@ -341,7 +558,15 @@ static inline int atomic64_add_negative(
2380c486
JR
4969 static inline long atomic64_add_return(long i, atomic64_t *v)
4970 {
4971 long __i = i;
4972- asm volatile(LOCK_PREFIX "xaddq %0, %1;"
4973+ asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
4974+
4975+#ifdef CONFIG_PAX_REFCOUNT
4976+ "jno 0f\n"
4977+ "movq %0, %1\n"
4978+ "int $4\n0:\n"
4979+ _ASM_EXTABLE(0b, 0b)
4980+#endif
4981+
4982 : "+r" (i), "+m" (v->counter)
4983 : : "memory");
4984 return i + __i;
de855c5d 4985@@ -372,17 +597,29 @@ static inline long atomic64_sub_return(l
2380c486
JR
4986 */
4987 static inline int atomic_add_unless(atomic_t *v, int a, int u)
4988 {
4989- int c, old;
4990+ int c, old, new;
4991 c = atomic_read(v);
4992 for (;;) {
4993- if (unlikely(c == (u)))
4994+ if (unlikely(c == u))
4995 break;
4996- old = atomic_cmpxchg((v), c, c + (a));
4997+
4998+ asm volatile("addl %2,%0\n"
4999+
5000+#ifdef CONFIG_PAX_REFCOUNT
5001+ "jno 0f\n"
5002+ "int $4\n0:\n"
5003+ _ASM_EXTABLE(0b, 0b)
5004+#endif
5005+
5006+ : "=r" (new)
5007+ : "0" (c), "ir" (a));
5008+
5009+ old = atomic_cmpxchg(v, c, new);
5010 if (likely(old == c))
5011 break;
5012 c = old;
5013 }
5014- return c != (u);
5015+ return c != u;
5016 }
5017
5018 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
de855c5d 5019@@ -398,17 +635,29 @@ static inline int atomic_add_unless(atom
2380c486
JR
5020 */
5021 static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
5022 {
5023- long c, old;
5024+ long c, old, new;
5025 c = atomic64_read(v);
5026 for (;;) {
5027- if (unlikely(c == (u)))
5028+ if (unlikely(c == u))
5029 break;
5030- old = atomic64_cmpxchg((v), c, c + (a));
5031+
5032+ asm volatile("addq %2,%0\n"
5033+
5034+#ifdef CONFIG_PAX_REFCOUNT
5035+ "jno 0f\n"
5036+ "int $4\n0:\n"
5037+ _ASM_EXTABLE(0b, 0b)
5038+#endif
5039+
5040+ : "=r" (new)
5041+ : "0" (c), "er" (a));
5042+
5043+ old = atomic64_cmpxchg((v), c, new);
5044 if (likely(old == c))
5045 break;
5046 c = old;
5047 }
5048- return c != (u);
5049+ return c != u;
5050 }
5051
5052 /**
017d2877
AM
5053diff -urNp linux-2.6.30.4/arch/x86/include/asm/boot.h linux-2.6.30.4/arch/x86/include/asm/boot.h
5054--- linux-2.6.30.4/arch/x86/include/asm/boot.h 2009-07-24 17:47:51.000000000 -0400
5055+++ linux-2.6.30.4/arch/x86/include/asm/boot.h 2009-07-30 09:48:09.922664908 -0400
5056@@ -9,10 +9,15 @@
5057 #ifdef __KERNEL__
2380c486
JR
5058
5059 /* Physical address where kernel should be loaded. */
5060-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
5061+#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
5062 + (CONFIG_PHYSICAL_ALIGN - 1)) \
5063 & ~(CONFIG_PHYSICAL_ALIGN - 1))
5064
5065+#ifndef __ASSEMBLY__
5066+extern unsigned char __LOAD_PHYSICAL_ADDR[];
5067+#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
5068+#endif
5069+
017d2877
AM
5070 #ifdef CONFIG_KERNEL_BZIP2
5071 #define BOOT_HEAP_SIZE 0x400000
5072 #else /* !CONFIG_KERNEL_BZIP2 */
5073diff -urNp linux-2.6.30.4/arch/x86/include/asm/cache.h linux-2.6.30.4/arch/x86/include/asm/cache.h
5074--- linux-2.6.30.4/arch/x86/include/asm/cache.h 2009-07-24 17:47:51.000000000 -0400
5075+++ linux-2.6.30.4/arch/x86/include/asm/cache.h 2009-07-30 09:48:09.923412137 -0400
2380c486
JR
5076@@ -6,6 +6,7 @@
5077 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
5078
5079 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
5080+#define __read_only __attribute__((__section__(".data.read_only")))
5081
5082 #ifdef CONFIG_X86_VSMP
5083 /* vSMP Internode cacheline shift */
017d2877
AM
5084diff -urNp linux-2.6.30.4/arch/x86/include/asm/checksum_32.h linux-2.6.30.4/arch/x86/include/asm/checksum_32.h
5085--- linux-2.6.30.4/arch/x86/include/asm/checksum_32.h 2009-07-24 17:47:51.000000000 -0400
5086+++ linux-2.6.30.4/arch/x86/include/asm/checksum_32.h 2009-07-30 09:48:09.923412137 -0400
2380c486
JR
5087@@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
5088 int len, __wsum sum,
5089 int *src_err_ptr, int *dst_err_ptr);
5090
5091+asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
5092+ int len, __wsum sum,
5093+ int *src_err_ptr, int *dst_err_ptr);
5094+
5095+asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
5096+ int len, __wsum sum,
5097+ int *src_err_ptr, int *dst_err_ptr);
5098+
5099 /*
5100 * Note: when you get a NULL pointer exception here this means someone
5101 * passed in an incorrect kernel address to one of these functions.
5102@@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
5103 int *err_ptr)
5104 {
5105 might_sleep();
5106- return csum_partial_copy_generic((__force void *)src, dst,
5107+ return csum_partial_copy_generic_from_user((__force void *)src, dst,
5108 len, sum, err_ptr, NULL);
5109 }
5110
5111@@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
5112 {
5113 might_sleep();
5114 if (access_ok(VERIFY_WRITE, dst, len))
5115- return csum_partial_copy_generic(src, (__force void *)dst,
5116+ return csum_partial_copy_generic_to_user(src, (__force void *)dst,
5117 len, sum, NULL, err_ptr);
5118
5119 if (len)
017d2877
AM
5120diff -urNp linux-2.6.30.4/arch/x86/include/asm/desc.h linux-2.6.30.4/arch/x86/include/asm/desc.h
5121--- linux-2.6.30.4/arch/x86/include/asm/desc.h 2009-07-24 17:47:51.000000000 -0400
5122+++ linux-2.6.30.4/arch/x86/include/asm/desc.h 2009-07-30 09:48:09.923412137 -0400
2380c486
JR
5123@@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
5124 desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
5125 desc->type = (info->read_exec_only ^ 1) << 1;
5126 desc->type |= info->contents << 2;
5127+ desc->type |= info->seg_not_present ^ 1;
5128 desc->s = 1;
5129 desc->dpl = 0x3;
5130 desc->p = info->seg_not_present ^ 1;
5131@@ -32,16 +33,12 @@ static inline void fill_ldt(struct desc_
5132 }
5133
5134 extern struct desc_ptr idt_descr;
5135-extern gate_desc idt_table[];
5136-
5137-struct gdt_page {
5138- struct desc_struct gdt[GDT_ENTRIES];
5139-} __attribute__((aligned(PAGE_SIZE)));
017d2877 5140-DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
2380c486
JR
5141+extern gate_desc idt_table[256];
5142
5143+extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
5144 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
5145 {
5146- return per_cpu(gdt_page, cpu).gdt;
5147+ return cpu_gdt_table[cpu];
5148 }
5149
5150 #ifdef CONFIG_X86_64
017d2877 5151@@ -116,19 +113,48 @@ static inline void paravirt_free_ldt(str
2380c486
JR
5152 static inline void native_write_idt_entry(gate_desc *idt, int entry,
5153 const gate_desc *gate)
5154 {
5155+
5156+#ifdef CONFIG_PAX_KERNEXEC
5157+ unsigned long cr0;
5158+
5159+ pax_open_kernel(cr0);
5160+#endif
5161+
5162 memcpy(&idt[entry], gate, sizeof(*gate));
5163+
5164+#ifdef CONFIG_PAX_KERNEXEC
5165+ pax_close_kernel(cr0);
5166+#endif
5167+
5168 }
5169
5170 static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
5171 const void *desc)
5172 {
5173+
5174+#ifdef CONFIG_PAX_KERNEXEC
5175+ unsigned long cr0;
5176+
5177+ pax_open_kernel(cr0);
5178+#endif
5179+
5180 memcpy(&ldt[entry], desc, 8);
5181+
5182+#ifdef CONFIG_PAX_KERNEXEC
5183+ pax_close_kernel(cr0);
5184+#endif
5185+
5186 }
5187
5188 static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
5189 const void *desc, int type)
5190 {
5191 unsigned int size;
5192+
5193+#ifdef CONFIG_PAX_KERNEXEC
5194+ unsigned long cr0;
5195+#endif
5196+
5197 switch (type) {
5198 case DESC_TSS:
5199 size = sizeof(tss_desc);
017d2877 5200@@ -140,7 +166,17 @@ static inline void native_write_gdt_entr
2380c486
JR
5201 size = sizeof(struct desc_struct);
5202 break;
5203 }
5204+
5205+#ifdef CONFIG_PAX_KERNEXEC
5206+ pax_open_kernel(cr0);
5207+#endif
5208+
5209 memcpy(&gdt[entry], desc, size);
5210+
5211+#ifdef CONFIG_PAX_KERNEXEC
5212+ pax_close_kernel(cr0);
5213+#endif
5214+
5215 }
5216
5217 static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
017d2877 5218@@ -212,7 +248,19 @@ static inline void native_set_ldt(const
2380c486
JR
5219
5220 static inline void native_load_tr_desc(void)
5221 {
5222+
5223+#ifdef CONFIG_PAX_KERNEXEC
5224+ unsigned long cr0;
5225+
5226+ pax_open_kernel(cr0);
5227+#endif
5228+
5229 asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
5230+
5231+#ifdef CONFIG_PAX_KERNEXEC
5232+ pax_close_kernel(cr0);
5233+#endif
5234+
5235 }
5236
5237 static inline void native_load_gdt(const struct desc_ptr *dtr)
017d2877 5238@@ -247,8 +295,19 @@ static inline void native_load_tls(struc
2380c486
JR
5239 unsigned int i;
5240 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
5241
5242+#ifdef CONFIG_PAX_KERNEXEC
5243+ unsigned long cr0;
5244+
5245+ pax_open_kernel(cr0);
5246+#endif
5247+
5248 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
5249 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
5250+
5251+#ifdef CONFIG_PAX_KERNEXEC
5252+ pax_close_kernel(cr0);
5253+#endif
5254+
5255 }
5256
5257 #define _LDT_empty(info) \
017d2877 5258@@ -380,6 +439,18 @@ static inline void set_system_intr_gate_
2380c486
JR
5259 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
5260 }
5261
5262+#ifdef CONFIG_X86_32
5263+static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
5264+{
5265+ struct desc_struct d;
5266+
5267+ if (likely(limit))
5268+ limit = (limit - 1UL) >> PAGE_SHIFT;
5269+ pack_descriptor(&d, base, limit, 0xFB, 0xC);
5270+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
5271+}
5272+#endif
5273+
5274 #else
5275 /*
5276 * GET_DESC_BASE reads the descriptor base of the specified segment.
017d2877
AM
5277diff -urNp linux-2.6.30.4/arch/x86/include/asm/e820.h linux-2.6.30.4/arch/x86/include/asm/e820.h
5278--- linux-2.6.30.4/arch/x86/include/asm/e820.h 2009-07-24 17:47:51.000000000 -0400
5279+++ linux-2.6.30.4/arch/x86/include/asm/e820.h 2009-07-30 09:48:09.924429298 -0400
2380c486
JR
5280@@ -135,7 +135,7 @@ extern char *memory_setup(void);
5281 #define ISA_END_ADDRESS 0x100000
5282 #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
5283
5284-#define BIOS_BEGIN 0x000a0000
5285+#define BIOS_BEGIN 0x000c0000
5286 #define BIOS_END 0x00100000
5287
5288 #ifdef __KERNEL__
017d2877
AM
5289diff -urNp linux-2.6.30.4/arch/x86/include/asm/elf.h linux-2.6.30.4/arch/x86/include/asm/elf.h
5290--- linux-2.6.30.4/arch/x86/include/asm/elf.h 2009-07-24 17:47:51.000000000 -0400
5291+++ linux-2.6.30.4/arch/x86/include/asm/elf.h 2009-07-30 09:48:09.927602624 -0400
5292@@ -263,7 +263,25 @@ extern int force_personality32;
2380c486
JR
5293 the loader. We need to make sure that it is out of the way of the program
5294 that it will "exec", and that there is sufficient room for the brk. */
5295
5296+#ifdef CONFIG_PAX_SEGMEXEC
5297+#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
5298+#else
5299 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
5300+#endif
5301+
5302+#ifdef CONFIG_PAX_ASLR
5303+#ifdef CONFIG_X86_32
5304+#define PAX_ELF_ET_DYN_BASE 0x10000000UL
5305+
5306+#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
5307+#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
5308+#else
5309+#define PAX_ELF_ET_DYN_BASE 0x400000UL
5310+
5311+#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
5312+#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
5313+#endif
5314+#endif
5315
5316 /* This yields a mask that user programs can use to figure out what
5317 instruction set this CPU supports. This could be done in user space,
017d2877 5318@@ -315,8 +333,7 @@ do { \
2380c486
JR
5319 #define ARCH_DLINFO \
5320 do { \
5321 if (vdso_enabled) \
5322- NEW_AUX_ENT(AT_SYSINFO_EHDR, \
5323- (unsigned long)current->mm->context.vdso); \
5324+ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
5325 } while (0)
5326
5327 #define AT_SYSINFO 32
017d2877 5328@@ -327,7 +344,7 @@ do { \
2380c486
JR
5329
5330 #endif /* !CONFIG_X86_32 */
5331
5332-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
5333+#define VDSO_CURRENT_BASE (current->mm->context.vdso)
5334
5335 #define VDSO_ENTRY \
5336 ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
017d2877 5337@@ -341,7 +358,4 @@ extern int arch_setup_additional_pages(s
2380c486
JR
5338 extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
5339 #define compat_arch_setup_additional_pages syscall32_setup_pages
5340
5341-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
5342-#define arch_randomize_brk arch_randomize_brk
5343-
5344 #endif /* _ASM_X86_ELF_H */
017d2877
AM
5345diff -urNp linux-2.6.30.4/arch/x86/include/asm/futex.h linux-2.6.30.4/arch/x86/include/asm/futex.h
5346--- linux-2.6.30.4/arch/x86/include/asm/futex.h 2009-07-24 17:47:51.000000000 -0400
5347+++ linux-2.6.30.4/arch/x86/include/asm/futex.h 2009-07-30 09:48:09.927602624 -0400
2380c486
JR
5348@@ -11,6 +11,40 @@
5349 #include <asm/processor.h>
5350 #include <asm/system.h>
5351
5352+#ifdef CONFIG_X86_32
5353+#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
5354+ asm volatile( \
5355+ "movw\t%w6, %%ds\n" \
5356+ "1:\t" insn "\n" \
5357+ "2:\tpushl\t%%ss\n" \
5358+ "\tpopl\t%%ds\n" \
5359+ "\t.section .fixup,\"ax\"\n" \
5360+ "3:\tmov\t%3, %1\n" \
5361+ "\tjmp\t2b\n" \
5362+ "\t.previous\n" \
5363+ _ASM_EXTABLE(1b, 3b) \
5364+ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
5365+ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
5366+
5367+#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
5368+ asm volatile("movw\t%w7, %%es\n" \
5369+ "1:\tmovl\t%%es:%2, %0\n" \
5370+ "\tmovl\t%0, %3\n" \
5371+ "\t" insn "\n" \
5372+ "2:\t" LOCK_PREFIX "cmpxchgl %3, %%es:%2\n"\
5373+ "\tjnz\t1b\n" \
5374+ "3:\tpushl\t%%ss\n" \
5375+ "\tpopl\t%%es\n" \
5376+ "\t.section .fixup,\"ax\"\n" \
5377+ "4:\tmov\t%5, %1\n" \
5378+ "\tjmp\t3b\n" \
5379+ "\t.previous\n" \
5380+ _ASM_EXTABLE(1b, 4b) \
5381+ _ASM_EXTABLE(2b, 4b) \
5382+ : "=&a" (oldval), "=&r" (ret), \
5383+ "+m" (*uaddr), "=&r" (tem) \
5384+ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
5385+#else
5386 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
5387 asm volatile("1:\t" insn "\n" \
5388 "2:\t.section .fixup,\"ax\"\n" \
5389@@ -36,8 +70,9 @@
5390 : "=&a" (oldval), "=&r" (ret), \
5391 "+m" (*uaddr), "=&r" (tem) \
5392 : "r" (oparg), "i" (-EFAULT), "1" (0))
5393+#endif
5394
5395-static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
5396+static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
5397 {
5398 int op = (encoded_op >> 28) & 7;
5399 int cmp = (encoded_op >> 24) & 15;
5400@@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
5401
5402 switch (op) {
5403 case FUTEX_OP_SET:
5404+#ifdef CONFIG_X86_32
5405+ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
5406+#else
5407 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
5408+#endif
5409 break;
5410 case FUTEX_OP_ADD:
5411+#ifdef CONFIG_X86_32
5412+ __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret, oldval,
5413+ uaddr, oparg);
5414+#else
5415 __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
5416 uaddr, oparg);
5417+#endif
5418 break;
5419 case FUTEX_OP_OR:
5420 __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
5421@@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
5422 return ret;
5423 }
5424
5425-static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
5426+static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
5427 int newval)
5428 {
5429
5430@@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
5431 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
5432 return -EFAULT;
5433
5434- asm volatile("1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
5435+ asm volatile(
5436+#ifdef CONFIG_X86_32
5437+ "\tmovw %w5, %%ds\n"
5438+ "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
5439+ "2:\tpushl %%ss\n"
5440+ "\tpopl %%ds\n"
5441+ "\t.section .fixup, \"ax\"\n"
5442+#else
5443+ "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n"
5444 "2:\t.section .fixup, \"ax\"\n"
5445+#endif
5446 "3:\tmov %2, %0\n"
5447 "\tjmp 2b\n"
5448 "\t.previous\n"
5449 _ASM_EXTABLE(1b, 3b)
5450 : "=a" (oldval), "+m" (*uaddr)
5451+#ifdef CONFIG_X86_32
5452+ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
5453+#else
5454 : "i" (-EFAULT), "r" (newval), "0" (oldval)
5455+#endif
5456 : "memory"
5457 );
5458
017d2877
AM
5459diff -urNp linux-2.6.30.4/arch/x86/include/asm/i387.h linux-2.6.30.4/arch/x86/include/asm/i387.h
5460--- linux-2.6.30.4/arch/x86/include/asm/i387.h 2009-07-24 17:47:51.000000000 -0400
5461+++ linux-2.6.30.4/arch/x86/include/asm/i387.h 2009-07-30 09:48:09.927602624 -0400
2380c486
JR
5462@@ -203,13 +203,8 @@ static inline void restore_fpu(struct ta
5463 }
5464
5465 /* We need a safe address that is cheap to find and that is already
5466- in L1 during context switch. The best choices are unfortunately
5467- different for UP and SMP */
5468-#ifdef CONFIG_SMP
5469-#define safe_address (__per_cpu_offset[0])
5470-#else
5471-#define safe_address (kstat_cpu(0).cpustat.user)
5472-#endif
5473+ in L1 during context switch. */
5474+#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
5475
5476 /*
5477 * These must be called with preempt disabled
017d2877
AM
5478diff -urNp linux-2.6.30.4/arch/x86/include/asm/io_64.h linux-2.6.30.4/arch/x86/include/asm/io_64.h
5479--- linux-2.6.30.4/arch/x86/include/asm/io_64.h 2009-07-24 17:47:51.000000000 -0400
5480+++ linux-2.6.30.4/arch/x86/include/asm/io_64.h 2009-07-30 09:48:09.927602624 -0400
5481@@ -140,6 +140,17 @@ __OUTS(l)
5482
5483 #include <linux/vmalloc.h>
2380c486
JR
5484
5485+#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
5486+static inline int valid_phys_addr_range (unsigned long addr, size_t count)
5487+{
5488+ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
5489+}
5490+
5491+static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
5492+{
5493+ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
5494+}
5495+
017d2877
AM
5496 #include <asm-generic/iomap.h>
5497
5498 void __memcpy_fromio(void *, unsigned long, unsigned);
5499diff -urNp linux-2.6.30.4/arch/x86/include/asm/irqflags.h linux-2.6.30.4/arch/x86/include/asm/irqflags.h
5500--- linux-2.6.30.4/arch/x86/include/asm/irqflags.h 2009-07-24 17:47:51.000000000 -0400
5501+++ linux-2.6.30.4/arch/x86/include/asm/irqflags.h 2009-07-30 09:48:09.928623877 -0400
2380c486
JR
5502@@ -141,6 +141,8 @@ static inline unsigned long __raw_local_
5503 #define INTERRUPT_RETURN iret
5504 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
5505 #define GET_CR0_INTO_EAX movl %cr0, %eax
5506+#define GET_CR0_INTO_EDX movl %cr0, %edx
5507+#define SET_CR0_FROM_EDX movl %edx, %cr0
5508 #endif
5509
5510
017d2877
AM
5511diff -urNp linux-2.6.30.4/arch/x86/include/asm/kmap_types.h linux-2.6.30.4/arch/x86/include/asm/kmap_types.h
5512--- linux-2.6.30.4/arch/x86/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
5513+++ linux-2.6.30.4/arch/x86/include/asm/kmap_types.h 2009-07-30 09:48:09.928623877 -0400
2380c486
JR
5514@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
5515 D(10) KM_IRQ1,
5516 D(11) KM_SOFTIRQ0,
5517 D(12) KM_SOFTIRQ1,
5518-D(13) KM_TYPE_NR
5519+D(13) KM_CLEARPAGE,
5520+D(14) KM_TYPE_NR
5521 };
5522
5523 #undef D
017d2877
AM
5524diff -urNp linux-2.6.30.4/arch/x86/include/asm/kvm_host.h linux-2.6.30.4/arch/x86/include/asm/kvm_host.h
5525--- linux-2.6.30.4/arch/x86/include/asm/kvm_host.h 2009-07-24 17:47:51.000000000 -0400
5526+++ linux-2.6.30.4/arch/x86/include/asm/kvm_host.h 2009-07-30 09:48:09.928623877 -0400
5527@@ -529,7 +529,7 @@ struct kvm_x86_ops {
2380c486
JR
5528 int (*get_mt_mask_shift)(void);
5529 };
5530
5531-extern struct kvm_x86_ops *kvm_x86_ops;
5532+extern const struct kvm_x86_ops *kvm_x86_ops;
5533
5534 int kvm_mmu_module_init(void);
5535 void kvm_mmu_module_exit(void);
017d2877
AM
5536diff -urNp linux-2.6.30.4/arch/x86/include/asm/local.h linux-2.6.30.4/arch/x86/include/asm/local.h
5537--- linux-2.6.30.4/arch/x86/include/asm/local.h 2009-07-24 17:47:51.000000000 -0400
5538+++ linux-2.6.30.4/arch/x86/include/asm/local.h 2009-07-30 09:48:09.929617473 -0400
2380c486
JR
5539@@ -18,26 +18,90 @@ typedef struct {
5540
5541 static inline void local_inc(local_t *l)
5542 {
5543- asm volatile(_ASM_INC "%0"
5544+ asm volatile(_ASM_INC "%0\n"
5545+
5546+#ifdef CONFIG_PAX_REFCOUNT
5547+#ifdef CONFIG_X86_32
5548+ "into\n0:\n"
5549+#else
5550+ "jno 0f\n"
5551+ "int $4\n0:\n"
5552+#endif
5553+ ".pushsection .fixup,\"ax\"\n"
5554+ "1:\n"
5555+ _ASM_DEC "%0\n"
5556+ "jmp 0b\n"
5557+ ".popsection\n"
5558+ _ASM_EXTABLE(0b, 1b)
5559+#endif
5560+
5561 : "+m" (l->a.counter));
5562 }
5563
5564 static inline void local_dec(local_t *l)
5565 {
5566- asm volatile(_ASM_DEC "%0"
5567+ asm volatile(_ASM_DEC "%0\n"
5568+
5569+#ifdef CONFIG_PAX_REFCOUNT
5570+#ifdef CONFIG_X86_32
5571+ "into\n0:\n"
5572+#else
5573+ "jno 0f\n"
5574+ "int $4\n0:\n"
5575+#endif
5576+ ".pushsection .fixup,\"ax\"\n"
5577+ "1:\n"
5578+ _ASM_INC "%0\n"
5579+ "jmp 0b\n"
5580+ ".popsection\n"
5581+ _ASM_EXTABLE(0b, 1b)
5582+#endif
5583+
5584 : "+m" (l->a.counter));
5585 }
5586
5587 static inline void local_add(long i, local_t *l)
5588 {
5589- asm volatile(_ASM_ADD "%1,%0"
5590+ asm volatile(_ASM_ADD "%1,%0\n"
5591+
5592+#ifdef CONFIG_PAX_REFCOUNT
5593+#ifdef CONFIG_X86_32
5594+ "into\n0:\n"
5595+#else
5596+ "jno 0f\n"
5597+ "int $4\n0:\n"
5598+#endif
5599+ ".pushsection .fixup,\"ax\"\n"
5600+ "1:\n"
5601+ _ASM_SUB "%1,%0\n"
5602+ "jmp 0b\n"
5603+ ".popsection\n"
5604+ _ASM_EXTABLE(0b, 1b)
5605+#endif
5606+
5607 : "+m" (l->a.counter)
5608 : "ir" (i));
5609 }
5610
5611 static inline void local_sub(long i, local_t *l)
5612 {
5613- asm volatile(_ASM_SUB "%1,%0"
5614+ asm volatile(_ASM_SUB "%1,%0\n"
5615+
5616+#ifdef CONFIG_PAX_REFCOUNT
5617+#ifdef CONFIG_X86_32
5618+ "into\n0:\n"
5619+#else
5620+ "jno 0f\n"
5621+ "int $4\n0:\n"
5622+#endif
5623+ ".pushsection .fixup,\"ax\"\n"
5624+ "1:\n"
5625+ _ASM_ADD "%1,%0\n"
5626+ "jmp 0b\n"
5627+ ".popsection\n"
5628+ _ASM_EXTABLE(0b, 1b)
5629+#endif
5630+
5631 : "+m" (l->a.counter)
5632 : "ir" (i));
5633 }
5634@@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
5635 {
5636 unsigned char c;
5637
5638- asm volatile(_ASM_SUB "%2,%0; sete %1"
5639+ asm volatile(_ASM_SUB "%2,%0\n"
5640+
5641+#ifdef CONFIG_PAX_REFCOUNT
5642+#ifdef CONFIG_X86_32
5643+ "into\n0:\n"
5644+#else
5645+ "jno 0f\n"
5646+ "int $4\n0:\n"
5647+#endif
5648+ ".pushsection .fixup,\"ax\"\n"
5649+ "1:\n"
5650+ _ASM_ADD "%2,%0\n"
5651+ "jmp 0b\n"
5652+ ".popsection\n"
5653+ _ASM_EXTABLE(0b, 1b)
5654+#endif
5655+
5656+ "sete %1\n"
5657 : "+m" (l->a.counter), "=qm" (c)
5658 : "ir" (i) : "memory");
5659 return c;
5660@@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
5661 {
5662 unsigned char c;
5663
5664- asm volatile(_ASM_DEC "%0; sete %1"
5665+ asm volatile(_ASM_DEC "%0\n"
5666+
5667+#ifdef CONFIG_PAX_REFCOUNT
5668+#ifdef CONFIG_X86_32
5669+ "into\n0:\n"
5670+#else
5671+ "jno 0f\n"
5672+ "int $4\n0:\n"
5673+#endif
5674+ ".pushsection .fixup,\"ax\"\n"
5675+ "1:\n"
5676+ _ASM_INC "%0\n"
5677+ "jmp 0b\n"
5678+ ".popsection\n"
5679+ _ASM_EXTABLE(0b, 1b)
5680+#endif
5681+
5682+ "sete %1\n"
5683 : "+m" (l->a.counter), "=qm" (c)
5684 : : "memory");
5685 return c != 0;
5686@@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
5687 {
5688 unsigned char c;
5689
5690- asm volatile(_ASM_INC "%0; sete %1"
5691+ asm volatile(_ASM_INC "%0\n"
5692+
5693+#ifdef CONFIG_PAX_REFCOUNT
5694+#ifdef CONFIG_X86_32
5695+ "into\n0:\n"
5696+#else
5697+ "jno 0f\n"
5698+ "int $4\n0:\n"
5699+#endif
5700+ ".pushsection .fixup,\"ax\"\n"
5701+ "1:\n"
5702+ _ASM_DEC "%0\n"
5703+ "jmp 0b\n"
5704+ ".popsection\n"
5705+ _ASM_EXTABLE(0b, 1b)
5706+#endif
5707+
5708+ "sete %1\n"
5709 : "+m" (l->a.counter), "=qm" (c)
5710 : : "memory");
5711 return c != 0;
5712@@ -110,7 +225,24 @@ static inline int local_add_negative(lon
5713 {
5714 unsigned char c;
5715
5716- asm volatile(_ASM_ADD "%2,%0; sets %1"
5717+ asm volatile(_ASM_ADD "%2,%0\n"
5718+
5719+#ifdef CONFIG_PAX_REFCOUNT
5720+#ifdef CONFIG_X86_32
5721+ "into\n0:\n"
5722+#else
5723+ "jno 0f\n"
5724+ "int $4\n0:\n"
5725+#endif
5726+ ".pushsection .fixup,\"ax\"\n"
5727+ "1:\n"
5728+ _ASM_SUB "%2,%0\n"
5729+ "jmp 0b\n"
5730+ ".popsection\n"
5731+ _ASM_EXTABLE(0b, 1b)
5732+#endif
5733+
5734+ "sets %1\n"
5735 : "+m" (l->a.counter), "=qm" (c)
5736 : "ir" (i) : "memory");
5737 return c;
5738@@ -133,7 +265,23 @@ static inline long local_add_return(long
5739 #endif
5740 /* Modern 486+ processor */
5741 __i = i;
5742- asm volatile(_ASM_XADD "%0, %1;"
5743+ asm volatile(_ASM_XADD "%0, %1\n"
5744+
5745+#ifdef CONFIG_PAX_REFCOUNT
5746+#ifdef CONFIG_X86_32
5747+ "into\n0:\n"
5748+#else
5749+ "jno 0f\n"
5750+ "int $4\n0:\n"
5751+#endif
5752+ ".pushsection .fixup,\"ax\"\n"
5753+ "1:\n"
5754+ _ASM_MOV "%0,%1\n"
5755+ "jmp 0b\n"
5756+ ".popsection\n"
5757+ _ASM_EXTABLE(0b, 1b)
5758+#endif
5759+
5760 : "+r" (i), "+m" (l->a.counter)
5761 : : "memory");
5762 return i + __i;
017d2877
AM
5763diff -urNp linux-2.6.30.4/arch/x86/include/asm/mman.h linux-2.6.30.4/arch/x86/include/asm/mman.h
5764--- linux-2.6.30.4/arch/x86/include/asm/mman.h 2009-07-24 17:47:51.000000000 -0400
5765+++ linux-2.6.30.4/arch/x86/include/asm/mman.h 2009-07-30 09:48:09.929617473 -0400
2380c486
JR
5766@@ -17,4 +17,14 @@
5767 #define MCL_CURRENT 1 /* lock all current mappings */
5768 #define MCL_FUTURE 2 /* lock all future mappings */
5769
5770+#ifdef __KERNEL__
5771+#ifndef __ASSEMBLY__
5772+#ifdef CONFIG_X86_32
5773+#define arch_mmap_check i386_mmap_check
5774+int i386_mmap_check(unsigned long addr, unsigned long len,
5775+ unsigned long flags);
5776+#endif
5777+#endif
5778+#endif
5779+
5780 #endif /* _ASM_X86_MMAN_H */
017d2877
AM
5781diff -urNp linux-2.6.30.4/arch/x86/include/asm/mmu_context.h linux-2.6.30.4/arch/x86/include/asm/mmu_context.h
5782--- linux-2.6.30.4/arch/x86/include/asm/mmu_context.h 2009-07-24 17:47:51.000000000 -0400
5783+++ linux-2.6.30.4/arch/x86/include/asm/mmu_context.h 2009-07-30 09:48:09.929617473 -0400
5784@@ -34,11 +34,17 @@ static inline void switch_mm(struct mm_s
de855c5d
AM
5785 struct task_struct *tsk)
5786 {
017d2877
AM
5787 unsigned cpu = smp_processor_id();
5788+#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
de855c5d
AM
5789+ int tlbstate = TLBSTATE_OK;
5790+#endif
5791
5792 if (likely(prev != next)) {
5793 /* stop flush ipis for the previous mm */
5794 cpu_clear(cpu, prev->cpu_vm_mask);
5795 #ifdef CONFIG_SMP
017d2877
AM
5796+#ifdef CONFIG_X86_32
5797+ tlbstate = percpu_read(cpu_tlbstate.state);
5798+#endif
5799 percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
5800 percpu_write(cpu_tlbstate.active_mm, next);
de855c5d 5801 #endif
017d2877 5802@@ -52,6 +58,26 @@ static inline void switch_mm(struct mm_s
2380c486
JR
5803 */
5804 if (unlikely(prev->context.ldt != next->context.ldt))
5805 load_LDT_nolock(&next->context);
5806+
017d2877 5807+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
2380c486
JR
5808+ if (!nx_enabled) {
5809+ smp_mb__before_clear_bit();
5810+ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
5811+ smp_mb__after_clear_bit();
5812+ cpu_set(cpu, next->context.cpu_user_cs_mask);
5813+ }
5814+#endif
5815+
017d2877 5816+#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC))
2380c486 5817+ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
de855c5d
AM
5818+ prev->context.user_cs_limit != next->context.user_cs_limit
5819+#ifdef CONFIG_SMP
5820+ || tlbstate != TLBSTATE_OK
5821+#endif
5822+ ))
2380c486
JR
5823+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
5824+#endif
5825+
5826 }
5827 #ifdef CONFIG_SMP
5828 else {
017d2877 5829@@ -65,6 +91,19 @@ static inline void switch_mm(struct mm_s
2380c486
JR
5830 */
5831 load_cr3(next->pgd);
5832 load_LDT_nolock(&next->context);
5833+
017d2877 5834+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
2380c486
JR
5835+ if (!nx_enabled)
5836+ cpu_set(cpu, next->context.cpu_user_cs_mask);
5837+#endif
5838+
017d2877 5839+#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC))
2380c486
JR
5840+#ifdef CONFIG_PAX_PAGEEXEC
5841+ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
5842+#endif
5843+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
5844+#endif
5845+
5846 }
5847 }
5848 #endif
017d2877
AM
5849diff -urNp linux-2.6.30.4/arch/x86/include/asm/mmu.h linux-2.6.30.4/arch/x86/include/asm/mmu.h
5850--- linux-2.6.30.4/arch/x86/include/asm/mmu.h 2009-07-24 17:47:51.000000000 -0400
5851+++ linux-2.6.30.4/arch/x86/include/asm/mmu.h 2009-07-30 09:48:09.929617473 -0400
2380c486
JR
5852@@ -9,10 +9,23 @@
5853 * we put the segment information here.
5854 */
5855 typedef struct {
5856- void *ldt;
5857+ struct desc_struct *ldt;
5858 int size;
5859 struct mutex lock;
5860- void *vdso;
5861+ unsigned long vdso;
5862+
5863+#ifdef CONFIG_X86_32
5864+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5865+ unsigned long user_cs_base;
5866+ unsigned long user_cs_limit;
5867+
5868+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5869+ cpumask_t cpu_user_cs_mask;
5870+#endif
5871+
5872+#endif
5873+#endif
5874+
5875 } mm_context_t;
5876
5877 #ifdef CONFIG_SMP
017d2877
AM
5878diff -urNp linux-2.6.30.4/arch/x86/include/asm/module.h linux-2.6.30.4/arch/x86/include/asm/module.h
5879--- linux-2.6.30.4/arch/x86/include/asm/module.h 2009-07-24 17:47:51.000000000 -0400
5880+++ linux-2.6.30.4/arch/x86/include/asm/module.h 2009-07-30 11:10:48.877547128 -0400
2380c486
JR
5881@@ -74,7 +74,12 @@ struct mod_arch_specific {};
5882 # else
5883 # define MODULE_STACKSIZE ""
5884 # endif
5885-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
5886+# ifdef CONFIG_GRKERNSEC
5887+# define MODULE_GRSEC "GRSECURITY "
5888+# else
5889+# define MODULE_GRSEC ""
5890+# endif
5891+# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
5892 #endif
5893
5894 #endif /* _ASM_X86_MODULE_H */
017d2877
AM
5895diff -urNp linux-2.6.30.4/arch/x86/include/asm/page_32_types.h linux-2.6.30.4/arch/x86/include/asm/page_32_types.h
5896--- linux-2.6.30.4/arch/x86/include/asm/page_32_types.h 2009-07-24 17:47:51.000000000 -0400
5897+++ linux-2.6.30.4/arch/x86/include/asm/page_32_types.h 2009-07-30 09:48:09.930625879 -0400
5898@@ -15,6 +15,23 @@
2380c486
JR
5899 */
5900 #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
5901
5902+#ifdef CONFIG_PAX_KERNEXEC
5903+#ifndef __ASSEMBLY__
5904+extern unsigned char MODULES_VADDR[];
5905+extern unsigned char MODULES_END[];
5906+extern unsigned char KERNEL_TEXT_OFFSET[];
5907+#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
5908+#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
5909+#endif
5910+#else
5911+#define ktla_ktva(addr) (addr)
5912+#define ktva_ktla(addr) (addr)
5913+#endif
5914+
5915+#ifdef CONFIG_PAX_PAGEEXEC
5916+#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
5917+#endif
5918+
5919 #ifdef CONFIG_4KSTACKS
5920 #define THREAD_ORDER 0
5921 #else
017d2877
AM
5922diff -urNp linux-2.6.30.4/arch/x86/include/asm/page_64_types.h linux-2.6.30.4/arch/x86/include/asm/page_64_types.h
5923--- linux-2.6.30.4/arch/x86/include/asm/page_64_types.h 2009-07-24 17:47:51.000000000 -0400
5924+++ linux-2.6.30.4/arch/x86/include/asm/page_64_types.h 2009-07-30 09:48:09.930625879 -0400
5925@@ -47,6 +47,9 @@
2380c486
JR
5926 #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
5927 #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
5928
5929+#define ktla_ktva(addr) (addr)
5930+#define ktva_ktla(addr) (addr)
5931+
5932 /* See Documentation/x86_64/mm.txt for a description of the memory map. */
5933 #define __PHYSICAL_MASK_SHIFT 46
5934 #define __VIRTUAL_MASK_SHIFT 48
017d2877
AM
5935diff -urNp linux-2.6.30.4/arch/x86/include/asm/paravirt.h linux-2.6.30.4/arch/x86/include/asm/paravirt.h
5936--- linux-2.6.30.4/arch/x86/include/asm/paravirt.h 2009-07-24 17:47:51.000000000 -0400
5937+++ linux-2.6.30.4/arch/x86/include/asm/paravirt.h 2009-07-30 09:48:09.931536832 -0400
5938@@ -1688,7 +1688,7 @@ static inline unsigned long __raw_local_
2380c486 5939
2380c486
JR
5940 #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
5941 #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
5942-#define PARA_INDIRECT(addr) *%cs:addr
5943+#define PARA_INDIRECT(addr) *%ss:addr
5944 #endif
5945
5946 #define INTERRUPT_RETURN \
017d2877
AM
5947diff -urNp linux-2.6.30.4/arch/x86/include/asm/pgalloc.h linux-2.6.30.4/arch/x86/include/asm/pgalloc.h
5948--- linux-2.6.30.4/arch/x86/include/asm/pgalloc.h 2009-07-24 17:47:51.000000000 -0400
5949+++ linux-2.6.30.4/arch/x86/include/asm/pgalloc.h 2009-07-30 09:48:09.931536832 -0400
2380c486
JR
5950@@ -52,7 +52,7 @@ static inline void pmd_populate_kernel(s
5951 pmd_t *pmd, pte_t *pte)
5952 {
5953 paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
5954- set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
5955+ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
5956 }
5957
5958 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
017d2877
AM
5959diff -urNp linux-2.6.30.4/arch/x86/include/asm/pgtable-2level.h linux-2.6.30.4/arch/x86/include/asm/pgtable-2level.h
5960--- linux-2.6.30.4/arch/x86/include/asm/pgtable-2level.h 2009-07-24 17:47:51.000000000 -0400
5961+++ linux-2.6.30.4/arch/x86/include/asm/pgtable-2level.h 2009-07-30 09:48:09.931536832 -0400
2380c486
JR
5962@@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
5963
5964 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
5965 {
5966+
5967+#ifdef CONFIG_PAX_KERNEXEC
5968+ unsigned long cr0;
5969+
5970+ pax_open_kernel(cr0);
5971+#endif
5972+
5973 *pmdp = pmd;
5974+
5975+#ifdef CONFIG_PAX_KERNEXEC
5976+ pax_close_kernel(cr0);
5977+#endif
5978+
5979 }
5980
5981 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
017d2877
AM
5982diff -urNp linux-2.6.30.4/arch/x86/include/asm/pgtable_32.h linux-2.6.30.4/arch/x86/include/asm/pgtable_32.h
5983--- linux-2.6.30.4/arch/x86/include/asm/pgtable_32.h 2009-07-24 17:47:51.000000000 -0400
5984+++ linux-2.6.30.4/arch/x86/include/asm/pgtable_32.h 2009-07-30 09:48:09.932929020 -0400
5985@@ -26,8 +26,6 @@
2380c486
JR
5986 struct mm_struct;
5987 struct vm_area_struct;
5988
5989-extern pgd_t swapper_pg_dir[1024];
5990-
5991 static inline void pgtable_cache_init(void) { }
5992 static inline void check_pgt_cache(void) { }
5993 void paging_init(void);
017d2877
AM
5994@@ -48,6 +46,12 @@ extern void set_pmd_pfn(unsigned long, u
5995 # include <asm/pgtable-2level.h>
2380c486
JR
5996 #endif
5997
5998+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
5999+#ifdef CONFIG_X86_PAE
6000+extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
6001+#endif
017d2877 6002+extern pte_t swapper_pg_fixmap[PTRS_PER_PMD];
2380c486 6003+
017d2877
AM
6004 #if defined(CONFIG_HIGHPTE)
6005 #define pte_offset_map(dir, address) \
6006 ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)), KM_PTE0) + \
6007@@ -80,6 +84,9 @@ do { \
2380c486
JR
6008
6009 #endif /* !__ASSEMBLY__ */
6010
6011+#define HAVE_ARCH_UNMAPPED_AREA
6012+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
6013+
6014 /*
6015 * kern_addr_valid() is (1) for FLATMEM and (0) for
6016 * SPARSEMEM and DISCONTIGMEM
017d2877
AM
6017diff -urNp linux-2.6.30.4/arch/x86/include/asm/pgtable-3level.h linux-2.6.30.4/arch/x86/include/asm/pgtable-3level.h
6018--- linux-2.6.30.4/arch/x86/include/asm/pgtable-3level.h 2009-07-24 17:47:51.000000000 -0400
6019+++ linux-2.6.30.4/arch/x86/include/asm/pgtable-3level.h 2009-07-30 09:48:09.931536832 -0400
6020@@ -38,12 +38,36 @@ static inline void native_set_pte_atomic
2380c486
JR
6021
6022 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
6023 {
6024+
6025+#ifdef CONFIG_PAX_KERNEXEC
6026+ unsigned long cr0;
6027+
6028+ pax_open_kernel(cr0);
6029+#endif
6030+
6031 set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
6032+
6033+#ifdef CONFIG_PAX_KERNEXEC
6034+ pax_close_kernel(cr0);
6035+#endif
6036+
6037 }
6038
6039 static inline void native_set_pud(pud_t *pudp, pud_t pud)
6040 {
6041+
6042+#ifdef CONFIG_PAX_KERNEXEC
6043+ unsigned long cr0;
6044+
6045+ pax_open_kernel(cr0);
6046+#endif
6047+
6048 set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
6049+
6050+#ifdef CONFIG_PAX_KERNEXEC
6051+ pax_close_kernel(cr0);
6052+#endif
6053+
6054 }
6055
6056 /*
017d2877
AM
6057diff -urNp linux-2.6.30.4/arch/x86/include/asm/pgtable_64.h linux-2.6.30.4/arch/x86/include/asm/pgtable_64.h
6058--- linux-2.6.30.4/arch/x86/include/asm/pgtable_64.h 2009-07-24 17:47:51.000000000 -0400
6059+++ linux-2.6.30.4/arch/x86/include/asm/pgtable_64.h 2009-07-30 09:48:09.932929020 -0400
6060@@ -16,9 +16,12 @@
2380c486
JR
6061
6062 extern pud_t level3_kernel_pgt[512];
6063 extern pud_t level3_ident_pgt[512];
6064+extern pud_t level3_vmalloc_pgt[512];
6065+extern pud_t level3_vmemmap_pgt[512];
6066 extern pmd_t level2_kernel_pgt[512];
6067 extern pmd_t level2_fixmap_pgt[512];
6068-extern pmd_t level2_ident_pgt[512];
6069+extern pmd_t level2_ident_pgt[512*4];
6070+extern pte_t level1_fixmap_pgt[512];
6071 extern pgd_t init_level4_pgt[];
6072
6073 #define swapper_pg_dir init_level4_pgt
017d2877 6074@@ -78,7 +81,19 @@ static inline pte_t native_ptep_get_and_
2380c486
JR
6075
6076 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
6077 {
6078+
6079+#ifdef CONFIG_PAX_KERNEXEC
6080+ unsigned long cr0;
6081+
6082+ pax_open_kernel(cr0);
6083+#endif
6084+
6085 *pmdp = pmd;
6086+
6087+#ifdef CONFIG_PAX_KERNEXEC
6088+ pax_close_kernel(cr0);
6089+#endif
6090+
6091 }
6092
6093 static inline void native_pmd_clear(pmd_t *pmd)
017d2877
AM
6094diff -urNp linux-2.6.30.4/arch/x86/include/asm/pgtable.h linux-2.6.30.4/arch/x86/include/asm/pgtable.h
6095--- linux-2.6.30.4/arch/x86/include/asm/pgtable.h 2009-07-24 17:47:51.000000000 -0400
6096+++ linux-2.6.30.4/arch/x86/include/asm/pgtable.h 2009-07-30 09:48:09.932929020 -0400
6097@@ -87,6 +87,11 @@ static inline void __init paravirt_paget
6098 * The following only work if pte_present() is true.
6099 * Undefined behaviour if not..
6100 */
6101+static inline int pte_user(pte_t pte)
6102+{
6103+ return pte_val(pte) & _PAGE_USER;
6104+}
6105+
6106 static inline int pte_dirty(pte_t pte)
6107 {
6108 return pte_flags(pte) & _PAGE_DIRTY;
6109@@ -169,9 +174,29 @@ static inline pte_t pte_wrprotect(pte_t
6110 return pte_clear_flags(pte, _PAGE_RW);
6111 }
2380c486 6112
017d2877
AM
6113+static inline pte_t pte_mkread(pte_t pte)
6114+{
6115+ return __pte(pte_val(pte) | _PAGE_USER);
6116+}
6117+
6118 static inline pte_t pte_mkexec(pte_t pte)
2380c486 6119 {
017d2877
AM
6120- return pte_clear_flags(pte, _PAGE_NX);
6121+#ifdef CONFIG_X86_PAE
6122+ if (__supported_pte_mask & _PAGE_NX)
6123+ return pte_clear_flags(pte, _PAGE_NX);
6124+ else
6125+#endif
6126+ return pte_set_flags(pte, _PAGE_USER);
6127+}
6128+
6129+static inline pte_t pte_exprotect(pte_t pte)
6130+{
6131+#ifdef CONFIG_X86_PAE
6132+ if (__supported_pte_mask & _PAGE_NX)
6133+ return pte_set_flags(pte, _PAGE_NX);
6134+ else
6135+#endif
6136+ return pte_clear_flags(pte, _PAGE_USER);
2380c486
JR
6137 }
6138
017d2877
AM
6139 static inline pte_t pte_mkdirty(pte_t pte)
6140@@ -467,7 +492,7 @@ static inline pud_t *pud_offset(pgd_t *p
6141
6142 static inline int pgd_bad(pgd_t pgd)
2380c486 6143 {
017d2877
AM
6144- return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
6145+ return (pgd_flags(pgd) & ~(_PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
2380c486
JR
6146 }
6147
017d2877
AM
6148 static inline int pgd_none(pgd_t pgd)
6149@@ -606,7 +631,19 @@ static inline void ptep_set_wrprotect(st
6150 */
6151 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
2380c486 6152 {
017d2877
AM
6153- memcpy(dst, src, count * sizeof(pgd_t));
6154+
6155+#ifdef CONFIG_PAX_KERNEXEC
6156+ unsigned long cr0;
6157+
6158+ pax_open_kernel(cr0);
6159+#endif
6160+
6161+ memcpy(dst, src, count * sizeof(pgd_t));
6162+
6163+#ifdef CONFIG_PAX_KERNEXEC
6164+ pax_close_kernel(cr0);
6165+#endif
6166+
2380c486
JR
6167 }
6168
017d2877
AM
6169
6170diff -urNp linux-2.6.30.4/arch/x86/include/asm/pgtable_types.h linux-2.6.30.4/arch/x86/include/asm/pgtable_types.h
6171--- linux-2.6.30.4/arch/x86/include/asm/pgtable_types.h 2009-07-24 17:47:51.000000000 -0400
6172+++ linux-2.6.30.4/arch/x86/include/asm/pgtable_types.h 2009-07-30 19:56:23.227966500 -0400
6173@@ -16,12 +16,11 @@
2380c486
JR
6174 #define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
6175 #define _PAGE_BIT_PAT 7 /* on 4KB pages */
6176 #define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
6177-#define _PAGE_BIT_UNUSED1 9 /* available for programmer */
6178+#define _PAGE_BIT_SPECIAL 9 /* special mappings, no associated struct page */
6179 #define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */
6180 #define _PAGE_BIT_UNUSED3 11
6181 #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
6182-#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1
6183-#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1
6184+#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SPECIAL
6185 #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
6186
6187 /* If _PAGE_BIT_PRESENT is clear, we use these: */
017d2877 6188@@ -39,7 +38,6 @@
2380c486
JR
6189 #define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
6190 #define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
6191 #define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
6192-#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
6193 #define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
6194 #define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
6195 #define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
017d2877 6196@@ -51,7 +49,7 @@
2380c486
JR
6197 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
6198 #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
6199 #else
6200-#define _PAGE_NX (_AT(pteval_t, 0))
6201+#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
6202 #endif
6203
6204 #define _PAGE_FILE (_AT(pteval_t, 1) << _PAGE_BIT_FILE)
017d2877 6205@@ -88,6 +86,9 @@
2380c486
JR
6206 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
6207 _PAGE_ACCESSED)
6208
6209+#define PAGE_READONLY_NOEXEC PAGE_READONLY
6210+#define PAGE_SHARED_NOEXEC PAGE_SHARED
6211+
6212 #define __PAGE_KERNEL_EXEC \
6213 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
6214 #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
017d2877 6215@@ -98,8 +99,8 @@
de855c5d 6216 #define __PAGE_KERNEL_WC (__PAGE_KERNEL | _PAGE_CACHE_WC)
2380c486
JR
6217 #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
6218 #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
017d2877
AM
6219-#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
6220-#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
de855c5d 6221+#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RO | _PAGE_USER)
2380c486
JR
6222+#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
6223 #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
6224 #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
6225 #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
017d2877 6226@@ -158,8 +159,8 @@
2380c486
JR
6227 * bits are combined, this will alow user to access the high address mapped
6228 * VDSO in the presence of CONFIG_COMPAT_VDSO
6229 */
6230-#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
017d2877 6231-#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
2380c486 6232+#define PTE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
017d2877 6233+#define PDE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
2380c486
JR
6234 #define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
6235 #endif
2380c486 6236
017d2877
AM
6237@@ -272,7 +273,11 @@ static inline pteval_t pte_flags(pte_t p
6238 typedef struct page *pgtable_t;
2380c486 6239
017d2877
AM
6240 extern pteval_t __supported_pte_mask;
6241+#ifdef CONFIG_X86_32
6242 extern int nx_enabled;
6243+#else
6244+#define nx_enabled (1)
2380c486 6245+#endif
017d2877 6246 extern void set_nx(void);
2380c486 6247
017d2877
AM
6248 #define pgprot_writecombine pgprot_writecombine
6249diff -urNp linux-2.6.30.4/arch/x86/include/asm/processor.h linux-2.6.30.4/arch/x86/include/asm/processor.h
6250--- linux-2.6.30.4/arch/x86/include/asm/processor.h 2009-07-24 17:47:51.000000000 -0400
6251+++ linux-2.6.30.4/arch/x86/include/asm/processor.h 2009-07-30 09:48:09.933533479 -0400
6252@@ -270,7 +270,7 @@ struct tss_struct {
2380c486
JR
6253
6254 } ____cacheline_aligned;
6255
017d2877 6256-DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss);
2380c486
JR
6257+extern struct tss_struct init_tss[NR_CPUS];
6258
6259 /*
6260 * Save the original ist values for checking stack pointers during debugging
017d2877 6261@@ -866,8 +866,17 @@ static inline void spin_lock_prefetch(co
2380c486
JR
6262 */
6263 #define TASK_SIZE PAGE_OFFSET
017d2877 6264 #define TASK_SIZE_MAX TASK_SIZE
2380c486
JR
6265+
6266+#ifdef CONFIG_PAX_SEGMEXEC
6267+#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
6268+#endif
6269+
6270+#ifdef CONFIG_PAX_SEGMEXEC
6271+#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
6272+#else
6273 #define STACK_TOP TASK_SIZE
6274-#define STACK_TOP_MAX STACK_TOP
6275+#endif
6276+#define STACK_TOP_MAX TASK_SIZE
6277
6278 #define INIT_THREAD { \
017d2877
AM
6279 .sp0 = sizeof(init_stack) + (long)&init_stack, \
6280@@ -885,7 +894,7 @@ static inline void spin_lock_prefetch(co
2380c486
JR
6281 */
6282 #define INIT_TSS { \
6283 .x86_tss = { \
6284- .sp0 = sizeof(init_stack) + (long)&init_stack, \
6285+ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
6286 .ss0 = __KERNEL_DS, \
6287 .ss1 = __KERNEL_CS, \
6288 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
017d2877 6289@@ -896,11 +905,7 @@ static inline void spin_lock_prefetch(co
2380c486
JR
6290 extern unsigned long thread_saved_pc(struct task_struct *tsk);
6291
6292 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
6293-#define KSTK_TOP(info) \
6294-({ \
6295- unsigned long *__ptr = (unsigned long *)(info); \
6296- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
6297-})
6298+#define KSTK_TOP(info) ((info)->task.thread.sp0)
6299
6300 /*
6301 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
017d2877 6302@@ -915,7 +920,7 @@ extern unsigned long thread_saved_pc(str
2380c486
JR
6303 #define task_pt_regs(task) \
6304 ({ \
6305 struct pt_regs *__regs__; \
6306- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
6307+ __regs__ = (struct pt_regs *)((task)->thread.sp0); \
6308 __regs__ - 1; \
6309 })
6310
017d2877 6311@@ -931,7 +936,7 @@ extern unsigned long thread_saved_pc(str
2380c486
JR
6312 * space during mmap's.
6313 */
6314 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
6315- 0xc0000000 : 0xFFFFe000)
6316+ 0xc0000000 : 0xFFFFf000)
6317
6318 #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
017d2877
AM
6319 IA32_PAGE_OFFSET : TASK_SIZE_MAX)
6320@@ -968,6 +973,10 @@ extern void start_thread(struct pt_regs
2380c486
JR
6321 */
6322 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
6323
6324+#ifdef CONFIG_PAX_SEGMEXEC
6325+#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
6326+#endif
6327+
6328 #define KSTK_EIP(task) (task_pt_regs(task)->ip)
6329
6330 /* Get/set a process' ability to use the timestamp counter instruction */
017d2877
AM
6331diff -urNp linux-2.6.30.4/arch/x86/include/asm/ptrace.h linux-2.6.30.4/arch/x86/include/asm/ptrace.h
6332--- linux-2.6.30.4/arch/x86/include/asm/ptrace.h 2009-07-24 17:47:51.000000000 -0400
6333+++ linux-2.6.30.4/arch/x86/include/asm/ptrace.h 2009-07-30 09:48:09.933533479 -0400
2380c486
JR
6334@@ -151,28 +151,29 @@ static inline unsigned long regs_return_
6335 }
6336
6337 /*
6338- * user_mode_vm(regs) determines whether a register set came from user mode.
6339+ * user_mode(regs) determines whether a register set came from user mode.
6340 * This is true if V8086 mode was enabled OR if the register set was from
6341 * protected mode with RPL-3 CS value. This tricky test checks that with
6342 * one comparison. Many places in the kernel can bypass this full check
6343- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
6344+ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
6345+ * be used.
6346 */
6347-static inline int user_mode(struct pt_regs *regs)
6348+static inline int user_mode_novm(struct pt_regs *regs)
6349 {
6350 #ifdef CONFIG_X86_32
6351 return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
6352 #else
6353- return !!(regs->cs & 3);
6354+ return !!(regs->cs & SEGMENT_RPL_MASK);
6355 #endif
6356 }
6357
6358-static inline int user_mode_vm(struct pt_regs *regs)
6359+static inline int user_mode(struct pt_regs *regs)
6360 {
6361 #ifdef CONFIG_X86_32
6362 return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
6363 USER_RPL;
6364 #else
6365- return user_mode(regs);
6366+ return user_mode_novm(regs);
6367 #endif
6368 }
6369
017d2877
AM
6370diff -urNp linux-2.6.30.4/arch/x86/include/asm/reboot.h linux-2.6.30.4/arch/x86/include/asm/reboot.h
6371--- linux-2.6.30.4/arch/x86/include/asm/reboot.h 2009-07-24 17:47:51.000000000 -0400
6372+++ linux-2.6.30.4/arch/x86/include/asm/reboot.h 2009-07-30 09:48:09.933533479 -0400
2380c486
JR
6373@@ -18,7 +18,7 @@ extern struct machine_ops machine_ops;
6374
6375 void native_machine_crash_shutdown(struct pt_regs *regs);
6376 void native_machine_shutdown(void);
6377-void machine_real_restart(const unsigned char *code, int length);
6378+void machine_real_restart(const unsigned char *code, unsigned int length);
6379
6380 typedef void (*nmi_shootdown_cb)(int, struct die_args*);
6381 void nmi_shootdown_cpus(nmi_shootdown_cb callback);
017d2877
AM
6382diff -urNp linux-2.6.30.4/arch/x86/include/asm/rwsem.h linux-2.6.30.4/arch/x86/include/asm/rwsem.h
6383--- linux-2.6.30.4/arch/x86/include/asm/rwsem.h 2009-07-24 17:47:51.000000000 -0400
6384+++ linux-2.6.30.4/arch/x86/include/asm/rwsem.h 2009-07-30 09:48:09.934667198 -0400
2380c486
JR
6385@@ -106,10 +106,26 @@ static inline void __down_read(struct rw
6386 {
6387 asm volatile("# beginning down_read\n\t"
6388 LOCK_PREFIX " incl (%%eax)\n\t"
6389+
6390+#ifdef CONFIG_PAX_REFCOUNT
6391+#ifdef CONFIG_X86_32
6392+ "into\n0:\n"
6393+#else
6394+ "jno 0f\n"
6395+ "int $4\n0:\n"
6396+#endif
6397+ ".pushsection .fixup,\"ax\"\n"
6398+ "1:\n"
6399+ LOCK_PREFIX "decl (%%eax)\n"
6400+ "jmp 0b\n"
6401+ ".popsection\n"
6402+ _ASM_EXTABLE(0b, 1b)
6403+#endif
6404+
6405 /* adds 0x00000001, returns the old value */
6406- " jns 1f\n"
6407+ " jns 2f\n"
6408 " call call_rwsem_down_read_failed\n"
6409- "1:\n\t"
6410+ "2:\n\t"
6411 "# ending down_read\n\t"
6412 : "+m" (sem->count)
6413 : "a" (sem)
6414@@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
6415 __s32 result, tmp;
6416 asm volatile("# beginning __down_read_trylock\n\t"
6417 " movl %0,%1\n\t"
6418- "1:\n\t"
6419+ "2:\n\t"
6420 " movl %1,%2\n\t"
6421 " addl %3,%2\n\t"
6422- " jle 2f\n\t"
6423+
6424+#ifdef CONFIG_PAX_REFCOUNT
6425+#ifdef CONFIG_X86_32
6426+ "into\n0:\n"
6427+#else
6428+ "jno 0f\n"
6429+ "int $4\n0:\n"
6430+#endif
6431+ ".pushsection .fixup,\"ax\"\n"
6432+ "1:\n"
6433+ "subl %3,%2\n"
6434+ "jmp 0b\n"
6435+ ".popsection\n"
6436+ _ASM_EXTABLE(0b, 1b)
6437+#endif
6438+
6439+ " jle 3f\n\t"
6440 LOCK_PREFIX " cmpxchgl %2,%0\n\t"
6441- " jnz 1b\n\t"
6442- "2:\n\t"
6443+ " jnz 2b\n\t"
6444+ "3:\n\t"
6445 "# ending __down_read_trylock\n\t"
6446 : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
6447 : "i" (RWSEM_ACTIVE_READ_BIAS)
6448@@ -148,12 +180,28 @@ static inline void __down_write_nested(s
6449 tmp = RWSEM_ACTIVE_WRITE_BIAS;
6450 asm volatile("# beginning down_write\n\t"
6451 LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
6452+
6453+#ifdef CONFIG_PAX_REFCOUNT
6454+#ifdef CONFIG_X86_32
6455+ "into\n0:\n"
6456+#else
6457+ "jno 0f\n"
6458+ "int $4\n0:\n"
6459+#endif
6460+ ".pushsection .fixup,\"ax\"\n"
6461+ "1:\n"
6462+ "movl %%edx,(%%eax)\n"
6463+ "jmp 0b\n"
6464+ ".popsection\n"
6465+ _ASM_EXTABLE(0b, 1b)
6466+#endif
6467+
6468 /* subtract 0x0000ffff, returns the old value */
6469 " testl %%edx,%%edx\n\t"
6470 /* was the count 0 before? */
6471- " jz 1f\n"
6472+ " jz 2f\n"
6473 " call call_rwsem_down_write_failed\n"
6474- "1:\n"
6475+ "2:\n"
6476 "# ending down_write"
6477 : "+m" (sem->count), "=d" (tmp)
6478 : "a" (sem), "1" (tmp)
6479@@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
6480 __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
6481 asm volatile("# beginning __up_read\n\t"
6482 LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
6483+
6484+#ifdef CONFIG_PAX_REFCOUNT
6485+#ifdef CONFIG_X86_32
6486+ "into\n0:\n"
6487+#else
6488+ "jno 0f\n"
6489+ "int $4\n0:\n"
6490+#endif
6491+ ".pushsection .fixup,\"ax\"\n"
6492+ "1:\n"
6493+ "movl %%edx,(%%eax)\n"
6494+ "jmp 0b\n"
6495+ ".popsection\n"
6496+ _ASM_EXTABLE(0b, 1b)
6497+#endif
6498+
6499 /* subtracts 1, returns the old value */
6500- " jns 1f\n\t"
6501+ " jns 2f\n\t"
6502 " call call_rwsem_wake\n"
6503- "1:\n"
6504+ "2:\n"
6505 "# ending __up_read\n"
6506 : "+m" (sem->count), "=d" (tmp)
6507 : "a" (sem), "1" (tmp)
6508@@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
6509 asm volatile("# beginning __up_write\n\t"
6510 " movl %2,%%edx\n\t"
6511 LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t"
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+ "movl %%edx,(%%eax)\n"
6523+ "jmp 0b\n"
6524+ ".popsection\n"
6525+ _ASM_EXTABLE(0b, 1b)
6526+#endif
6527+
6528 /* tries to transition
6529 0xffff0001 -> 0x00000000 */
6530- " jz 1f\n"
6531+ " jz 2f\n"
6532 " call call_rwsem_wake\n"
6533- "1:\n\t"
6534+ "2:\n\t"
6535 "# ending __up_write\n"
6536 : "+m" (sem->count)
6537 : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
6538@@ -222,10 +302,26 @@ static inline void __downgrade_write(str
6539 {
6540 asm volatile("# beginning __downgrade_write\n\t"
6541 LOCK_PREFIX " addl %2,(%%eax)\n\t"
6542+
6543+#ifdef CONFIG_PAX_REFCOUNT
6544+#ifdef CONFIG_X86_32
6545+ "into\n0:\n"
6546+#else
6547+ "jno 0f\n"
6548+ "int $4\n0:\n"
6549+#endif
6550+ ".pushsection .fixup,\"ax\"\n"
6551+ "1:\n"
6552+ LOCK_PREFIX "subl %2,(%%eax)\n"
6553+ "jmp 0b\n"
6554+ ".popsection\n"
6555+ _ASM_EXTABLE(0b, 1b)
6556+#endif
6557+
6558 /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
6559- " jns 1f\n\t"
6560+ " jns 2f\n\t"
6561 " call call_rwsem_downgrade_wake\n"
6562- "1:\n\t"
6563+ "2:\n\t"
6564 "# ending __downgrade_write\n"
6565 : "+m" (sem->count)
6566 : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
6567@@ -237,7 +333,23 @@ static inline void __downgrade_write(str
6568 */
6569 static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
6570 {
6571- asm volatile(LOCK_PREFIX "addl %1,%0"
6572+ asm volatile(LOCK_PREFIX "addl %1,%0\n"
6573+
6574+#ifdef CONFIG_PAX_REFCOUNT
6575+#ifdef CONFIG_X86_32
6576+ "into\n0:\n"
6577+#else
6578+ "jno 0f\n"
6579+ "int $4\n0:\n"
6580+#endif
6581+ ".pushsection .fixup,\"ax\"\n"
6582+ "1:\n"
6583+ LOCK_PREFIX "subl %1,%0\n"
6584+ "jmp 0b\n"
6585+ ".popsection\n"
6586+ _ASM_EXTABLE(0b, 1b)
6587+#endif
6588+
6589 : "+m" (sem->count)
6590 : "ir" (delta));
6591 }
6592@@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
6593 {
6594 int tmp = delta;
6595
6596- asm volatile(LOCK_PREFIX "xadd %0,%1"
6597+ asm volatile(LOCK_PREFIX "xadd %0,%1\n"
6598+
6599+#ifdef CONFIG_PAX_REFCOUNT
6600+#ifdef CONFIG_X86_32
6601+ "into\n0:\n"
6602+#else
6603+ "jno 0f\n"
6604+ "int $4\n0:\n"
6605+#endif
6606+ ".pushsection .fixup,\"ax\"\n"
6607+ "1:\n"
6608+ "movl %0,%1\n"
6609+ "jmp 0b\n"
6610+ ".popsection\n"
6611+ _ASM_EXTABLE(0b, 1b)
6612+#endif
6613+
6614 : "+r" (tmp), "+m" (sem->count)
6615 : : "memory");
6616
017d2877
AM
6617diff -urNp linux-2.6.30.4/arch/x86/include/asm/segment.h linux-2.6.30.4/arch/x86/include/asm/segment.h
6618--- linux-2.6.30.4/arch/x86/include/asm/segment.h 2009-07-24 17:47:51.000000000 -0400
6619+++ linux-2.6.30.4/arch/x86/include/asm/segment.h 2009-07-30 09:48:09.934667198 -0400
6620@@ -88,7 +88,7 @@
2380c486
JR
6621 #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
6622 #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
6623
6624-#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
6625+#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
6626 #ifdef CONFIG_SMP
6627 #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
6628 #else
017d2877
AM
6629@@ -102,6 +102,12 @@
6630 #define __KERNEL_STACK_CANARY 0
2380c486
JR
6631 #endif
6632
017d2877 6633+#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 17)
2380c486
JR
6634+#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
6635+
017d2877 6636+#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 18)
2380c486
JR
6637+#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
6638+
6639 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
6640
6641 /*
017d2877 6642@@ -139,7 +145,7 @@
2380c486
JR
6643 */
6644
6645 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
6646-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
6647+#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
6648
6649
6650 #else
017d2877
AM
6651diff -urNp linux-2.6.30.4/arch/x86/include/asm/spinlock.h linux-2.6.30.4/arch/x86/include/asm/spinlock.h
6652--- linux-2.6.30.4/arch/x86/include/asm/spinlock.h 2009-07-24 17:47:51.000000000 -0400
6653+++ linux-2.6.30.4/arch/x86/include/asm/spinlock.h 2009-07-30 09:48:09.934667198 -0400
6654@@ -249,18 +249,50 @@ static inline int __raw_write_can_lock(r
2380c486
JR
6655 static inline void __raw_read_lock(raw_rwlock_t *rw)
6656 {
6657 asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
6658- "jns 1f\n"
6659- "call __read_lock_failed\n\t"
6660+
6661+#ifdef CONFIG_PAX_REFCOUNT
6662+#ifdef CONFIG_X86_32
6663+ "into\n0:\n"
6664+#else
6665+ "jno 0f\n"
6666+ "int $4\n0:\n"
6667+#endif
6668+ ".pushsection .fixup,\"ax\"\n"
6669 "1:\n"
6670+ LOCK_PREFIX " addl $1,(%0)\n"
6671+ "jmp 0b\n"
6672+ ".popsection\n"
6673+ _ASM_EXTABLE(0b, 1b)
6674+#endif
6675+
6676+ "jns 2f\n"
6677+ "call __read_lock_failed\n\t"
6678+ "2:\n"
6679 ::LOCK_PTR_REG (rw) : "memory");
6680 }
6681
6682 static inline void __raw_write_lock(raw_rwlock_t *rw)
6683 {
6684 asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
6685- "jz 1f\n"
6686- "call __write_lock_failed\n\t"
6687+
6688+#ifdef CONFIG_PAX_REFCOUNT
6689+#ifdef CONFIG_X86_32
6690+ "into\n0:\n"
6691+#else
6692+ "jno 0f\n"
6693+ "int $4\n0:\n"
6694+#endif
6695+ ".pushsection .fixup,\"ax\"\n"
6696 "1:\n"
6697+ LOCK_PREFIX " addl %1,(%0)\n"
6698+ "jmp 0b\n"
6699+ ".popsection\n"
6700+ _ASM_EXTABLE(0b, 1b)
6701+#endif
6702+
6703+ "jz 2f\n"
6704+ "call __write_lock_failed\n\t"
6705+ "2:\n"
6706 ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
6707 }
6708
017d2877 6709@@ -286,12 +318,45 @@ static inline int __raw_write_trylock(ra
2380c486
JR
6710
6711 static inline void __raw_read_unlock(raw_rwlock_t *rw)
6712 {
6713- asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
6714+ asm volatile(LOCK_PREFIX "incl %0\n"
6715+
6716+#ifdef CONFIG_PAX_REFCOUNT
6717+#ifdef CONFIG_X86_32
6718+ "into\n0:\n"
6719+#else
6720+ "jno 0f\n"
6721+ "int $4\n0:\n"
6722+#endif
6723+ ".pushsection .fixup,\"ax\"\n"
6724+ "1:\n"
6725+ LOCK_PREFIX "decl %0\n"
6726+ "jmp 0b\n"
6727+ ".popsection\n"
6728+ _ASM_EXTABLE(0b, 1b)
6729+#endif
6730+
6731+ :"+m" (rw->lock) : : "memory");
6732 }
6733
6734 static inline void __raw_write_unlock(raw_rwlock_t *rw)
6735 {
6736- asm volatile(LOCK_PREFIX "addl %1, %0"
6737+ asm volatile(LOCK_PREFIX "addl %1, %0\n"
6738+
6739+#ifdef CONFIG_PAX_REFCOUNT
6740+#ifdef CONFIG_X86_32
6741+ "into\n0:\n"
6742+#else
6743+ "jno 0f\n"
6744+ "int $4\n0:\n"
6745+#endif
6746+ ".pushsection .fixup,\"ax\"\n"
6747+ "1:\n"
6748+ LOCK_PREFIX "subl %1,%0\n"
6749+ "jmp 0b\n"
6750+ ".popsection\n"
6751+ _ASM_EXTABLE(0b, 1b)
6752+#endif
6753+
6754 : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
6755 }
6756
017d2877
AM
6757diff -urNp linux-2.6.30.4/arch/x86/include/asm/system.h linux-2.6.30.4/arch/x86/include/asm/system.h
6758--- linux-2.6.30.4/arch/x86/include/asm/system.h 2009-07-24 17:47:51.000000000 -0400
6759+++ linux-2.6.30.4/arch/x86/include/asm/system.h 2009-07-30 09:48:09.935636803 -0400
6760@@ -227,7 +227,7 @@ static inline unsigned long get_limit(un
2380c486
JR
6761 {
6762 unsigned long __limit;
6763 asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
6764- return __limit + 1;
6765+ return __limit;
6766 }
6767
6768 static inline void native_clts(void)
017d2877 6769@@ -353,6 +353,23 @@ static inline void native_wbinvd(void)
2380c486
JR
6770
6771 #define stts() write_cr0(read_cr0() | X86_CR0_TS)
6772
6773+#define pax_open_kernel(cr0) \
6774+do { \
6775+ typecheck(unsigned long, cr0); \
6776+ preempt_disable(); \
017d2877 6777+ barrier(); \
2380c486
JR
6778+ cr0 = read_cr0(); \
6779+ write_cr0(cr0 & ~X86_CR0_WP); \
6780+} while (0)
6781+
6782+#define pax_close_kernel(cr0) \
6783+do { \
6784+ typecheck(unsigned long, cr0); \
6785+ write_cr0(cr0); \
017d2877 6786+ barrier(); \
2380c486
JR
6787+ preempt_enable_no_resched(); \
6788+} while (0)
6789+
6790 #endif /* __KERNEL__ */
6791
6792 static inline void clflush(volatile void *__p)
017d2877 6793@@ -367,7 +384,7 @@ void enable_hlt(void);
2380c486
JR
6794
6795 void cpu_idle_wait(void);
6796
6797-extern unsigned long arch_align_stack(unsigned long sp);
6798+#define arch_align_stack(x) ((x) & ~0xfUL)
6799 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
6800
6801 void default_idle(void);
017d2877
AM
6802diff -urNp linux-2.6.30.4/arch/x86/include/asm/uaccess_32.h linux-2.6.30.4/arch/x86/include/asm/uaccess_32.h
6803--- linux-2.6.30.4/arch/x86/include/asm/uaccess_32.h 2009-07-24 17:47:51.000000000 -0400
6804+++ linux-2.6.30.4/arch/x86/include/asm/uaccess_32.h 2009-07-30 09:48:09.936413079 -0400
6805@@ -44,6 +44,9 @@ unsigned long __must_check __copy_from_u
6806 static __always_inline unsigned long __must_check
6807 __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
6808 {
6809+ if ((long)n < 0)
6810+ return n;
6811+
6812 if (__builtin_constant_p(n)) {
6813 unsigned long ret;
6814
6815@@ -62,6 +65,8 @@ __copy_to_user_inatomic(void __user *to,
de855c5d
AM
6816 return ret;
6817 }
6818 }
6819+ if (!__builtin_constant_p(n))
6820+ check_object_size(from, n, true);
6821 return __copy_to_user_ll(to, from, n);
6822 }
6823
017d2877
AM
6824@@ -89,6 +94,9 @@ __copy_to_user(void __user *to, const vo
6825 static __always_inline unsigned long
6826 __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
6827 {
6828+ if ((long)n < 0)
6829+ return n;
6830+
6831 /* Avoid zeroing the tail if the copy fails..
6832 * If 'n' is constant and 1, 2, or 4, we do still zero on a failure,
6833 * but as the zeroing behaviour is only significant when n is not
6834@@ -138,6 +146,10 @@ static __always_inline unsigned long
6835 __copy_from_user(void *to, const void __user *from, unsigned long n)
6836 {
6837 might_fault();
6838+
6839+ if ((long)n < 0)
6840+ return n;
6841+
6842 if (__builtin_constant_p(n)) {
6843 unsigned long ret;
6844
6845@@ -153,6 +165,8 @@ __copy_from_user(void *to, const void __
de855c5d
AM
6846 return ret;
6847 }
6848 }
6849+ if (!__builtin_constant_p(n))
6850+ check_object_size(to, n, false);
6851 return __copy_from_user_ll(to, from, n);
6852 }
6853
017d2877
AM
6854@@ -160,6 +174,10 @@ static __always_inline unsigned long __c
6855 const void __user *from, unsigned long n)
6856 {
6857 might_fault();
6858+
6859+ if ((long)n < 0)
6860+ return n;
6861+
6862 if (__builtin_constant_p(n)) {
6863 unsigned long ret;
de855c5d 6864
017d2877
AM
6865@@ -182,14 +200,62 @@ static __always_inline unsigned long
6866 __copy_from_user_inatomic_nocache(void *to, const void __user *from,
6867 unsigned long n)
6868 {
6869- return __copy_from_user_ll_nocache_nozero(to, from, n);
6870+ if ((long)n < 0)
6871+ return n;
6872+
6873+ return __copy_from_user_ll_nocache_nozero(to, from, n);
6874+}
6875+
de855c5d
AM
6876+/**
6877+ * copy_to_user: - Copy a block of data into user space.
6878+ * @to: Destination address, in user space.
6879+ * @from: Source address, in kernel space.
6880+ * @n: Number of bytes to copy.
6881+ *
6882+ * Context: User context only. This function may sleep.
6883+ *
6884+ * Copy data from kernel space to user space.
6885+ *
6886+ * Returns number of bytes that could not be copied.
6887+ * On success, this will be zero.
6888+ */
6889+static __always_inline unsigned long __must_check
6890+copy_to_user(void __user *to, const void *from, unsigned long n)
6891+{
6892+ if (access_ok(VERIFY_WRITE, to, n))
6893+ n = __copy_to_user(to, from, n);
6894+ return n;
6895+}
6896+
6897+/**
6898+ * copy_from_user: - Copy a block of data from user space.
6899+ * @to: Destination address, in kernel space.
6900+ * @from: Source address, in user space.
6901+ * @n: Number of bytes to copy.
6902+ *
6903+ * Context: User context only. This function may sleep.
6904+ *
6905+ * Copy data from user space to kernel space.
6906+ *
6907+ * Returns number of bytes that could not be copied.
6908+ * On success, this will be zero.
6909+ *
6910+ * If some data could not be copied, this function will pad the copied
6911+ * data to the requested size using zero bytes.
6912+ */
6913+static __always_inline unsigned long __must_check
6914+copy_from_user(void *to, const void __user *from, unsigned long n)
6915+{
6916+ if (access_ok(VERIFY_READ, from, n))
6917+ n = __copy_from_user(to, from, n);
6918+ else if ((long)n > 0) {
6919+ if (!__builtin_constant_p(n))
6920+ check_object_size(to, n, false);
6921+ memset(to, 0, n);
6922+ }
6923+ return n;
017d2877
AM
6924 }
6925
6926-unsigned long __must_check copy_to_user(void __user *to,
6927- const void *from, unsigned long n);
6928-unsigned long __must_check copy_from_user(void *to,
6929- const void __user *from,
6930- unsigned long n);
de855c5d
AM
6931 long __must_check strncpy_from_user(char *dst, const char __user *src,
6932 long count);
6933 long __must_check __strncpy_from_user(char *dst,
017d2877
AM
6934diff -urNp linux-2.6.30.4/arch/x86/include/asm/uaccess_64.h linux-2.6.30.4/arch/x86/include/asm/uaccess_64.h
6935--- linux-2.6.30.4/arch/x86/include/asm/uaccess_64.h 2009-07-30 20:32:40.365617606 -0400
6936+++ linux-2.6.30.4/arch/x86/include/asm/uaccess_64.h 2009-07-30 20:32:47.927601167 -0400
2380c486
JR
6937@@ -10,6 +10,8 @@
6938 #include <linux/lockdep.h>
6939 #include <asm/page.h>
6940
6941+#define set_fs(x) (current_thread_info()->addr_limit = (x))
6942+
6943 /*
6944 * Copy To/From Userspace
6945 */
017d2877 6946@@ -19,20 +21,22 @@ __must_check unsigned long
de855c5d
AM
6947 copy_user_generic(void *to, const void *from, unsigned len);
6948
6949 __must_check unsigned long
6950-copy_to_user(void __user *to, const void *from, unsigned len);
6951-__must_check unsigned long
6952-copy_from_user(void *to, const void __user *from, unsigned len);
6953-__must_check unsigned long
6954 copy_in_user(void __user *to, const void __user *from, unsigned len);
6955
6956 static __always_inline __must_check
6957-int __copy_from_user(void *dst, const void __user *src, unsigned size)
6958+unsigned long __copy_from_user(void *dst, const void __user *src, unsigned size)
6959 {
6960- int ret = 0;
6961+ unsigned ret = 0;
6962
6963 might_fault();
6964- if (!__builtin_constant_p(size))
017d2877
AM
6965+
6966+ if ((int)size < 0)
6967+ return size;
6968+
de855c5d
AM
6969+ if (!__builtin_constant_p(size)) {
6970+ check_object_size(dst, size, false);
6971 return copy_user_generic(dst, (__force void *)src, size);
6972+ }
6973 switch (size) {
6974 case 1:__get_user_asm(*(u8 *)dst, (u8 __user *)src,
6975 ret, "b", "b", "=q", 1);
017d2877 6976@@ -70,13 +74,19 @@ int __copy_from_user(void *dst, const vo
de855c5d
AM
6977 }
6978
6979 static __always_inline __must_check
6980-int __copy_to_user(void __user *dst, const void *src, unsigned size)
6981+unsigned long __copy_to_user(void __user *dst, const void *src, unsigned size)
6982 {
6983- int ret = 0;
6984+ unsigned ret = 0;
6985
6986 might_fault();
6987- if (!__builtin_constant_p(size))
017d2877
AM
6988+
6989+ if ((int)size < 0)
6990+ return size;
6991+
de855c5d
AM
6992+ if (!__builtin_constant_p(size)) {
6993+ check_object_size(src, size, true);
6994 return copy_user_generic((__force void *)dst, src, size);
6995+ }
6996 switch (size) {
6997 case 1:__put_user_asm(*(u8 *)src, (u8 __user *)dst,
6998 ret, "b", "b", "iq", 1);
017d2877 6999@@ -114,11 +124,39 @@ int __copy_to_user(void __user *dst, con
de855c5d
AM
7000 }
7001
7002 static __always_inline __must_check
7003-int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
7004+unsigned long copy_to_user(void __user *to, const void *from, unsigned len)
017d2877
AM
7005 {
7006- int ret = 0;
de855c5d
AM
7007+ if (access_ok(VERIFY_WRITE, to, len))
7008+ len = __copy_to_user(to, from, len);
7009+ return len;
7010+}
7011+
7012+static __always_inline __must_check
7013+unsigned long copy_from_user(void *to, const void __user *from, unsigned len)
7014+{
017d2877
AM
7015+ if ((int)len < 0)
7016+ return len;
7017+
de855c5d
AM
7018+ if (access_ok(VERIFY_READ, from, len))
7019+ len = __copy_from_user(to, from, len);
7020+ else if ((int)len > 0) {
7021+ if (!__builtin_constant_p(len))
7022+ check_object_size(to, len, false);
7023+ memset(to, 0, len);
7024+ }
7025+ return len;
7026+}
7027+
7028+static __always_inline __must_check
7029+unsigned long __copy_in_user(void __user *dst, const void __user *src, unsigned size)
017d2877 7030+{
de855c5d
AM
7031+ unsigned ret = 0;
7032
7033 might_fault();
017d2877
AM
7034+
7035+ if ((int)size < 0)
7036+ return size;
7037+
de855c5d 7038 if (!__builtin_constant_p(size))
017d2877
AM
7039 return copy_user_generic((__force void *)dst,
7040 (__force void *)src, size);
7041@@ -179,30 +217,38 @@ __must_check unsigned long __clear_user(
de855c5d
AM
7042 __must_check long __copy_from_user_inatomic(void *dst, const void __user *src,
7043 unsigned size);
7044
7045-static __must_check __always_inline int
7046+static __must_check __always_inline unsigned long
7047 __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size)
7048 {
017d2877
AM
7049+ if ((int)size < 0)
7050+ return size;
7051+
de855c5d
AM
7052 return copy_user_generic((__force void *)dst, src, size);
7053 }
7054
7055-extern long __copy_user_nocache(void *dst, const void __user *src,
7056+extern unsigned long __copy_user_nocache(void *dst, const void __user *src,
7057 unsigned size, int zerorest);
7058
017d2877
AM
7059-static inline int
7060-__copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
7061+static inline unsigned long __copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
de855c5d
AM
7062 {
7063 might_sleep();
017d2877
AM
7064+
7065+ if ((int)size < 0)
7066+ return size;
7067+
de855c5d
AM
7068 return __copy_user_nocache(dst, src, size, 1);
7069 }
7070
017d2877
AM
7071-static inline int
7072-__copy_from_user_inatomic_nocache(void *dst, const void __user *src,
7073+static inline unsigned long __copy_from_user_inatomic_nocache(void *dst, const void __user *src,
7074 unsigned size)
de855c5d 7075 {
017d2877
AM
7076+ if ((int)size < 0)
7077+ return size;
7078+
de855c5d
AM
7079 return __copy_user_nocache(dst, src, size, 0);
7080 }
7081
7082-unsigned long
7083+extern unsigned long
7084 copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest);
7085
7086 #endif /* _ASM_X86_UACCESS_64_H */
017d2877
AM
7087diff -urNp linux-2.6.30.4/arch/x86/include/asm/uaccess.h linux-2.6.30.4/arch/x86/include/asm/uaccess.h
7088--- linux-2.6.30.4/arch/x86/include/asm/uaccess.h 2009-07-30 20:32:40.364705510 -0400
7089+++ linux-2.6.30.4/arch/x86/include/asm/uaccess.h 2009-07-30 20:32:47.926577259 -0400
de855c5d
AM
7090@@ -8,8 +8,10 @@
7091 #include <linux/thread_info.h>
7092 #include <linux/prefetch.h>
2380c486 7093 #include <linux/string.h>
de855c5d 7094+#include <linux/slab.h>
2380c486
JR
7095 #include <asm/asm.h>
7096 #include <asm/page.h>
7097+#include <asm/segment.h>
7098
7099 #define VERIFY_READ 0
7100 #define VERIFY_WRITE 1
de855c5d 7101@@ -29,7 +31,12 @@
2380c486
JR
7102
7103 #define get_ds() (KERNEL_DS)
7104 #define get_fs() (current_thread_info()->addr_limit)
7105+#ifdef CONFIG_X86_32
7106+void __set_fs(mm_segment_t x, int cpu);
7107+void set_fs(mm_segment_t x);
7108+#else
7109 #define set_fs(x) (current_thread_info()->addr_limit = (x))
7110+#endif
7111
7112 #define segment_eq(a, b) ((a).seg == (b).seg)
7113
de855c5d 7114@@ -187,9 +194,12 @@ extern int __get_user_bad(void);
2380c486
JR
7115
7116 #ifdef CONFIG_X86_32
017d2877 7117 #define __put_user_asm_u64(x, addr, err, errret) \
2380c486
JR
7118- asm volatile("1: movl %%eax,0(%2)\n" \
7119- "2: movl %%edx,4(%2)\n" \
7120+ asm volatile(" movw %w5,%%ds\n" \
7121+ "1: movl %%eax,%%ds:0(%2)\n" \
7122+ "2: movl %%edx,%%ds:4(%2)\n" \
7123 "3:\n" \
7124+ " pushl %%ss\n" \
7125+ " popl %%ds\n" \
7126 ".section .fixup,\"ax\"\n" \
7127 "4: movl %3,%0\n" \
7128 " jmp 3b\n" \
de855c5d 7129@@ -197,7 +207,8 @@ extern int __get_user_bad(void);
2380c486
JR
7130 _ASM_EXTABLE(1b, 4b) \
7131 _ASM_EXTABLE(2b, 4b) \
7132 : "=r" (err) \
017d2877
AM
7133- : "A" (x), "r" (addr), "i" (errret), "0" (err))
7134+ : "A" (x), "r" (addr), "i" (errret), "0" (err), \
2380c486
JR
7135+ "r"(__USER_DS))
7136
017d2877
AM
7137 #define __put_user_asm_ex_u64(x, addr) \
7138 asm volatile("1: movl %%eax,0(%1)\n" \
7139@@ -373,6 +384,22 @@ do { \
2380c486
JR
7140 } \
7141 } while (0)
7142
7143+#ifdef CONFIG_X86_32
7144+#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
7145+ asm volatile(" movw %w5,%%ds\n" \
7146+ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
7147+ "2:\n" \
7148+ " pushl %%ss\n" \
7149+ " popl %%ds\n" \
7150+ ".section .fixup,\"ax\"\n" \
7151+ "3: movl %3,%0\n" \
7152+ " xor"itype" %"rtype"1,%"rtype"1\n" \
7153+ " jmp 2b\n" \
7154+ ".previous\n" \
7155+ _ASM_EXTABLE(1b, 3b) \
7156+ : "=r" (err), ltype (x) \
7157+ : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
7158+#else
7159 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
7160 asm volatile("1: mov"itype" %2,%"rtype"1\n" \
7161 "2:\n" \
017d2877 7162@@ -384,6 +411,7 @@ do { \
2380c486
JR
7163 _ASM_EXTABLE(1b, 3b) \
7164 : "=r" (err), ltype(x) \
7165 : "m" (__m(addr)), "i" (errret), "0" (err))
7166+#endif
7167
017d2877
AM
7168 #define __get_user_size_ex(x, ptr, size) \
7169 do { \
7170@@ -406,11 +434,22 @@ do { \
7171 } \
7172 } while (0)
7173
7174+#ifdef CONFIG_X86_32
7175+#define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
7176+ asm volatile(" movw %w2,%%ds\n" \
7177+ "1: mov"itype" %%ds:%1,%"rtype"0\n" \
7178+ "2:\n" \
7179+ " pushl %%ss\n" \
7180+ " popl %%ds\n" \
7181+ _ASM_EXTABLE(1b, 2b - 1b) \
7182+ : ltype(x) : "m" (__m(addr)), "r"(__USER_DS))
7183+#else
7184 #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
7185 asm volatile("1: mov"itype" %1,%"rtype"0\n" \
7186 "2:\n" \
7187 _ASM_EXTABLE(1b, 2b - 1b) \
7188 : ltype(x) : "m" (__m(addr)))
7189+#endif
7190
2380c486
JR
7191 #define __put_user_nocheck(x, ptr, size) \
7192 ({ \
017d2877 7193@@ -437,6 +476,22 @@ struct __large_struct { unsigned long bu
2380c486
JR
7194 * we do not write to any memory gcc knows about, so there are no
7195 * aliasing issues.
7196 */
7197+#ifdef CONFIG_X86_32
7198+#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
7199+ asm volatile(" movw %w5,%%ds\n" \
7200+ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
7201+ "2:\n" \
7202+ " pushl %%ss\n" \
7203+ " popl %%ds\n" \
7204+ ".section .fixup,\"ax\"\n" \
7205+ "3: movl %3,%0\n" \
7206+ " jmp 2b\n" \
7207+ ".previous\n" \
7208+ _ASM_EXTABLE(1b, 3b) \
7209+ : "=r"(err) \
7210+ : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
7211+ "r"(__USER_DS))
7212+#else
7213 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
7214 asm volatile("1: mov"itype" %"rtype"1,%2\n" \
7215 "2:\n" \
017d2877 7216@@ -447,12 +502,24 @@ struct __large_struct { unsigned long bu
2380c486
JR
7217 _ASM_EXTABLE(1b, 3b) \
7218 : "=r"(err) \
7219 : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
7220+#endif
017d2877
AM
7221
7222+#ifdef CONFIG_X86_32
7223+#define __put_user_asm_ex(x, addr, itype, rtype, ltype) \
7224+ asm volatile(" movw %w2,%%ds\n" \
7225+ "1: mov"itype" %"rtype"0,%%ds:%1\n" \
7226+ "2:\n" \
7227+ " pushl %%ss\n" \
7228+ " popl %%ds\n" \
7229+ _ASM_EXTABLE(1b, 2b - 1b) \
7230+ : : ltype(x), "m" (__m(addr)), "r"(__USER_DS))
7231+#else
7232 #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \
7233 asm volatile("1: mov"itype" %"rtype"0,%1\n" \
7234 "2:\n" \
7235 _ASM_EXTABLE(1b, 2b - 1b) \
7236 : : ltype(x), "m" (__m(addr)))
7237+#endif
7238
7239 /*
7240 * uaccess_try and catch
7241@@ -567,6 +634,7 @@ extern struct movsl_mask {
2380c486
JR
7242
7243 #define ARCH_HAS_NOCACHE_UACCESS 1
7244
7245+#define ARCH_HAS_SORT_EXTABLE
7246 #ifdef CONFIG_X86_32
7247 # include "uaccess_32.h"
7248 #else
017d2877
AM
7249diff -urNp linux-2.6.30.4/arch/x86/include/asm/vgtod.h linux-2.6.30.4/arch/x86/include/asm/vgtod.h
7250--- linux-2.6.30.4/arch/x86/include/asm/vgtod.h 2009-07-24 17:47:51.000000000 -0400
7251+++ linux-2.6.30.4/arch/x86/include/asm/vgtod.h 2009-07-30 09:48:09.936413079 -0400
de855c5d
AM
7252@@ -14,6 +14,7 @@ struct vsyscall_gtod_data {
7253 int sysctl_enabled;
7254 struct timezone sys_tz;
7255 struct { /* extract of a clocksource struct */
7256+ char name[8];
7257 cycle_t (*vread)(void);
7258 cycle_t cycle_last;
7259 cycle_t mask;
017d2877
AM
7260diff -urNp linux-2.6.30.4/arch/x86/include/asm/vsyscall.h linux-2.6.30.4/arch/x86/include/asm/vsyscall.h
7261--- linux-2.6.30.4/arch/x86/include/asm/vsyscall.h 2009-07-24 17:47:51.000000000 -0400
7262+++ linux-2.6.30.4/arch/x86/include/asm/vsyscall.h 2009-07-30 09:48:09.937413620 -0400
de855c5d
AM
7263@@ -15,9 +15,10 @@ enum vsyscall_num {
7264
7265 #ifdef __KERNEL__
7266 #include <linux/seqlock.h>
7267+#include <linux/getcpu.h>
7268+#include <linux/time.h>
7269
7270 #define __section_vgetcpu_mode __attribute__ ((unused, __section__ (".vgetcpu_mode"), aligned(16)))
7271-#define __section_jiffies __attribute__ ((unused, __section__ (".jiffies"), aligned(16)))
7272
7273 /* Definitions for CONFIG_GENERIC_TIME definitions */
7274 #define __section_vsyscall_gtod_data __attribute__ \
7275@@ -31,7 +32,6 @@ enum vsyscall_num {
7276 #define VGETCPU_LSL 2
7277
7278 extern int __vgetcpu_mode;
7279-extern volatile unsigned long __jiffies;
7280
7281 /* kernel space (writeable) */
7282 extern int vgetcpu_mode;
7283@@ -39,6 +39,9 @@ extern struct timezone sys_tz;
7284
7285 extern void map_vsyscall(void);
7286
7287+extern int vgettimeofday(struct timeval * tv, struct timezone * tz);
7288+extern time_t vtime(time_t *t);
7289+extern long vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache);
7290 #endif /* __KERNEL__ */
7291
7292 #endif /* _ASM_X86_VSYSCALL_H */
017d2877
AM
7293diff -urNp linux-2.6.30.4/arch/x86/Kconfig linux-2.6.30.4/arch/x86/Kconfig
7294--- linux-2.6.30.4/arch/x86/Kconfig 2009-07-24 17:47:51.000000000 -0400
7295+++ linux-2.6.30.4/arch/x86/Kconfig 2009-07-30 12:32:41.330879042 -0400
7296@@ -345,6 +345,7 @@ config X86_VSMP
7297 select PARAVIRT
7298 depends on X86_64 && PCI
7299 depends on X86_EXTENDED_PLATFORM
7300+ depends on !PAX_KERNEXEC
7301 ---help---
7302 Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is
7303 supposed to run on these EM64T-based machines. Only choose this option
7304@@ -464,6 +465,7 @@ config VMI
7305 bool "VMI Guest support"
7306 select PARAVIRT
7307 depends on X86_32
7308+ depends on !PAX_KERNEXEC
7309 ---help---
7310 VMI provides a paravirtualized interface to the VMware ESX server
7311 (it could be used by other hypervisors in theory too, but is not
7312@@ -474,6 +476,7 @@ config KVM_CLOCK
7313 bool "KVM paravirtualized clock"
7314 select PARAVIRT
7315 select PARAVIRT_CLOCK
7316+ depends on !PAX_KERNEXEC
7317 ---help---
7318 Turning on this option will allow you to run a paravirtualized clock
7319 when running over the KVM hypervisor. Instead of relying on a PIT
7320@@ -484,6 +487,7 @@ config KVM_CLOCK
7321 config KVM_GUEST
7322 bool "KVM Guest support"
7323 select PARAVIRT
7324+ depends on !PAX_KERNEXEC
7325 ---help---
7326 This option enables various optimizations for running under the KVM
7327 hypervisor.
7328@@ -492,6 +496,7 @@ source "arch/x86/lguest/Kconfig"
7329
7330 config PARAVIRT
7331 bool "Enable paravirtualization code"
7332+ depends on !PAX_KERNEXEC
7333 ---help---
7334 This changes the kernel so it can modify itself when it is run
7335 under a hypervisor, potentially improving performance significantly
7336@@ -1058,7 +1063,7 @@ config PAGE_OFFSET
2380c486
JR
7337 hex
7338 default 0xB0000000 if VMSPLIT_3G_OPT
7339 default 0x80000000 if VMSPLIT_2G
7340- default 0x78000000 if VMSPLIT_2G_OPT
7341+ default 0x70000000 if VMSPLIT_2G_OPT
7342 default 0x40000000 if VMSPLIT_1G
7343 default 0xC0000000
7344 depends on X86_32
017d2877
AM
7345@@ -1376,7 +1381,7 @@ config X86_PAT
7346
7347 config EFI
7348 bool "EFI runtime service support"
7349- depends on ACPI
7350+ depends on ACPI && !PAX_KERNEXEC
7351 ---help---
7352 This enables the kernel to use EFI runtime services that are
7353 available (such as the EFI variable services).
7354@@ -1467,8 +1472,7 @@ config KEXEC_JUMP
2380c486
JR
7355 config PHYSICAL_START
7356 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
7357 default "0x1000000" if X86_NUMAQ
7358- default "0x200000" if X86_64
7359- default "0x100000"
7360+ default "0x200000"
017d2877 7361 ---help---
2380c486
JR
7362 This gives the physical address where the kernel is loaded.
7363
017d2877 7364@@ -1560,9 +1564,10 @@ config HOTPLUG_CPU
2380c486
JR
7365 Say N if you want to disable CPU hotplug.
7366
7367 config COMPAT_VDSO
7368- def_bool y
7369+ def_bool n
7370 prompt "Compat VDSO support"
017d2877
AM
7371 depends on X86_32 || IA32_EMULATION
7372+ depends on !PAX_NOEXEC && !PAX_MEMORY_UDEREF
7373 ---help---
2380c486
JR
7374 Map the 32-bit VDSO to the predictable old-style address too.
7375 ---help---
017d2877
AM
7376diff -urNp linux-2.6.30.4/arch/x86/Kconfig.cpu linux-2.6.30.4/arch/x86/Kconfig.cpu
7377--- linux-2.6.30.4/arch/x86/Kconfig.cpu 2009-07-24 17:47:51.000000000 -0400
7378+++ linux-2.6.30.4/arch/x86/Kconfig.cpu 2009-07-30 09:48:09.916592662 -0400
7379@@ -331,7 +331,7 @@ config X86_PPRO_FENCE
2380c486
JR
7380
7381 config X86_F00F_BUG
7382 def_bool y
7383- depends on M586MMX || M586TSC || M586 || M486 || M386
7384+ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
7385
7386 config X86_WP_WORKS_OK
7387 def_bool y
017d2877 7388@@ -351,7 +351,7 @@ config X86_POPAD_OK
2380c486
JR
7389
7390 config X86_ALIGNMENT_16
7391 def_bool y
7392- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
7393+ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
7394
7395 config X86_INTEL_USERCOPY
7396 def_bool y
017d2877 7397@@ -397,7 +397,7 @@ config X86_CMPXCHG64
2380c486
JR
7398 # generates cmov.
7399 config X86_CMOV
7400 def_bool y
7401- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64)
7402+ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64)
7403
7404 config X86_MINIMUM_CPU_FAMILY
7405 int
017d2877
AM
7406diff -urNp linux-2.6.30.4/arch/x86/Kconfig.debug linux-2.6.30.4/arch/x86/Kconfig.debug
7407--- linux-2.6.30.4/arch/x86/Kconfig.debug 2009-07-24 17:47:51.000000000 -0400
7408+++ linux-2.6.30.4/arch/x86/Kconfig.debug 2009-07-30 09:48:09.916592662 -0400
7409@@ -99,7 +99,7 @@ config X86_PTDUMP
2380c486
JR
7410 config DEBUG_RODATA
7411 bool "Write protect kernel read-only data structures"
7412 default y
7413- depends on DEBUG_KERNEL
7414+ depends on DEBUG_KERNEL && BROKEN
017d2877 7415 ---help---
2380c486
JR
7416 Mark the kernel read-only data as write-protected in the pagetables,
7417 in order to catch accidental (and incorrect) writes to such const
017d2877
AM
7418diff -urNp linux-2.6.30.4/arch/x86/kernel/acpi/boot.c linux-2.6.30.4/arch/x86/kernel/acpi/boot.c
7419--- linux-2.6.30.4/arch/x86/kernel/acpi/boot.c 2009-07-24 17:47:51.000000000 -0400
7420+++ linux-2.6.30.4/arch/x86/kernel/acpi/boot.c 2009-07-30 09:48:09.938432163 -0400
7421@@ -1737,7 +1737,7 @@ static struct dmi_system_id __initdata a
2380c486
JR
7422 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
7423 },
7424 },
7425- {}
7426+ { NULL, NULL, {{0, {0}}}, NULL}
7427 };
7428
7429 /*
017d2877
AM
7430diff -urNp linux-2.6.30.4/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.30.4/arch/x86/kernel/acpi/realmode/wakeup.S
7431--- linux-2.6.30.4/arch/x86/kernel/acpi/realmode/wakeup.S 2009-07-24 17:47:51.000000000 -0400
7432+++ linux-2.6.30.4/arch/x86/kernel/acpi/realmode/wakeup.S 2009-07-30 09:48:09.938432163 -0400
2380c486
JR
7433@@ -104,7 +104,7 @@ _start:
7434 movl %eax, %ecx
7435 orl %edx, %ecx
7436 jz 1f
7437- movl $0xc0000080, %ecx
7438+ mov $MSR_EFER, %ecx
7439 wrmsr
7440 1:
7441
017d2877
AM
7442diff -urNp linux-2.6.30.4/arch/x86/kernel/acpi/sleep.c linux-2.6.30.4/arch/x86/kernel/acpi/sleep.c
7443--- linux-2.6.30.4/arch/x86/kernel/acpi/sleep.c 2009-07-24 17:47:51.000000000 -0400
7444+++ linux-2.6.30.4/arch/x86/kernel/acpi/sleep.c 2009-07-30 09:48:09.938432163 -0400
de855c5d
AM
7445@@ -11,11 +11,12 @@
7446 #include <linux/cpumask.h>
7447 #include <asm/segment.h>
7448 #include <asm/desc.h>
7449+#include <asm/e820.h>
7450
7451 #include "realmode/wakeup.h"
7452 #include "sleep.h"
7453
7454-unsigned long acpi_wakeup_address;
7455+unsigned long acpi_wakeup_address = 0x2000;
7456 unsigned long acpi_realmode_flags;
7457
7458 /* address in low memory of the wakeup routine. */
7459@@ -37,6 +38,10 @@ int acpi_save_state_mem(void)
2380c486
JR
7460 {
7461 struct wakeup_header *header;
7462
7463+#if defined(CONFIG_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_PAX_KERNEXEC)
7464+ unsigned long cr0;
7465+#endif
7466+
7467 if (!acpi_realmode) {
7468 printk(KERN_ERR "Could not allocate memory during boot, "
7469 "S3 disabled\n");
de855c5d 7470@@ -99,8 +104,18 @@ int acpi_save_state_mem(void)
2380c486
JR
7471 header->trampoline_segment = setup_trampoline() >> 4;
7472 #ifdef CONFIG_SMP
7473 stack_start.sp = temp_stack + sizeof(temp_stack);
7474+
7475+#ifdef CONFIG_PAX_KERNEXEC
7476+ pax_open_kernel(cr0);
7477+#endif
7478+
7479 early_gdt_descr.address =
7480 (unsigned long)get_cpu_gdt_table(smp_processor_id());
7481+
7482+#ifdef CONFIG_PAX_KERNEXEC
7483+ pax_close_kernel(cr0);
7484+#endif
7485+
017d2877 7486 initial_gs = per_cpu_offset(smp_processor_id());
2380c486
JR
7487 #endif
7488 initial_code = (unsigned long)wakeup_long64;
017d2877 7489@@ -134,14 +149,8 @@ void __init acpi_reserve_bootmem(void)
de855c5d
AM
7490 return;
7491 }
7492
7493- acpi_realmode = (unsigned long)alloc_bootmem_low(WAKEUP_SIZE);
7494-
7495- if (!acpi_realmode) {
7496- printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
7497- return;
7498- }
7499-
7500- acpi_wakeup_address = virt_to_phys((void *)acpi_realmode);
7501+ reserve_early(acpi_wakeup_address, acpi_wakeup_address + WAKEUP_SIZE, "ACPI Wakeup Code");
7502+ acpi_realmode = (unsigned long)__va(acpi_wakeup_address);;
7503 }
7504
7505
017d2877
AM
7506diff -urNp linux-2.6.30.4/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.30.4/arch/x86/kernel/acpi/wakeup_32.S
7507--- linux-2.6.30.4/arch/x86/kernel/acpi/wakeup_32.S 2009-07-24 17:47:51.000000000 -0400
7508+++ linux-2.6.30.4/arch/x86/kernel/acpi/wakeup_32.S 2009-07-30 09:48:09.938432163 -0400
2380c486
JR
7509@@ -30,13 +30,11 @@ wakeup_pmode_return:
7510 # and restore the stack ... but you need gdt for this to work
7511 movl saved_context_esp, %esp
7512
7513- movl %cs:saved_magic, %eax
7514- cmpl $0x12345678, %eax
7515+ cmpl $0x12345678, saved_magic
7516 jne bogus_magic
7517
7518 # jump to place where we left off
7519- movl saved_eip, %eax
7520- jmp *%eax
7521+ jmp *(saved_eip)
7522
7523 bogus_magic:
7524 jmp bogus_magic
017d2877
AM
7525diff -urNp linux-2.6.30.4/arch/x86/kernel/alternative.c linux-2.6.30.4/arch/x86/kernel/alternative.c
7526--- linux-2.6.30.4/arch/x86/kernel/alternative.c 2009-07-24 17:47:51.000000000 -0400
7527+++ linux-2.6.30.4/arch/x86/kernel/alternative.c 2009-07-30 09:48:09.939725122 -0400
7528@@ -400,7 +400,7 @@ void apply_paravirt(struct paravirt_patc
2380c486
JR
7529
7530 BUG_ON(p->len > MAX_PATCH_LEN);
7531 /* prep the buffer with the original instructions */
7532- memcpy(insnbuf, p->instr, p->len);
7533+ memcpy(insnbuf, ktla_ktva(p->instr), p->len);
7534 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
7535 (unsigned long)p->instr, p->len);
7536
017d2877 7537@@ -485,11 +485,26 @@ void __init alternative_instructions(voi
2380c486
JR
7538 * instructions. And on the local CPU you need to be protected again NMI or MCE
7539 * handlers seeing an inconsistent instruction while you patch.
7540 */
7541-void *text_poke_early(void *addr, const void *opcode, size_t len)
7542+void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
7543 {
7544 unsigned long flags;
7545+
7546+#ifdef CONFIG_PAX_KERNEXEC
7547+ unsigned long cr0;
7548+#endif
7549+
7550 local_irq_save(flags);
7551- memcpy(addr, opcode, len);
7552+
7553+#ifdef CONFIG_PAX_KERNEXEC
7554+ pax_open_kernel(cr0);
7555+#endif
7556+
7557+ memcpy(ktla_ktva(addr), opcode, len);
7558+
7559+#ifdef CONFIG_PAX_KERNEXEC
7560+ pax_close_kernel(cr0);
7561+#endif
7562+
7563 local_irq_restore(flags);
7564 sync_core();
7565 /* Could also do a CLFLUSH here to speed up CPU recovery; but
017d2877 7566@@ -512,35 +527,27 @@ void *text_poke_early(void *addr, const
2380c486
JR
7567 */
7568 void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
7569 {
7570- unsigned long flags;
7571- char *vaddr;
2380c486
JR
7572+ unsigned char *vaddr = ktla_ktva(addr);
7573 struct page *pages[2];
7574- int i;
7575+ size_t i;
7576+
7577+ if (!core_kernel_text((unsigned long)addr)
7578
7579- if (!core_kernel_text((unsigned long)addr)) {
7580- pages[0] = vmalloc_to_page(addr);
7581- pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
7582+#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
7583+ && (vaddr < MODULES_VADDR || MODULES_END < vaddr)
7584+#endif
7585+
7586+ ) {
7587+ pages[0] = vmalloc_to_page(vaddr);
7588+ pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
7589 } else {
7590- pages[0] = virt_to_page(addr);
7591+ pages[0] = virt_to_page(vaddr);
7592 WARN_ON(!PageReserved(pages[0]));
7593- pages[1] = virt_to_page(addr + PAGE_SIZE);
7594+ pages[1] = virt_to_page(vaddr + PAGE_SIZE);
7595 }
7596 BUG_ON(!pages[0]);
2380c486 7597- local_irq_save(flags);
017d2877
AM
7598- set_fixmap(FIX_TEXT_POKE0, page_to_phys(pages[0]));
7599- if (pages[1])
7600- set_fixmap(FIX_TEXT_POKE1, page_to_phys(pages[1]));
7601- vaddr = (char *)fix_to_virt(FIX_TEXT_POKE0);
2380c486 7602- memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
017d2877
AM
7603- clear_fixmap(FIX_TEXT_POKE0);
7604- if (pages[1])
7605- clear_fixmap(FIX_TEXT_POKE1);
7606- local_flush_tlb();
2380c486
JR
7607- sync_core();
7608- /* Could also do a CLFLUSH here to speed up CPU recovery; but
7609- that causes hangs on some VIA CPUs. */
7610+ text_poke_early(addr, opcode, len);
7611 for (i = 0; i < len; i++)
7612- BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
017d2877
AM
7613- local_irq_restore(flags);
7614+ BUG_ON(((char *)vaddr)[i] != ((char *)opcode)[i]);
2380c486
JR
7615 return addr;
7616 }
017d2877
AM
7617diff -urNp linux-2.6.30.4/arch/x86/kernel/apm_32.c linux-2.6.30.4/arch/x86/kernel/apm_32.c
7618--- linux-2.6.30.4/arch/x86/kernel/apm_32.c 2009-07-24 17:47:51.000000000 -0400
7619+++ linux-2.6.30.4/arch/x86/kernel/apm_32.c 2009-07-30 09:48:09.939725122 -0400
2380c486
JR
7620@@ -403,7 +403,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
7621 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
7622 static struct apm_user *user_list;
7623 static DEFINE_SPINLOCK(user_list_lock);
7624-static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
7625+static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
7626
7627 static const char driver_version[] = "1.16ac"; /* no spaces */
7628
017d2877 7629@@ -576,12 +576,25 @@ static long __apm_bios_call(void *_call)
2380c486 7630 struct desc_struct *gdt;
017d2877 7631 struct apm_bios_call *call = _call;
2380c486
JR
7632
7633+#ifdef CONFIG_PAX_KERNEXEC
7634+ unsigned long cr0;
7635+#endif
7636+
2380c486 7637 cpu = get_cpu();
017d2877 7638 BUG_ON(cpu != 0);
2380c486
JR
7639 gdt = get_cpu_gdt_table(cpu);
7640 save_desc_40 = gdt[0x40 / 8];
7641+
7642+#ifdef CONFIG_PAX_KERNEXEC
7643+ pax_open_kernel(cr0);
7644+#endif
7645+
7646 gdt[0x40 / 8] = bad_bios_desc;
7647
7648+#ifdef CONFIG_PAX_KERNEXEC
7649+ pax_close_kernel(cr0);
7650+#endif
7651+
7652 apm_irq_save(flags);
7653 APM_DO_SAVE_SEGS;
017d2877
AM
7654 apm_bios_call_asm(call->func, call->ebx, call->ecx,
7655@@ -589,7 +602,17 @@ static long __apm_bios_call(void *_call)
7656 &call->esi);
2380c486
JR
7657 APM_DO_RESTORE_SEGS;
7658 apm_irq_restore(flags);
7659+
7660+#ifdef CONFIG_PAX_KERNEXEC
7661+ pax_open_kernel(cr0);
7662+#endif
7663+
7664 gdt[0x40 / 8] = save_desc_40;
7665+
7666+#ifdef CONFIG_PAX_KERNEXEC
7667+ pax_close_kernel(cr0);
7668+#endif
7669+
7670 put_cpu();
2380c486 7671
017d2877
AM
7672 return call->eax & 0xff;
7673@@ -652,19 +675,42 @@ static long __apm_bios_call_simple(void
2380c486 7674 struct desc_struct *gdt;
017d2877 7675 struct apm_bios_call *call = _call;
2380c486
JR
7676
7677+#ifdef CONFIG_PAX_KERNEXEC
7678+ unsigned long cr0;
7679+#endif
7680+
2380c486 7681 cpu = get_cpu();
017d2877 7682 BUG_ON(cpu != 0);
2380c486
JR
7683 gdt = get_cpu_gdt_table(cpu);
7684 save_desc_40 = gdt[0x40 / 8];
7685+
7686+#ifdef CONFIG_PAX_KERNEXEC
7687+ pax_open_kernel(cr0);
7688+#endif
7689+
7690 gdt[0x40 / 8] = bad_bios_desc;
7691
7692+#ifdef CONFIG_PAX_KERNEXEC
7693+ pax_close_kernel(cr0);
7694+#endif
7695+
7696 apm_irq_save(flags);
7697 APM_DO_SAVE_SEGS;
017d2877
AM
7698 error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
7699 &call->eax);
2380c486
JR
7700 APM_DO_RESTORE_SEGS;
7701 apm_irq_restore(flags);
7702+
7703+#ifdef CONFIG_PAX_KERNEXEC
7704+ pax_open_kernel(cr0);
7705+#endif
7706+
7707 gdt[0x40 / 8] = save_desc_40;
7708+
7709+#ifdef CONFIG_PAX_KERNEXEC
7710+ pax_close_kernel(cr0);
7711+#endif
7712+
7713 put_cpu();
2380c486 7714 return error;
017d2877
AM
7715 }
7716@@ -967,7 +1013,7 @@ recalc:
2380c486
JR
7717
7718 static void apm_power_off(void)
7719 {
7720- unsigned char po_bios_call[] = {
7721+ const unsigned char po_bios_call[] = {
7722 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
7723 0x8e, 0xd0, /* movw ax,ss */
7724 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
017d2877 7725@@ -1925,7 +1971,10 @@ static const struct file_operations apm_
2380c486
JR
7726 static struct miscdevice apm_device = {
7727 APM_MINOR_DEV,
7728 "apm_bios",
7729- &apm_bios_fops
7730+ &apm_bios_fops,
7731+ {NULL, NULL},
7732+ NULL,
7733+ NULL
7734 };
7735
7736
017d2877 7737@@ -2246,7 +2295,7 @@ static struct dmi_system_id __initdata a
2380c486
JR
7738 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
7739 },
7740
7741- { }
7742+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
7743 };
7744
7745 /*
017d2877 7746@@ -2264,6 +2313,10 @@ static int __init apm_init(void)
2380c486
JR
7747 struct desc_struct *gdt;
7748 int err;
7749
7750+#ifdef CONFIG_PAX_KERNEXEC
7751+ unsigned long cr0;
7752+#endif
7753+
7754 dmi_check_system(apm_dmi_table);
7755
7756 if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
017d2877 7757@@ -2337,9 +2390,18 @@ static int __init apm_init(void)
2380c486
JR
7758 * This is for buggy BIOS's that refer to (real mode) segment 0x40
7759 * even though they are called in protected mode.
7760 */
7761+
7762+#ifdef CONFIG_PAX_KERNEXEC
7763+ pax_open_kernel(cr0);
7764+#endif
7765+
7766 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
7767 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
7768
7769+#ifdef CONFIG_PAX_KERNEXEC
7770+ pax_close_kernel(cr0);
7771+#endif
7772+
7773 /*
7774 * Set up the long jump entry point to the APM BIOS, which is called
7775 * from inline assembly.
017d2877 7776@@ -2358,6 +2420,11 @@ static int __init apm_init(void)
2380c486
JR
7777 * code to that CPU.
7778 */
7779 gdt = get_cpu_gdt_table(0);
7780+
7781+#ifdef CONFIG_PAX_KERNEXEC
7782+ pax_open_kernel(cr0);
7783+#endif
7784+
7785 set_base(gdt[APM_CS >> 3],
7786 __va((unsigned long)apm_info.bios.cseg << 4));
7787 set_base(gdt[APM_CS_16 >> 3],
017d2877 7788@@ -2365,6 +2432,10 @@ static int __init apm_init(void)
2380c486
JR
7789 set_base(gdt[APM_DS >> 3],
7790 __va((unsigned long)apm_info.bios.dseg << 4));
7791
7792+#ifdef CONFIG_PAX_KERNEXEC
7793+ pax_close_kernel(cr0);
7794+#endif
7795+
7796 proc_create("apm", 0, NULL, &apm_file_ops);
7797
7798 kapmd_task = kthread_create(apm, NULL, "kapmd");
017d2877
AM
7799diff -urNp linux-2.6.30.4/arch/x86/kernel/asm-offsets_32.c linux-2.6.30.4/arch/x86/kernel/asm-offsets_32.c
7800--- linux-2.6.30.4/arch/x86/kernel/asm-offsets_32.c 2009-07-24 17:47:51.000000000 -0400
7801+++ linux-2.6.30.4/arch/x86/kernel/asm-offsets_32.c 2009-07-30 09:48:09.939725122 -0400
7802@@ -115,6 +115,7 @@ void foo(void)
2380c486
JR
7803 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
7804 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
7805 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
7806+ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
7807 #endif
7808
7809 #ifdef CONFIG_XEN
017d2877
AM
7810diff -urNp linux-2.6.30.4/arch/x86/kernel/asm-offsets_64.c linux-2.6.30.4/arch/x86/kernel/asm-offsets_64.c
7811--- linux-2.6.30.4/arch/x86/kernel/asm-offsets_64.c 2009-07-24 17:47:51.000000000 -0400
7812+++ linux-2.6.30.4/arch/x86/kernel/asm-offsets_64.c 2009-07-30 09:48:09.939725122 -0400
7813@@ -114,6 +114,7 @@ int main(void)
2380c486
JR
7814 ENTRY(cr8);
7815 BLANK();
7816 #undef ENTRY
7817+ DEFINE(TSS_size, sizeof(struct tss_struct));
7818 DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
7819 BLANK();
7820 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
017d2877
AM
7821diff -urNp linux-2.6.30.4/arch/x86/kernel/cpu/common.c linux-2.6.30.4/arch/x86/kernel/cpu/common.c
7822--- linux-2.6.30.4/arch/x86/kernel/cpu/common.c 2009-07-24 17:47:51.000000000 -0400
7823+++ linux-2.6.30.4/arch/x86/kernel/cpu/common.c 2009-07-30 09:48:09.941068037 -0400
7824@@ -60,60 +60,6 @@ void __init setup_cpu_local_masks(void)
2380c486 7825
017d2877 7826 static const struct cpu_dev *this_cpu __cpuinitdata;
2380c486 7827
017d2877 7828-DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
2380c486 7829-#ifdef CONFIG_X86_64
017d2877
AM
7830- /*
7831- * We need valid kernel segments for data and code in long mode too
7832- * IRET will check the segment types kkeil 2000/10/28
7833- * Also sysret mandates a special GDT layout
7834- *
7835- * TLS descriptors are currently at a different place compared to i386.
7836- * Hopefully nobody expects them at a fixed place (Wine?)
7837- */
7838- [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
7839- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
7840- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
7841- [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
7842- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
7843- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
2380c486 7844-#else
017d2877
AM
7845- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
7846- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
7847- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
7848- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
2380c486
JR
7849- /*
7850- * Segments used for calling PnP BIOS have byte granularity.
7851- * They code segments and data segments have fixed 64k limits,
7852- * the transfer segment sizes are set at run time.
7853- */
7854- /* 32-bit code */
017d2877 7855- [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
2380c486 7856- /* 16-bit code */
017d2877 7857- [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
2380c486 7858- /* 16-bit data */
017d2877 7859- [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
2380c486 7860- /* 16-bit data */
017d2877 7861- [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
2380c486 7862- /* 16-bit data */
017d2877 7863- [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
2380c486
JR
7864- /*
7865- * The APM segments have byte granularity and their bases
7866- * are set at run time. All have 64k limits.
7867- */
7868- /* 32-bit code */
017d2877 7869- [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
2380c486 7870- /* 16-bit code */
017d2877 7871- [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
2380c486 7872- /* data */
017d2877 7873- [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
2380c486 7874-
017d2877
AM
7875- [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
7876- [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } },
7877- GDT_STACK_CANARY_INIT
2380c486 7878-#endif
017d2877 7879-} };
2380c486
JR
7880-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
7881-
017d2877
AM
7882 static int __init x86_xsave_setup(char *s)
7883 {
7884 setup_clear_cpu_cap(X86_FEATURE_XSAVE);
7885@@ -320,7 +266,7 @@ void switch_to_new_gdt(int cpu)
2380c486
JR
7886 {
7887 struct desc_ptr gdt_descr;
7888
017d2877
AM
7889- gdt_descr.address = (long)get_cpu_gdt_table(cpu);
7890+ gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
2380c486
JR
7891 gdt_descr.size = GDT_SIZE - 1;
7892 load_gdt(&gdt_descr);
017d2877
AM
7893 /* Reload the per-cpu base */
7894@@ -796,6 +742,10 @@ static void __cpuinit identify_cpu(struc
7895 /* Filter out anything that depends on CPUID levels we don't have */
7896 filter_cpuid_features(c, true);
2380c486
JR
7897
7898+#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
7899+ setup_clear_cpu_cap(X86_FEATURE_SEP);
7900+#endif
7901+
7902 /* If the model name is still unset, do table lookup. */
7903 if (!c->x86_model_id[0]) {
017d2877
AM
7904 const char *p;
7905@@ -972,7 +922,7 @@ static __init int setup_disablecpuid(cha
7906 __setup("clearcpuid=", setup_disablecpuid);
2380c486 7907
017d2877 7908 #ifdef CONFIG_X86_64
2380c486
JR
7909-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
7910+struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
7911
017d2877
AM
7912 DEFINE_PER_CPU_FIRST(union irq_stack_union,
7913 irq_stack_union) __aligned(PAGE_SIZE);
7914@@ -1082,7 +1032,7 @@ void __cpuinit cpu_init(void)
7915 int i;
2380c486 7916
017d2877
AM
7917 cpu = stack_smp_processor_id();
7918- t = &per_cpu(init_tss, cpu);
7919+ t = init_tss + cpu;
7920 orig_ist = &per_cpu(orig_ist, cpu);
7921
7922 #ifdef CONFIG_NUMA
7923@@ -1180,7 +1130,7 @@ void __cpuinit cpu_init(void)
2380c486
JR
7924 {
7925 int cpu = smp_processor_id();
7926 struct task_struct *curr = current;
7927- struct tss_struct *t = &per_cpu(init_tss, cpu);
7928+ struct tss_struct *t = init_tss + cpu;
7929 struct thread_struct *thread = &curr->thread;
7930
7931 if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
017d2877
AM
7932diff -urNp linux-2.6.30.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.30.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
7933--- linux-2.6.30.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2009-07-24 17:47:51.000000000 -0400
7934+++ linux-2.6.30.4/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2009-07-30 09:48:09.941068037 -0400
7935@@ -590,7 +590,7 @@ static const struct dmi_system_id sw_any
2380c486
JR
7936 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
7937 },
7938 },
7939- { }
7940+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
7941 };
7942 #endif
7943
017d2877
AM
7944diff -urNp linux-2.6.30.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.30.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
7945--- linux-2.6.30.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2009-07-24 17:47:51.000000000 -0400
7946+++ linux-2.6.30.4/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2009-07-30 09:48:09.941727851 -0400
2380c486
JR
7947@@ -225,7 +225,7 @@ static struct cpu_model models[] =
7948 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
7949 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
7950
7951- { NULL, }
7952+ { NULL, NULL, 0, NULL}
7953 };
7954 #undef _BANIAS
7955 #undef BANIAS
017d2877
AM
7956diff -urNp linux-2.6.30.4/arch/x86/kernel/cpu/intel.c linux-2.6.30.4/arch/x86/kernel/cpu/intel.c
7957--- linux-2.6.30.4/arch/x86/kernel/cpu/intel.c 2009-07-24 17:47:51.000000000 -0400
7958+++ linux-2.6.30.4/arch/x86/kernel/cpu/intel.c 2009-07-30 09:48:09.941727851 -0400
7959@@ -117,7 +117,7 @@ static void __cpuinit trap_init_f00f_bug
2380c486
JR
7960 * Update the IDT descriptor and reload the IDT so that
7961 * it uses the read-only mapped virtual address.
7962 */
7963- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
7964+ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
7965 load_idt(&idt_descr);
7966 }
7967 #endif
017d2877
AM
7968diff -urNp linux-2.6.30.4/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.30.4/arch/x86/kernel/cpu/mcheck/mce_64.c
7969--- linux-2.6.30.4/arch/x86/kernel/cpu/mcheck/mce_64.c 2009-07-24 17:47:51.000000000 -0400
7970+++ linux-2.6.30.4/arch/x86/kernel/cpu/mcheck/mce_64.c 2009-07-30 09:48:09.941727851 -0400
7971@@ -830,6 +830,7 @@ static struct miscdevice mce_log_device
2380c486
JR
7972 MISC_MCELOG_MINOR,
7973 "mcelog",
7974 &mce_chrdev_ops,
7975+ {NULL, NULL}, NULL, NULL
7976 };
7977
017d2877
AM
7978 /*
7979diff -urNp linux-2.6.30.4/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.30.4/arch/x86/kernel/cpu/mtrr/generic.c
7980--- linux-2.6.30.4/arch/x86/kernel/cpu/mtrr/generic.c 2009-07-24 17:47:51.000000000 -0400
7981+++ linux-2.6.30.4/arch/x86/kernel/cpu/mtrr/generic.c 2009-07-30 09:48:09.942991706 -0400
2380c486
JR
7982@@ -23,14 +23,14 @@ static struct fixed_range_block fixed_ra
7983 { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
7984 { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
7985 { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
7986- {}
7987+ { 0, 0 }
7988 };
7989
7990 static unsigned long smp_changes_mask;
7991 static int mtrr_state_set;
7992 u64 mtrr_tom2;
7993
7994-struct mtrr_state_type mtrr_state = {};
7995+struct mtrr_state_type mtrr_state;
7996 EXPORT_SYMBOL_GPL(mtrr_state);
7997
017d2877
AM
7998 /**
7999diff -urNp linux-2.6.30.4/arch/x86/kernel/crash.c linux-2.6.30.4/arch/x86/kernel/crash.c
8000--- linux-2.6.30.4/arch/x86/kernel/crash.c 2009-07-24 17:47:51.000000000 -0400
8001+++ linux-2.6.30.4/arch/x86/kernel/crash.c 2009-07-30 09:48:09.942991706 -0400
8002@@ -41,7 +41,7 @@ static void kdump_nmi_callback(int cpu,
2380c486
JR
8003 regs = args->regs;
8004
8005 #ifdef CONFIG_X86_32
8006- if (!user_mode_vm(regs)) {
8007+ if (!user_mode(regs)) {
8008 crash_fixup_ss_esp(&fixed_regs, regs);
8009 regs = &fixed_regs;
8010 }
017d2877
AM
8011diff -urNp linux-2.6.30.4/arch/x86/kernel/doublefault_32.c linux-2.6.30.4/arch/x86/kernel/doublefault_32.c
8012--- linux-2.6.30.4/arch/x86/kernel/doublefault_32.c 2009-07-24 17:47:51.000000000 -0400
8013+++ linux-2.6.30.4/arch/x86/kernel/doublefault_32.c 2009-07-30 09:48:09.942991706 -0400
2380c486
JR
8014@@ -11,7 +11,7 @@
8015
8016 #define DOUBLEFAULT_STACKSIZE (1024)
8017 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
8018-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
8019+#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
8020
8021 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
8022
8023@@ -21,7 +21,7 @@ static void doublefault_fn(void)
8024 unsigned long gdt, tss;
8025
8026 store_gdt(&gdt_desc);
8027- gdt = gdt_desc.address;
8028+ gdt = (unsigned long)gdt_desc.address;
8029
8030 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
8031
8032@@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
8033 /* 0x2 bit is always set */
8034 .flags = X86_EFLAGS_SF | 0x2,
8035 .sp = STACK_START,
8036- .es = __USER_DS,
8037+ .es = __KERNEL_DS,
8038 .cs = __KERNEL_CS,
8039 .ss = __KERNEL_DS,
8040- .ds = __USER_DS,
8041+ .ds = __KERNEL_DS,
8042 .fs = __KERNEL_PERCPU,
8043
8044 .__cr3 = __pa_nodebug(swapper_pg_dir),
017d2877
AM
8045diff -urNp linux-2.6.30.4/arch/x86/kernel/dumpstack_32.c linux-2.6.30.4/arch/x86/kernel/dumpstack_32.c
8046--- linux-2.6.30.4/arch/x86/kernel/dumpstack_32.c 2009-07-24 17:47:51.000000000 -0400
8047+++ linux-2.6.30.4/arch/x86/kernel/dumpstack_32.c 2009-07-30 09:48:09.943696998 -0400
2380c486
JR
8048@@ -107,11 +107,12 @@ void show_registers(struct pt_regs *regs
8049 * When in-kernel, we also print out the stack and code at the
8050 * time of the fault..
8051 */
8052- if (!user_mode_vm(regs)) {
8053+ if (!user_mode(regs)) {
8054 unsigned int code_prologue = code_bytes * 43 / 64;
8055 unsigned int code_len = code_bytes;
8056 unsigned char c;
8057 u8 *ip;
8058+ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
8059
8060 printk(KERN_EMERG "Stack:\n");
8061 show_stack_log_lvl(NULL, regs, &regs->sp,
8062@@ -119,10 +120,10 @@ void show_registers(struct pt_regs *regs
8063
8064 printk(KERN_EMERG "Code: ");
8065
8066- ip = (u8 *)regs->ip - code_prologue;
8067+ ip = (u8 *)regs->ip - code_prologue + cs_base;
8068 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
8069 /* try starting at IP */
8070- ip = (u8 *)regs->ip;
8071+ ip = (u8 *)regs->ip + cs_base;
8072 code_len = code_len - code_prologue + 1;
8073 }
8074 for (i = 0; i < code_len; i++, ip++) {
8075@@ -131,7 +132,7 @@ void show_registers(struct pt_regs *regs
8076 printk(" Bad EIP value.");
8077 break;
8078 }
8079- if (ip == (u8 *)regs->ip)
8080+ if (ip == (u8 *)regs->ip + cs_base)
8081 printk("<%02x> ", c);
8082 else
8083 printk("%02x ", c);
8084@@ -144,6 +145,7 @@ int is_valid_bugaddr(unsigned long ip)
8085 {
8086 unsigned short ud2;
8087
8088+ ip = ktla_ktva(ip);
8089 if (ip < PAGE_OFFSET)
8090 return 0;
8091 if (probe_kernel_address((unsigned short *)ip, ud2))
017d2877
AM
8092diff -urNp linux-2.6.30.4/arch/x86/kernel/dumpstack.c linux-2.6.30.4/arch/x86/kernel/dumpstack.c
8093--- linux-2.6.30.4/arch/x86/kernel/dumpstack.c 2009-07-24 17:47:51.000000000 -0400
8094+++ linux-2.6.30.4/arch/x86/kernel/dumpstack.c 2009-07-30 09:48:09.942991706 -0400
8095@@ -180,7 +180,7 @@ void dump_stack(void)
de855c5d
AM
8096 #endif
8097
8098 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
8099- current->pid, current->comm, print_tainted(),
8100+ task_pid_nr(current), current->comm, print_tainted(),
8101 init_utsname()->release,
8102 (int)strcspn(init_utsname()->version, " "),
8103 init_utsname()->version);
017d2877
AM
8104@@ -241,7 +241,7 @@ void __kprobes oops_end(unsigned long fl
8105 panic("Fatal exception in interrupt");
8106 if (panic_on_oops)
8107 panic("Fatal exception");
8108- do_exit(signr);
8109+ do_group_exit(signr);
8110 }
8111
8112 int __kprobes __die(const char *str, struct pt_regs *regs, long err)
8113@@ -295,7 +295,7 @@ void die(const char *str, struct pt_regs
2380c486
JR
8114 unsigned long flags = oops_begin();
8115 int sig = SIGSEGV;
8116
8117- if (!user_mode_vm(regs))
8118+ if (!user_mode(regs))
8119 report_bug(regs->ip, regs);
8120
8121 if (__die(str, regs, err))
017d2877
AM
8122diff -urNp linux-2.6.30.4/arch/x86/kernel/e820.c linux-2.6.30.4/arch/x86/kernel/e820.c
8123--- linux-2.6.30.4/arch/x86/kernel/e820.c 2009-07-24 17:47:51.000000000 -0400
8124+++ linux-2.6.30.4/arch/x86/kernel/e820.c 2009-07-30 09:48:09.943696998 -0400
8125@@ -739,7 +739,10 @@ struct early_res {
de855c5d
AM
8126 };
8127 static struct early_res early_res[MAX_EARLY_RES] __initdata = {
8128 { 0, PAGE_SIZE, "BIOS data page" }, /* BIOS data page */
8129- {}
8130+#ifdef CONFIG_VM86
8131+ { PAGE_SIZE, ISA_START_ADDRESS, "V86 mode memory", 1 },
8132+#endif
8133+ { 0, 0, {0}, 0 }
8134 };
8135
8136 static int __init find_overlapped_early(u64 start, u64 end)
017d2877
AM
8137diff -urNp linux-2.6.30.4/arch/x86/kernel/efi_32.c linux-2.6.30.4/arch/x86/kernel/efi_32.c
8138--- linux-2.6.30.4/arch/x86/kernel/efi_32.c 2009-07-24 17:47:51.000000000 -0400
8139+++ linux-2.6.30.4/arch/x86/kernel/efi_32.c 2009-07-30 09:48:09.943696998 -0400
2380c486
JR
8140@@ -38,70 +38,38 @@
8141 */
8142
8143 static unsigned long efi_rt_eflags;
8144-static pgd_t efi_bak_pg_dir_pointer[2];
8145+static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
8146
8147-void efi_call_phys_prelog(void)
8148+void __init efi_call_phys_prelog(void)
8149 {
8150- unsigned long cr4;
8151- unsigned long temp;
8152 struct desc_ptr gdt_descr;
8153
8154 local_irq_save(efi_rt_eflags);
8155
8156- /*
8157- * If I don't have PAE, I should just duplicate two entries in page
8158- * directory. If I have PAE, I just need to duplicate one entry in
8159- * page directory.
8160- */
8161- cr4 = read_cr4_safe();
8162
8163- if (cr4 & X86_CR4_PAE) {
8164- efi_bak_pg_dir_pointer[0].pgd =
8165- swapper_pg_dir[pgd_index(0)].pgd;
8166- swapper_pg_dir[0].pgd =
8167- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
8168- } else {
8169- efi_bak_pg_dir_pointer[0].pgd =
8170- swapper_pg_dir[pgd_index(0)].pgd;
8171- efi_bak_pg_dir_pointer[1].pgd =
8172- swapper_pg_dir[pgd_index(0x400000)].pgd;
8173- swapper_pg_dir[pgd_index(0)].pgd =
8174- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
8175- temp = PAGE_OFFSET + 0x400000;
8176- swapper_pg_dir[pgd_index(0x400000)].pgd =
8177- swapper_pg_dir[pgd_index(temp)].pgd;
8178- }
8179+ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
8180+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
8181+ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
8182
8183 /*
8184 * After the lock is released, the original page table is restored.
8185 */
8186 __flush_tlb_all();
8187
8188- gdt_descr.address = __pa(get_cpu_gdt_table(0));
8189+ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
8190 gdt_descr.size = GDT_SIZE - 1;
8191 load_gdt(&gdt_descr);
8192 }
8193
8194-void efi_call_phys_epilog(void)
8195+void __init efi_call_phys_epilog(void)
8196 {
8197- unsigned long cr4;
8198 struct desc_ptr gdt_descr;
8199
8200- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
8201+ gdt_descr.address = get_cpu_gdt_table(0);
8202 gdt_descr.size = GDT_SIZE - 1;
8203 load_gdt(&gdt_descr);
8204
8205- cr4 = read_cr4_safe();
8206-
8207- if (cr4 & X86_CR4_PAE) {
8208- swapper_pg_dir[pgd_index(0)].pgd =
8209- efi_bak_pg_dir_pointer[0].pgd;
8210- } else {
8211- swapper_pg_dir[pgd_index(0)].pgd =
8212- efi_bak_pg_dir_pointer[0].pgd;
8213- swapper_pg_dir[pgd_index(0x400000)].pgd =
8214- efi_bak_pg_dir_pointer[1].pgd;
8215- }
8216+ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
8217
8218 /*
8219 * After the lock is released, the original page table is restored.
017d2877
AM
8220diff -urNp linux-2.6.30.4/arch/x86/kernel/efi_stub_32.S linux-2.6.30.4/arch/x86/kernel/efi_stub_32.S
8221--- linux-2.6.30.4/arch/x86/kernel/efi_stub_32.S 2009-07-24 17:47:51.000000000 -0400
8222+++ linux-2.6.30.4/arch/x86/kernel/efi_stub_32.S 2009-07-30 09:48:09.944948217 -0400
2380c486
JR
8223@@ -6,6 +6,7 @@
8224 */
8225
8226 #include <linux/linkage.h>
8227+#include <linux/init.h>
017d2877 8228 #include <asm/page_types.h>
2380c486
JR
8229
8230 /*
8231@@ -20,7 +21,7 @@
8232 * service functions will comply with gcc calling convention, too.
8233 */
8234
8235-.text
8236+__INIT
8237 ENTRY(efi_call_phys)
8238 /*
8239 * 0. The function can only be called in Linux kernel. So CS has been
8240@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
8241 * The mapping of lower virtual memory has been created in prelog and
8242 * epilog.
8243 */
8244- movl $1f, %edx
8245- subl $__PAGE_OFFSET, %edx
8246- jmp *%edx
8247+ jmp 1f-__PAGE_OFFSET
8248 1:
8249
8250 /*
8251@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
8252 * parameter 2, ..., param n. To make things easy, we save the return
8253 * address of efi_call_phys in a global variable.
8254 */
8255- popl %edx
8256- movl %edx, saved_return_addr
8257- /* get the function pointer into ECX*/
8258- popl %ecx
8259- movl %ecx, efi_rt_function_ptr
8260- movl $2f, %edx
8261- subl $__PAGE_OFFSET, %edx
8262- pushl %edx
8263+ popl (saved_return_addr)
8264+ popl (efi_rt_function_ptr)
8265
8266 /*
8267 * 3. Clear PG bit in %CR0.
8268@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
8269 /*
8270 * 5. Call the physical function.
8271 */
8272- jmp *%ecx
8273+ call *(efi_rt_function_ptr-__PAGE_OFFSET)
8274
8275-2:
8276 /*
8277 * 6. After EFI runtime service returns, control will return to
8278 * following instruction. We'd better readjust stack pointer first.
017d2877 8279@@ -88,35 +80,28 @@ ENTRY(efi_call_phys)
2380c486
JR
8280 movl %cr0, %edx
8281 orl $0x80000000, %edx
8282 movl %edx, %cr0
8283- jmp 1f
8284-1:
8285+
8286 /*
8287 * 8. Now restore the virtual mode from flat mode by
8288 * adding EIP with PAGE_OFFSET.
8289 */
8290- movl $1f, %edx
8291- jmp *%edx
8292+ jmp 1f+__PAGE_OFFSET
8293 1:
8294
8295 /*
8296 * 9. Balance the stack. And because EAX contain the return value,
8297 * we'd better not clobber it.
8298 */
8299- leal efi_rt_function_ptr, %edx
8300- movl (%edx), %ecx
8301- pushl %ecx
8302+ pushl (efi_rt_function_ptr)
8303
8304 /*
8305- * 10. Push the saved return address onto the stack and return.
8306+ * 10. Return to the saved return address.
8307 */
8308- leal saved_return_addr, %edx
8309- movl (%edx), %ecx
8310- pushl %ecx
8311- ret
8312+ jmpl *(saved_return_addr)
017d2877 8313 ENDPROC(efi_call_phys)
2380c486
JR
8314 .previous
8315
8316-.data
8317+__INITDATA
8318 saved_return_addr:
8319 .long 0
8320 efi_rt_function_ptr:
017d2877
AM
8321diff -urNp linux-2.6.30.4/arch/x86/kernel/entry_32.S linux-2.6.30.4/arch/x86/kernel/entry_32.S
8322--- linux-2.6.30.4/arch/x86/kernel/entry_32.S 2009-07-24 17:47:51.000000000 -0400
8323+++ linux-2.6.30.4/arch/x86/kernel/entry_32.S 2009-07-30 09:48:09.945662533 -0400
8324@@ -192,7 +192,7 @@
8325
8326 #endif /* CONFIG_X86_32_LAZY_GS */
8327
8328-.macro SAVE_ALL
8329+.macro __SAVE_ALL _DS
8330 cld
8331 PUSH_GS
8332 pushl %fs
8333@@ -225,7 +225,7 @@
8334 pushl %ebx
8335 CFI_ADJUST_CFA_OFFSET 4
8336 CFI_REL_OFFSET ebx, 0
8337- movl $(__USER_DS), %edx
8338+ movl $\_DS, %edx
8339 movl %edx, %ds
8340 movl %edx, %es
8341 movl $(__KERNEL_PERCPU), %edx
8342@@ -233,6 +233,21 @@
8343 SET_KERNEL_GS %edx
8344 .endm
8345
8346+.macro SAVE_ALL
2380c486 8347+#ifdef CONFIG_PAX_KERNEXEC
017d2877
AM
8348+ __SAVE_ALL __KERNEL_DS
8349+ GET_CR0_INTO_EDX;
8350+ movl %edx, %esi;
8351+ orl $X86_CR0_WP, %edx;
8352+ xorl %edx, %esi;
2380c486
JR
8353+ SET_CR0_FROM_EDX
8354+#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
017d2877 8355+ __SAVE_ALL __KERNEL_DS
2380c486 8356+#else
017d2877 8357+ __SAVE_ALL __USER_DS
2380c486 8358+#endif
017d2877 8359+.endm
2380c486 8360+
017d2877
AM
8361 .macro RESTORE_INT_REGS
8362 popl %ebx
8363 CFI_ADJUST_CFA_OFFSET -4
8364@@ -330,6 +345,11 @@ ENTRY(ret_from_fork)
2380c486
JR
8365 CFI_ADJUST_CFA_OFFSET 4
8366 popfl
8367 CFI_ADJUST_CFA_OFFSET -4
8368+
8369+#ifdef CONFIG_PAX_KERNEXEC
8370+ xorl %esi, %esi
8371+#endif
8372+
8373 jmp syscall_exit
8374 CFI_ENDPROC
8375 END(ret_from_fork)
017d2877 8376@@ -353,7 +373,17 @@ check_userspace:
2380c486
JR
8377 movb PT_CS(%esp), %al
8378 andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
8379 cmpl $USER_RPL, %eax
8380+
8381+#ifdef CONFIG_PAX_KERNEXEC
8382+ jae resume_userspace
8383+
8384+ GET_CR0_INTO_EDX
8385+ xorl %esi, %edx
8386+ SET_CR0_FROM_EDX
8387+ jmp resume_kernel
8388+#else
8389 jb resume_kernel # not returning to v8086 or userspace
8390+#endif
8391
8392 ENTRY(resume_userspace)
8393 LOCKDEP_SYS_EXIT
017d2877 8394@@ -415,10 +445,9 @@ sysenter_past_esp:
2380c486
JR
8395 /*CFI_REL_OFFSET cs, 0*/
8396 /*
8397 * Push current_thread_info()->sysenter_return to the stack.
8398- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
8399- * pushed above; +8 corresponds to copy_thread's esp0 setting.
8400 */
8401- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
8402+ GET_THREAD_INFO(%ebp)
8403+ pushl TI_sysenter_return(%ebp)
8404 CFI_ADJUST_CFA_OFFSET 4
8405 CFI_REL_OFFSET eip, 0
8406
017d2877 8407@@ -431,9 +460,19 @@ sysenter_past_esp:
2380c486
JR
8408 * Load the potential sixth argument from user stack.
8409 * Careful about security.
8410 */
8411+ movl PT_OLDESP(%esp),%ebp
8412+
8413+#ifdef CONFIG_PAX_MEMORY_UDEREF
8414+ mov PT_OLDSS(%esp),%ds
8415+1: movl %ds:(%ebp),%ebp
8416+ push %ss
8417+ pop %ds
8418+#else
8419 cmpl $__PAGE_OFFSET-3,%ebp
8420 jae syscall_fault
8421 1: movl (%ebp),%ebp
8422+#endif
8423+
8424 movl %ebp,PT_EBP(%esp)
8425 .section __ex_table,"a"
8426 .align 4
017d2877
AM
8427@@ -456,12 +495,23 @@ sysenter_do_call:
8428 testl $_TIF_ALLWORK_MASK, %ecx
2380c486
JR
8429 jne sysexit_audit
8430 sysenter_exit:
8431+
8432+#ifdef CONFIG_PAX_RANDKSTACK
8433+ pushl %eax
8434+ CFI_ADJUST_CFA_OFFSET 4
8435+ call pax_randomize_kstack
8436+ popl %eax
8437+ CFI_ADJUST_CFA_OFFSET -4
8438+#endif
8439+
8440 /* if something modifies registers it must also disable sysexit */
8441 movl PT_EIP(%esp), %edx
8442 movl PT_OLDESP(%esp), %ecx
8443 xorl %ebp,%ebp
8444 TRACE_IRQS_ON
8445 1: mov PT_FS(%esp), %fs
8446+2: mov PT_DS(%esp), %ds
8447+3: mov PT_ES(%esp), %es
017d2877 8448 PTGS_TO_GS
2380c486
JR
8449 ENABLE_INTERRUPTS_SYSEXIT
8450
017d2877 8451@@ -505,11 +555,17 @@ sysexit_audit:
2380c486
JR
8452
8453 CFI_ENDPROC
8454 .pushsection .fixup,"ax"
8455-2: movl $0,PT_FS(%esp)
8456+4: movl $0,PT_FS(%esp)
8457+ jmp 1b
8458+5: movl $0,PT_DS(%esp)
8459+ jmp 1b
8460+6: movl $0,PT_ES(%esp)
8461 jmp 1b
8462 .section __ex_table,"a"
8463 .align 4
8464- .long 1b,2b
8465+ .long 1b,4b
8466+ .long 2b,5b
8467+ .long 3b,6b
8468 .popsection
017d2877 8469 PTGS_TO_GS_EX
2380c486 8470 ENDPROC(ia32_sysenter_target)
017d2877
AM
8471@@ -539,6 +595,10 @@ syscall_exit:
8472 testl $_TIF_ALLWORK_MASK, %ecx # current->work
2380c486
JR
8473 jne syscall_exit_work
8474
8475+#ifdef CONFIG_PAX_RANDKSTACK
8476+ call pax_randomize_kstack
8477+#endif
8478+
8479 restore_all:
8480 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
8481 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
017d2877 8482@@ -631,25 +691,19 @@ work_resched:
2380c486
JR
8483
8484 work_notifysig: # deal with pending signals and
8485 # notify-resume requests
8486+ movl %esp, %eax
8487 #ifdef CONFIG_VM86
8488 testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
8489- movl %esp, %eax
8490- jne work_notifysig_v86 # returning to kernel-space or
8491+ jz 1f # returning to kernel-space or
8492 # vm86-space
8493- xorl %edx, %edx
8494- call do_notify_resume
8495- jmp resume_userspace_sig
8496
8497- ALIGN
8498-work_notifysig_v86:
8499 pushl %ecx # save ti_flags for do_notify_resume
8500 CFI_ADJUST_CFA_OFFSET 4
8501 call save_v86_state # %eax contains pt_regs pointer
8502 popl %ecx
8503 CFI_ADJUST_CFA_OFFSET -4
8504 movl %eax, %esp
8505-#else
8506- movl %esp, %eax
8507+1:
8508 #endif
8509 xorl %edx, %edx
8510 call do_notify_resume
017d2877 8511@@ -684,6 +738,10 @@ END(syscall_exit_work)
2380c486
JR
8512
8513 RING0_INT_FRAME # can't unwind into user space anyway
8514 syscall_fault:
8515+#ifdef CONFIG_PAX_MEMORY_UDEREF
8516+ push %ss
8517+ pop %ds
8518+#endif
8519 GET_THREAD_INFO(%ebp)
8520 movl $-EFAULT,PT_EAX(%esp)
8521 jmp resume_userspace
017d2877 8522@@ -717,7 +775,13 @@ PTREGSCALL(vm86old)
2380c486 8523
017d2877
AM
8524 .macro FIXUP_ESPFIX_STACK
8525 /* since we are on a wrong stack, we cant make it a C code :( */
8526- PER_CPU(gdt_page, %ebx)
2380c486
JR
8527+#ifdef CONFIG_SMP
8528+ movl PER_CPU_VAR(cpu_number), %ebx;
8529+ shll $PAGE_SHIFT_asm, %ebx;
8530+ addl $cpu_gdt_table, %ebx;
8531+#else
8532+ movl $cpu_gdt_table, %ebx;
8533+#endif
017d2877
AM
8534 GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah)
8535 addl %esp, %eax
8536 pushl $__KERNEL_DS
8537@@ -1176,7 +1240,6 @@ return_to_handler:
2380c486
JR
8538 ret
8539 #endif
8540
8541-.section .rodata,"a"
8542 #include "syscall_table_32.S"
8543
8544 syscall_table_size=(.-sys_call_table)
017d2877
AM
8545@@ -1228,12 +1291,21 @@ error_code:
8546 movl %ecx, %fs
8547 UNWIND_ESPFIX_STACK
8548 GS_TO_REG %ecx
2380c486
JR
8549+
8550+#ifdef CONFIG_PAX_KERNEXEC
8551+ GET_CR0_INTO_EDX
8552+ movl %edx, %esi
8553+ orl $X86_CR0_WP, %edx
8554+ xorl %edx, %esi
8555+ SET_CR0_FROM_EDX
8556+#endif
8557+
017d2877 8558 movl PT_GS(%esp), %edi # get the function address
2380c486
JR
8559 movl PT_ORIG_EAX(%esp), %edx # get the error code
8560 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
017d2877
AM
8561 REG_TO_PTGS %ecx
8562 SET_KERNEL_GS %ecx
2380c486
JR
8563- movl $(__USER_DS), %ecx
8564+ movl $(__KERNEL_DS), %ecx
8565 movl %ecx, %ds
8566 movl %ecx, %es
8567 TRACE_IRQS_OFF
017d2877 8568@@ -1329,6 +1401,13 @@ nmi_stack_correct:
2380c486
JR
8569 xorl %edx,%edx # zero error code
8570 movl %esp,%eax # pt_regs pointer
8571 call do_nmi
8572+
8573+#ifdef CONFIG_PAX_KERNEXEC
8574+ GET_CR0_INTO_EDX
8575+ xorl %esi, %edx
8576+ SET_CR0_FROM_EDX
8577+#endif
8578+
8579 jmp restore_nocheck_notrace
8580 CFI_ENDPROC
8581
017d2877 8582@@ -1369,6 +1448,13 @@ nmi_espfix_stack:
2380c486
JR
8583 FIXUP_ESPFIX_STACK # %eax == %esp
8584 xorl %edx,%edx # zero error code
8585 call do_nmi
8586+
8587+#ifdef CONFIG_PAX_KERNEXEC
8588+ GET_CR0_INTO_EDX
8589+ xorl %esi, %edx
8590+ SET_CR0_FROM_EDX
8591+#endif
8592+
8593 RESTORE_REGS
8594 lss 12+4(%esp), %esp # back to espfix stack
8595 CFI_ADJUST_CFA_OFFSET -24
017d2877
AM
8596diff -urNp linux-2.6.30.4/arch/x86/kernel/entry_64.S linux-2.6.30.4/arch/x86/kernel/entry_64.S
8597--- linux-2.6.30.4/arch/x86/kernel/entry_64.S 2009-07-24 17:47:51.000000000 -0400
8598+++ linux-2.6.30.4/arch/x86/kernel/entry_64.S 2009-07-30 09:48:09.945662533 -0400
8599@@ -1073,7 +1073,8 @@ ENTRY(\sym)
2380c486
JR
8600 TRACE_IRQS_OFF
8601 movq %rsp,%rdi /* pt_regs pointer */
8602 xorl %esi,%esi /* no error code */
017d2877
AM
8603- PER_CPU(init_tss, %rbp)
8604+ imul $TSS_size, PER_CPU_VAR(cpu_number), %ebp
2380c486 8605+ lea init_tss(%rbp), %rbp
017d2877 8606 subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
2380c486 8607 call \do_sym
017d2877
AM
8608 addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
8609diff -urNp linux-2.6.30.4/arch/x86/kernel/ftrace.c linux-2.6.30.4/arch/x86/kernel/ftrace.c
8610--- linux-2.6.30.4/arch/x86/kernel/ftrace.c 2009-07-24 17:47:51.000000000 -0400
8611+++ linux-2.6.30.4/arch/x86/kernel/ftrace.c 2009-07-30 09:48:09.945662533 -0400
8612@@ -284,9 +284,9 @@ int ftrace_update_ftrace_func(ftrace_fun
2380c486
JR
8613 unsigned char old[MCOUNT_INSN_SIZE], *new;
8614 int ret;
8615
8616- memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
8617+ memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
8618 new = ftrace_call_replace(ip, (unsigned long)func);
8619- ret = ftrace_modify_code(ip, old, new);
8620+ ret = ftrace_modify_code(ktla_ktva(ip), old, new);
8621
8622 return ret;
8623 }
017d2877
AM
8624diff -urNp linux-2.6.30.4/arch/x86/kernel/head32.c linux-2.6.30.4/arch/x86/kernel/head32.c
8625--- linux-2.6.30.4/arch/x86/kernel/head32.c 2009-07-24 17:47:51.000000000 -0400
8626+++ linux-2.6.30.4/arch/x86/kernel/head32.c 2009-07-30 09:48:09.946846946 -0400
2380c486
JR
8627@@ -13,12 +13,13 @@
8628 #include <asm/e820.h>
8629 #include <asm/bios_ebda.h>
8630 #include <asm/trampoline.h>
8631+#include <asm/boot.h>
8632
8633 void __init i386_start_kernel(void)
8634 {
8635 reserve_trampoline_memory();
8636
017d2877
AM
8637- reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
8638+ reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&__bss_stop), "TEXT DATA BSS");
2380c486
JR
8639
8640 #ifdef CONFIG_BLK_DEV_INITRD
8641 /* Reserve INITRD */
017d2877
AM
8642diff -urNp linux-2.6.30.4/arch/x86/kernel/head_32.S linux-2.6.30.4/arch/x86/kernel/head_32.S
8643--- linux-2.6.30.4/arch/x86/kernel/head_32.S 2009-07-24 17:47:51.000000000 -0400
8644+++ linux-2.6.30.4/arch/x86/kernel/head_32.S 2009-07-30 19:56:23.400350396 -0400
8645@@ -20,6 +20,7 @@
2380c486
JR
8646 #include <asm/setup.h>
8647 #include <asm/processor-flags.h>
017d2877 8648 #include <asm/percpu.h>
2380c486
JR
8649+#include <asm/msr-index.h>
8650
8651 /* Physical address */
8652 #define pa(X) ((X) - __PAGE_OFFSET)
017d2877
AM
8653@@ -53,11 +54,7 @@
8654 * and small than max_low_pfn, otherwise will waste some page table entries
8655 */
2380c486
JR
8656
8657-#if PTRS_PER_PMD > 1
017d2877 8658-#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
2380c486 8659-#else
017d2877 8660-#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
2380c486 8661-#endif
017d2877 8662+#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PTE)
2380c486 8663
017d2877
AM
8664 /* Enough space to fit pagetables for the low memory linear map */
8665 MAPPING_BEYOND_END = \
8666@@ -74,6 +71,15 @@ INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_P
8667 RESERVE_BRK(pagetables, INIT_MAP_SIZE)
2380c486
JR
8668
8669 /*
8670+ * Real beginning of normal "text" segment
8671+ */
8672+ENTRY(stext)
8673+ENTRY(_stext)
8674+
8675+.section .text.startup,"ax",@progbits
8676+ ljmp $(__BOOT_CS),$phys_startup_32
8677+
8678+/*
8679 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
8680 * %esi points to the real-mode code as a 32-bit pointer.
8681 * CS and DS must be 4 GB flat segments, but we don't depend on
017d2877 8682@@ -81,6 +87,12 @@ RESERVE_BRK(pagetables, INIT_MAP_SIZE)
2380c486
JR
8683 * can.
8684 */
8685 .section .text.head,"ax",@progbits
8686+
8687+#ifdef CONFIG_PAX_KERNEXEC
8688+/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
8689+.fill 4096,1,0xcc
8690+#endif
8691+
8692 ENTRY(startup_32)
8693 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
8694 us to not reload segments */
017d2877 8695@@ -98,6 +110,56 @@ ENTRY(startup_32)
2380c486
JR
8696 movl %eax,%gs
8697 2:
8698
8699+ movl $pa(cpu_gdt_table),%edi
017d2877 8700+ movl $__per_cpu_load,%eax
2380c486
JR
8701+ movw %ax,__KERNEL_PERCPU + 2(%edi)
8702+ rorl $16,%eax
8703+ movb %al,__KERNEL_PERCPU + 4(%edi)
8704+ movb %ah,__KERNEL_PERCPU + 7(%edi)
017d2877
AM
8705+ movl $__per_cpu_end - 1,%eax
8706+ subl $__per_cpu_load,%eax
2380c486
JR
8707+ movw %ax,__KERNEL_PERCPU + 0(%edi)
8708+
8709+#ifdef CONFIG_PAX_MEMORY_UDEREF
8710+ /* check for VMware */
8711+ movl $0x564d5868,%eax
8712+ xorl %ebx,%ebx
8713+ movl $0xa,%ecx
8714+ movl $0x5658,%edx
8715+ in (%dx),%eax
8716+ cmpl $0x564d5868,%ebx
8717+ jz 2f
8718+
8719+ movl $NR_CPUS,%ecx
8720+ movl $pa(cpu_gdt_table),%edi
8721+1:
8722+ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
8723+ addl $PAGE_SIZE_asm,%edi
8724+ loop 1b
8725+2:
8726+#endif
8727+
8728+#ifdef CONFIG_PAX_KERNEXEC
8729+ movl $pa(boot_gdt),%edi
8730+ movl $KERNEL_TEXT_OFFSET,%eax
8731+ movw %ax,__BOOT_CS + 2(%edi)
8732+ rorl $16,%eax
8733+ movb %al,__BOOT_CS + 4(%edi)
8734+ movb %ah,__BOOT_CS + 7(%edi)
8735+ rorl $16,%eax
8736+
8737+ movl $NR_CPUS,%ecx
8738+ movl $pa(cpu_gdt_table),%edi
8739+1:
8740+ movw %ax,__KERNEL_CS + 2(%edi)
8741+ rorl $16,%eax
8742+ movb %al,__KERNEL_CS + 4(%edi)
8743+ movb %ah,__KERNEL_CS + 7(%edi)
8744+ rorl $16,%eax
8745+ addl $PAGE_SIZE_asm,%edi
8746+ loop 1b
8747+#endif
8748+
8749 /*
8750 * Clear BSS first so that there are no surprises...
8751 */
017d2877 8752@@ -141,9 +203,7 @@ ENTRY(startup_32)
2380c486
JR
8753 cmpl $num_subarch_entries, %eax
8754 jae bad_subarch
8755
8756- movl pa(subarch_entries)(,%eax,4), %eax
8757- subl $__PAGE_OFFSET, %eax
8758- jmp *%eax
8759+ jmp *pa(subarch_entries)(,%eax,4)
8760
8761 bad_subarch:
8762 WEAK(lguest_entry)
017d2877 8763@@ -155,9 +215,9 @@ WEAK(xen_entry)
2380c486
JR
8764 __INITDATA
8765
8766 subarch_entries:
8767- .long default_entry /* normal x86/PC */
8768- .long lguest_entry /* lguest hypervisor */
8769- .long xen_entry /* Xen hypervisor */
8770+ .long pa(default_entry) /* normal x86/PC */
8771+ .long pa(lguest_entry) /* lguest hypervisor */
8772+ .long pa(xen_entry) /* Xen hypervisor */
8773 num_subarch_entries = (. - subarch_entries) / 4
8774 .previous
8775 #endif /* CONFIG_PARAVIRT */
017d2877 8776@@ -218,8 +278,14 @@ default_entry:
2380c486
JR
8777 movl %eax, pa(max_pfn_mapped)
8778
8779 /* Do early initialization of the fixmap area */
8780- movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
8781- movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
017d2877
AM
8782+#ifdef CONFIG_COMPAT_VDSO
8783+ movl $pa(swapper_pg_fixmap0)+PDE_IDENT_ATTR+_PAGE_USER,pa(swapper_pg_pmd+0x1000*KPMDS-8)
8784+#else
8785+ movl $pa(swapper_pg_fixmap0)+PDE_IDENT_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
8786+#endif
8787+ movl $pa(swapper_pg_fixmap1)+PDE_IDENT_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-16)
8788+ movl $pa(swapper_pg_fixmap2)+PDE_IDENT_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-24)
8789+ movl $pa(swapper_pg_fixmap3)+PDE_IDENT_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-32)
2380c486
JR
8790 #else /* Not PAE */
8791
8792 page_pde_offset = (__PAGE_OFFSET >> 20);
017d2877 8793@@ -249,8 +315,14 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
2380c486
JR
8794 movl %eax, pa(max_pfn_mapped)
8795
8796 /* Do early initialization of the fixmap area */
8797- movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
8798- movl %eax,pa(swapper_pg_dir+0xffc)
017d2877
AM
8799+#ifdef CONFIG_COMPAT_VDSO
8800+ movl $pa(swapper_pg_fixmap0)+PDE_IDENT_ATTR+_PAGE_USER,pa(swapper_pg_dir+0xffc)
8801+#else
8802+ movl $pa(swapper_pg_fixmap0)+PDE_IDENT_ATTR,pa(swapper_pg_dir+0xffc)
8803+#endif
8804+ movl $pa(swapper_pg_fixmap1)+PDE_IDENT_ATTR,pa(swapper_pg_dir+0xff8)
8805+ movl $pa(swapper_pg_fixmap2)+PDE_IDENT_ATTR,pa(swapper_pg_dir+0xff4)
8806+ movl $pa(swapper_pg_fixmap3)+PDE_IDENT_ATTR,pa(swapper_pg_dir+0xff0)
2380c486
JR
8807 #endif
8808 jmp 3f
8809 /*
017d2877 8810@@ -314,13 +386,16 @@ ENTRY(startup_32_smp)
2380c486
JR
8811 jnc 6f
8812
8813 /* Setup EFER (Extended Feature Enable Register) */
8814- movl $0xc0000080, %ecx
8815+ movl $MSR_EFER, %ecx
8816 rdmsr
8817
8818 btsl $11, %eax
8819 /* Make changes effective */
8820 wrmsr
8821
8822+ btsl $_PAGE_BIT_NX-32,pa(__supported_pte_mask+4)
8823+ movl $1,pa(nx_enabled)
8824+
8825 6:
8826
8827 /*
017d2877 8828@@ -346,9 +421,7 @@ ENTRY(startup_32_smp)
2380c486
JR
8829
8830 #ifdef CONFIG_SMP
8831 cmpb $0, ready
8832- jz 1f /* Initial CPU cleans BSS */
8833- jmp checkCPUtype
8834-1:
8835+ jnz checkCPUtype /* Initial CPU cleans BSS */
8836 #endif /* CONFIG_SMP */
8837
8838 /*
017d2877 8839@@ -426,7 +499,7 @@ is386: movl $2,%ecx # set MP
2380c486
JR
8840 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
8841 movl %eax,%ss # after changing gdt.
017d2877 8842
2380c486 8843- movl $(__USER_DS),%eax # DS/ES contains default USER segment
017d2877 8844+ movl $(__KERNEL_DS),%eax # DS/ES contains default KERNEL segment
2380c486
JR
8845 movl %eax,%ds
8846 movl %eax,%es
8847
017d2877
AM
8848@@ -440,8 +513,9 @@ is386: movl $2,%ecx # set MP
8849 */
8850 cmpb $0,ready
8851 jne 1f
8852- movl $per_cpu__gdt_page,%eax
8853+ movl $cpu_gdt_table,%eax
8854 movl $per_cpu__stack_canary,%ecx
8855+ addl $__per_cpu_load,%ecx
8856 subl $20, %ecx
8857 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
8858 shrl $16, %ecx
8859@@ -460,10 +534,6 @@ is386: movl $2,%ecx # set MP
2380c486
JR
8860 #ifdef CONFIG_SMP
8861 movb ready, %cl
8862 movb $1, ready
8863- cmpb $0,%cl # the first CPU calls start_kernel
8864- je 1f
2380c486
JR
8865- movl (stack_start), %esp
8866-1:
8867 #endif /* CONFIG_SMP */
8868 jmp *(initial_code)
8869
017d2877 8870@@ -549,22 +619,22 @@ early_page_fault:
2380c486
JR
8871 jmp early_fault
8872
8873 early_fault:
8874- cld
8875 #ifdef CONFIG_PRINTK
017d2877 8876+ cmpl $1,%ss:early_recursion_flag
2380c486
JR
8877+ je hlt_loop
8878+ incl %ss:early_recursion_flag
8879+ cld
8880 pusha
8881 movl $(__KERNEL_DS),%eax
8882 movl %eax,%ds
8883 movl %eax,%es
8884- cmpl $2,early_recursion_flag
8885- je hlt_loop
8886- incl early_recursion_flag
8887 movl %cr2,%eax
8888 pushl %eax
8889 pushl %edx /* trapno */
017d2877 8890 pushl $fault_msg
2380c486 8891 call printk
017d2877 8892+; call dump_stack
2380c486 8893 #endif
017d2877 8894- call dump_stack
2380c486
JR
8895 hlt_loop:
8896 hlt
8897 jmp hlt_loop
017d2877 8898@@ -572,8 +642,11 @@ hlt_loop:
2380c486
JR
8899 /* This is the default interrupt "handler" :-) */
8900 ALIGN
8901 ignore_int:
8902- cld
8903 #ifdef CONFIG_PRINTK
8904+ cmpl $2,%ss:early_recursion_flag
8905+ je hlt_loop
8906+ incl %ss:early_recursion_flag
8907+ cld
8908 pushl %eax
8909 pushl %ecx
8910 pushl %edx
017d2877 8911@@ -582,9 +655,6 @@ ignore_int:
2380c486
JR
8912 movl $(__KERNEL_DS),%eax
8913 movl %eax,%ds
8914 movl %eax,%es
8915- cmpl $2,early_recursion_flag
8916- je hlt_loop
8917- incl early_recursion_flag
8918 pushl 16(%esp)
8919 pushl 24(%esp)
8920 pushl 32(%esp)
017d2877 8921@@ -608,37 +678,49 @@ ignore_int:
2380c486
JR
8922 ENTRY(initial_code)
8923 .long i386_start_kernel
8924
8925-.section .text
8926-/*
8927- * Real beginning of normal "text" segment
8928- */
8929-ENTRY(stext)
8930-ENTRY(_stext)
8931-
8932 /*
8933 * BSS section
8934 */
8935-.section ".bss.page_aligned","wa"
8936- .align PAGE_SIZE_asm
8937 #ifdef CONFIG_X86_PAE
8938+.section .swapper_pg_pmd,"a",@progbits
8939 swapper_pg_pmd:
8940 .fill 1024*KPMDS,4,0
8941 #else
8942+.section .swapper_pg_dir,"a",@progbits
8943 ENTRY(swapper_pg_dir)
8944 .fill 1024,4,0
8945 #endif
017d2877
AM
8946-swapper_pg_fixmap:
8947+
8948+ENTRY(swapper_pg_fixmap0)
8949+ .fill 1024,4,0
8950+
8951+ENTRY(swapper_pg_fixmap1)
8952+ .fill 1024,4,0
8953+
8954+ENTRY(swapper_pg_fixmap2)
8955+ .fill 1024,4,0
8956+
8957+ENTRY(swapper_pg_fixmap3)
2380c486
JR
8958 .fill 1024,4,0
8959+
8960+.section .empty_zero_page,"a",@progbits
8961 ENTRY(empty_zero_page)
8962 .fill 4096,1,0
017d2877
AM
8963
8964 /*
2380c486
JR
8965+ * The IDT has to be page-aligned to simplify the Pentium
8966+ * F0 0F bug workaround.. We have a special link segment
8967+ * for this.
8968+ */
8969+.section .idt,"a",@progbits
8970+ENTRY(idt_table)
8971+ .fill 256,8,0
8972+
017d2877 8973+/*
2380c486
JR
8974 * This starts the data section.
8975 */
2380c486
JR
8976 #ifdef CONFIG_X86_PAE
8977-.section ".data.page_aligned","wa"
8978- /* Page-aligned for the benefit of paravirt? */
8979- .align PAGE_SIZE_asm
8980+.section .swapper_pg_dir,"a",@progbits
8981 ENTRY(swapper_pg_dir)
8982 .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */
8983 # if KPMDS == 3
017d2877 8984@@ -661,11 +743,12 @@ ENTRY(swapper_pg_dir)
2380c486
JR
8985
8986 .data
8987 ENTRY(stack_start)
8988- .long init_thread_union+THREAD_SIZE
8989+ .long init_thread_union+THREAD_SIZE-8
8990 .long __BOOT_DS
8991
8992 ready: .byte 0
8993
8994+.section .rodata,"a",@progbits
8995 early_recursion_flag:
8996 .long 0
8997
017d2877 8998@@ -701,7 +784,7 @@ fault_msg:
2380c486
JR
8999 .word 0 # 32 bit align gdt_desc.address
9000 boot_gdt_descr:
9001 .word __BOOT_DS+7
9002- .long boot_gdt - __PAGE_OFFSET
9003+ .long pa(boot_gdt)
9004
9005 .word 0 # 32-bit align idt_desc.address
9006 idt_descr:
017d2877 9007@@ -712,7 +795,7 @@ idt_descr:
2380c486
JR
9008 .word 0 # 32 bit align gdt_desc.address
9009 ENTRY(early_gdt_descr)
9010 .word GDT_ENTRIES*8-1
9011- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
9012+ .long cpu_gdt_table /* Overwritten for secondary CPUs */
9013
9014 /*
9015 * The boot_gdt must mirror the equivalent in setup.S and is
017d2877 9016@@ -721,5 +804,59 @@ ENTRY(early_gdt_descr)
2380c486
JR
9017 .align L1_CACHE_BYTES
9018 ENTRY(boot_gdt)
9019 .fill GDT_ENTRY_BOOT_CS,8,0
9020- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
9021- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
9022+ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
9023+ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
9024+
9025+ .align PAGE_SIZE_asm
9026+ENTRY(cpu_gdt_table)
9027+ .rept NR_CPUS
9028+ .quad 0x0000000000000000 /* NULL descriptor */
9029+ .quad 0x0000000000000000 /* 0x0b reserved */
9030+ .quad 0x0000000000000000 /* 0x13 reserved */
9031+ .quad 0x0000000000000000 /* 0x1b reserved */
9032+ .quad 0x0000000000000000 /* 0x20 unused */
9033+ .quad 0x0000000000000000 /* 0x28 unused */
9034+ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
9035+ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
9036+ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
9037+ .quad 0x0000000000000000 /* 0x4b reserved */
9038+ .quad 0x0000000000000000 /* 0x53 reserved */
9039+ .quad 0x0000000000000000 /* 0x5b reserved */
9040+
9041+ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
9042+ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
9043+ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
9044+ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
9045+
9046+ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
9047+ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
9048+
9049+ /*
9050+ * Segments used for calling PnP BIOS have byte granularity.
9051+ * The code segments and data segments have fixed 64k limits,
9052+ * the transfer segment sizes are set at run time.
9053+ */
9054+ .quad 0x00409b000000ffff /* 0x90 32-bit code */
9055+ .quad 0x00009b000000ffff /* 0x98 16-bit code */
9056+ .quad 0x000093000000ffff /* 0xa0 16-bit data */
9057+ .quad 0x0000930000000000 /* 0xa8 16-bit data */
9058+ .quad 0x0000930000000000 /* 0xb0 16-bit data */
9059+
9060+ /*
9061+ * The APM segments have byte granularity and their bases
9062+ * are set at run time. All have 64k limits.
9063+ */
9064+ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
9065+ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
9066+ .quad 0x004093000000ffff /* 0xc8 APM DS data */
9067+
9068+ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
9069+ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
017d2877
AM
9070+ .quad 0x0040930000000018 /* 0xe0 - STACK_CANARY */
9071+ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_CS */
9072+ .quad 0x0000000000000000 /* 0xf0 - PCIBIOS_DS */
2380c486
JR
9073+ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
9074+
9075+ /* Be sure this is zeroed to avoid false validations in Xen */
9076+ .fill PAGE_SIZE_asm - GDT_SIZE,1,0
9077+ .endr
017d2877
AM
9078diff -urNp linux-2.6.30.4/arch/x86/kernel/head_64.S linux-2.6.30.4/arch/x86/kernel/head_64.S
9079--- linux-2.6.30.4/arch/x86/kernel/head_64.S 2009-07-24 17:47:51.000000000 -0400
9080+++ linux-2.6.30.4/arch/x86/kernel/head_64.S 2009-07-30 09:48:09.947450201 -0400
9081@@ -39,6 +39,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
2380c486
JR
9082 L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
9083 L4_START_KERNEL = pgd_index(__START_KERNEL_map)
9084 L3_START_KERNEL = pud_index(__START_KERNEL_map)
9085+L4_VMALLOC_START = pgd_index(VMALLOC_START)
9086+L3_VMALLOC_START = pud_index(VMALLOC_START)
9087+L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
9088+L3_VMEMMAP_START = pud_index(VMEMMAP_START)
9089
9090 .text
9091 .section .text.head
017d2877 9092@@ -86,35 +90,22 @@ startup_64:
2380c486
JR
9093 */
9094 addq %rbp, init_level4_pgt + 0(%rip)
9095 addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
9096+ addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
9097+ addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
9098 addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
9099
9100 addq %rbp, level3_ident_pgt + 0(%rip)
9101+ addq %rbp, level3_ident_pgt + 8(%rip)
9102+ addq %rbp, level3_ident_pgt + 16(%rip)
9103+ addq %rbp, level3_ident_pgt + 24(%rip)
9104
9105- addq %rbp, level3_kernel_pgt + (510*8)(%rip)
9106- addq %rbp, level3_kernel_pgt + (511*8)(%rip)
9107+ addq %rbp, level3_vmemmap_pgt + (L3_VMEMMAP_START*8)(%rip)
9108
9109- addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
9110+ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
9111+ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
9112
9113- /* Add an Identity mapping if I am above 1G */
9114- leaq _text(%rip), %rdi
9115- andq $PMD_PAGE_MASK, %rdi
9116-
9117- movq %rdi, %rax
9118- shrq $PUD_SHIFT, %rax
9119- andq $(PTRS_PER_PUD - 1), %rax
9120- jz ident_complete
9121-
9122- leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx
9123- leaq level3_ident_pgt(%rip), %rbx
9124- movq %rdx, 0(%rbx, %rax, 8)
9125-
9126- movq %rdi, %rax
9127- shrq $PMD_SHIFT, %rax
9128- andq $(PTRS_PER_PMD - 1), %rax
9129- leaq __PAGE_KERNEL_IDENT_LARGE_EXEC(%rdi), %rdx
9130- leaq level2_spare_pgt(%rip), %rbx
9131- movq %rdx, 0(%rbx, %rax, 8)
9132-ident_complete:
9133+ addq %rbp, level2_fixmap_pgt + (506*8)(%rip)
9134+ addq %rbp, level2_fixmap_pgt + (507*8)(%rip)
9135
9136 /*
9137 * Fixup the kernel text+data virtual addresses. Note that
017d2877 9138@@ -188,6 +179,10 @@ ENTRY(secondary_startup_64)
2380c486
JR
9139 btl $20,%edi /* No Execute supported? */
9140 jnc 1f
9141 btsl $_EFER_NX, %eax
9142+ leaq init_level4_pgt(%rip), %rdi
9143+ btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
9144+ btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
9145+ btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
9146 1: wrmsr /* Make changes effective */
9147
9148 /* Setup cr0 */
017d2877 9149@@ -263,16 +258,16 @@ ENTRY(secondary_startup_64)
2380c486 9150 .quad x86_64_start_kernel
017d2877
AM
9151 ENTRY(initial_gs)
9152 .quad INIT_PER_CPU_VAR(irq_stack_union)
2380c486
JR
9153- __FINITDATA
9154
9155 ENTRY(stack_start)
9156 .quad init_thread_union+THREAD_SIZE-8
9157 .word 0
9158+ __FINITDATA
9159
9160 bad_address:
9161 jmp bad_address
9162
9163- .section ".init.text","ax"
9164+ __INIT
9165 #ifdef CONFIG_EARLY_PRINTK
9166 .globl early_idt_handlers
9167 early_idt_handlers:
017d2877 9168@@ -317,18 +312,23 @@ ENTRY(early_idt_handler)
2380c486
JR
9169 #endif /* EARLY_PRINTK */
9170 1: hlt
9171 jmp 1b
9172+ .previous
9173
9174 #ifdef CONFIG_EARLY_PRINTK
9175+ __INITDATA
9176 early_recursion_flag:
9177 .long 0
9178+ .previous
9179
9180+ .section .rodata,"a",@progbits
9181 early_idt_msg:
9182 .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
9183 early_idt_ripmsg:
9184 .asciz "RIP %s\n"
9185-#endif /* CONFIG_EARLY_PRINTK */
9186 .previous
9187+#endif /* CONFIG_EARLY_PRINTK */
9188
9189+ .section .rodata,"a",@progbits
2380c486 9190 #define NEXT_PAGE(name) \
017d2877
AM
9191 .balign PAGE_SIZE; \
9192 ENTRY(name)
9193@@ -351,13 +351,27 @@ NEXT_PAGE(init_level4_pgt)
2380c486
JR
9194 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
9195 .org init_level4_pgt + L4_PAGE_OFFSET*8, 0
9196 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
9197+ .org init_level4_pgt + L4_VMALLOC_START*8, 0
9198+ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
9199+ .org init_level4_pgt + L4_VMEMMAP_START*8, 0
9200+ .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
9201 .org init_level4_pgt + L4_START_KERNEL*8, 0
9202 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
9203 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
9204
9205 NEXT_PAGE(level3_ident_pgt)
9206 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
9207- .fill 511,8,0
9208+ .quad level2_ident_pgt + PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
9209+ .quad level2_ident_pgt + 2*PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
9210+ .quad level2_ident_pgt + 3*PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
9211+ .fill 508,8,0
9212+
9213+NEXT_PAGE(level3_vmalloc_pgt)
9214+ .fill 512,8,0
9215+
9216+NEXT_PAGE(level3_vmemmap_pgt)
9217+ .fill L3_VMEMMAP_START,8,0
9218+ .quad level2_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
9219
9220 NEXT_PAGE(level3_kernel_pgt)
9221 .fill L3_START_KERNEL,8,0
017d2877 9222@@ -365,20 +379,27 @@ NEXT_PAGE(level3_kernel_pgt)
2380c486
JR
9223 .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
9224 .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
9225
9226+NEXT_PAGE(level2_vmemmap_pgt)
9227+ .fill 512,8,0
9228+
9229 NEXT_PAGE(level2_fixmap_pgt)
9230 .fill 506,8,0
9231 .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
9232- /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
9233- .fill 5,8,0
9234+ .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
9235+ /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
9236+ .fill 4,8,0
9237
9238 NEXT_PAGE(level1_fixmap_pgt)
9239 .fill 512,8,0
9240
9241-NEXT_PAGE(level2_ident_pgt)
9242- /* Since I easily can, map the first 1G.
9243+NEXT_PAGE(level1_vsyscall_pgt)
9244+ .fill 512,8,0
9245+
9246+ /* Since I easily can, map the first 4G.
9247 * Don't set NX because code runs from these pages.
9248 */
9249- PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
9250+NEXT_PAGE(level2_ident_pgt)
9251+ PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, 4*PTRS_PER_PMD)
9252
9253 NEXT_PAGE(level2_kernel_pgt)
9254 /*
017d2877 9255@@ -391,33 +412,49 @@ NEXT_PAGE(level2_kernel_pgt)
2380c486
JR
9256 * If you want to increase this then increase MODULES_VADDR
9257 * too.)
9258 */
9259- PMDS(0, __PAGE_KERNEL_LARGE_EXEC,
9260- KERNEL_IMAGE_SIZE/PMD_SIZE)
9261-
9262-NEXT_PAGE(level2_spare_pgt)
9263- .fill 512, 8, 0
9264+ PMDS(0, __PAGE_KERNEL_LARGE_EXEC, KERNEL_IMAGE_SIZE/PMD_SIZE)
9265
9266 #undef PMDS
9267 #undef NEXT_PAGE
9268
9269- .data
9270+ .align PAGE_SIZE
9271+ENTRY(cpu_gdt_table)
9272+ .rept NR_CPUS
9273+ .quad 0x0000000000000000 /* NULL descriptor */
9274+ .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
9275+ .quad 0x00af9b000000ffff /* __KERNEL_CS */
9276+ .quad 0x00cf93000000ffff /* __KERNEL_DS */
9277+ .quad 0x00cffb000000ffff /* __USER32_CS */
9278+ .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */
9279+ .quad 0x00affb000000ffff /* __USER_CS */
9280+ .quad 0x0 /* unused */
9281+ .quad 0,0 /* TSS */
9282+ .quad 0,0 /* LDT */
9283+ .quad 0,0,0 /* three TLS descriptors */
9284+ .quad 0x0000f40000000000 /* node/CPU stored in limit */
9285+ /* asm/segment.h:GDT_ENTRIES must match this */
9286+
9287+ /* zero the remaining page */
9288+ .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
9289+ .endr
9290+
9291 .align 16
9292 .globl early_gdt_descr
9293 early_gdt_descr:
9294 .word GDT_ENTRIES*8-1
017d2877
AM
9295 early_gdt_descr_base:
9296- .quad INIT_PER_CPU_VAR(gdt_page)
2380c486
JR
9297+ .quad cpu_gdt_table
9298
9299 ENTRY(phys_base)
9300 /* This must match the first entry in level2_kernel_pgt */
9301 .quad 0x0000000000000000
9302
9303 #include "../../x86/xen/xen-head.S"
9304-
9305- .section .bss, "aw", @nobits
9306+
9307+ .section .rodata,"a",@progbits
9308 .align L1_CACHE_BYTES
9309 ENTRY(idt_table)
017d2877
AM
9310- .skip IDT_ENTRIES * 16
9311+ .fill 256,16,0
2380c486
JR
9312
9313 .section .bss.page_aligned, "aw", @nobits
9314 .align PAGE_SIZE
017d2877
AM
9315diff -urNp linux-2.6.30.4/arch/x86/kernel/i386_ksyms_32.c linux-2.6.30.4/arch/x86/kernel/i386_ksyms_32.c
9316--- linux-2.6.30.4/arch/x86/kernel/i386_ksyms_32.c 2009-07-24 17:47:51.000000000 -0400
9317+++ linux-2.6.30.4/arch/x86/kernel/i386_ksyms_32.c 2009-07-30 09:48:09.948476455 -0400
2380c486
JR
9318@@ -10,8 +10,12 @@
9319 EXPORT_SYMBOL(mcount);
9320 #endif
9321
9322+EXPORT_SYMBOL_GPL(cpu_gdt_table);
9323+
9324 /* Networking helper routines. */
9325 EXPORT_SYMBOL(csum_partial_copy_generic);
9326+EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
9327+EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
9328
9329 EXPORT_SYMBOL(__get_user_1);
9330 EXPORT_SYMBOL(__get_user_2);
9331@@ -26,3 +30,7 @@ EXPORT_SYMBOL(strstr);
9332
9333 EXPORT_SYMBOL(csum_partial);
9334 EXPORT_SYMBOL(empty_zero_page);
9335+
9336+#ifdef CONFIG_PAX_KERNEXEC
9337+EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
9338+#endif
017d2877
AM
9339diff -urNp linux-2.6.30.4/arch/x86/kernel/init_task.c linux-2.6.30.4/arch/x86/kernel/init_task.c
9340--- linux-2.6.30.4/arch/x86/kernel/init_task.c 2009-07-24 17:47:51.000000000 -0400
9341+++ linux-2.6.30.4/arch/x86/kernel/init_task.c 2009-07-30 09:48:09.948476455 -0400
2380c486
JR
9342@@ -40,5 +40,5 @@ EXPORT_SYMBOL(init_task);
9343 * section. Since TSS's are completely CPU-local, we want them
9344 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
9345 */
9346-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
9347-
9348+struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
9349+EXPORT_SYMBOL(init_tss);
017d2877
AM
9350diff -urNp linux-2.6.30.4/arch/x86/kernel/ioport.c linux-2.6.30.4/arch/x86/kernel/ioport.c
9351--- linux-2.6.30.4/arch/x86/kernel/ioport.c 2009-07-24 17:47:51.000000000 -0400
9352+++ linux-2.6.30.4/arch/x86/kernel/ioport.c 2009-07-30 11:10:48.918448854 -0400
2380c486
JR
9353@@ -6,6 +6,7 @@
9354 #include <linux/sched.h>
9355 #include <linux/kernel.h>
9356 #include <linux/capability.h>
9357+#include <linux/security.h>
9358 #include <linux/errno.h>
9359 #include <linux/types.h>
9360 #include <linux/ioport.h>
9361@@ -41,6 +42,12 @@ asmlinkage long sys_ioperm(unsigned long
9362
9363 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
9364 return -EINVAL;
9365+#ifdef CONFIG_GRKERNSEC_IO
9366+ if (turn_on) {
9367+ gr_handle_ioperm();
9368+ return -EPERM;
9369+ }
9370+#endif
9371 if (turn_on && !capable(CAP_SYS_RAWIO))
9372 return -EPERM;
9373
9374@@ -67,7 +74,7 @@ asmlinkage long sys_ioperm(unsigned long
9375 * because the ->io_bitmap_max value must match the bitmap
9376 * contents:
9377 */
9378- tss = &per_cpu(init_tss, get_cpu());
9379+ tss = init_tss + get_cpu();
9380
9381 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
9382
017d2877 9383@@ -111,8 +118,13 @@ static int do_iopl(unsigned int level, s
2380c486
JR
9384 return -EINVAL;
9385 /* Trying to gain more privileges? */
9386 if (level > old) {
9387+#ifdef CONFIG_GRKERNSEC_IO
9388+ gr_handle_iopl();
9389+ return -EPERM;
9390+#else
9391 if (!capable(CAP_SYS_RAWIO))
9392 return -EPERM;
9393+#endif
9394 }
9395 regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
9396
017d2877
AM
9397diff -urNp linux-2.6.30.4/arch/x86/kernel/irq_32.c linux-2.6.30.4/arch/x86/kernel/irq_32.c
9398--- linux-2.6.30.4/arch/x86/kernel/irq_32.c 2009-07-24 17:47:51.000000000 -0400
9399+++ linux-2.6.30.4/arch/x86/kernel/irq_32.c 2009-07-30 09:48:09.948476455 -0400
9400@@ -94,7 +94,7 @@ execute_on_irq_stack(int overflow, struc
2380c486
JR
9401 return 0;
9402
9403 /* build the stack frame on the IRQ stack */
9404- isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
9405+ isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
9406 irqctx->tinfo.task = curctx->tinfo.task;
9407 irqctx->tinfo.previous_esp = current_stack_pointer;
9408
017d2877 9409@@ -175,7 +175,7 @@ asmlinkage void do_softirq(void)
2380c486
JR
9410 irqctx->tinfo.previous_esp = current_stack_pointer;
9411
9412 /* build the stack frame on the softirq stack */
9413- isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
9414+ isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
9415
9416 call_on_stack(__do_softirq, isp);
9417 /*
017d2877
AM
9418diff -urNp linux-2.6.30.4/arch/x86/kernel/kprobes.c linux-2.6.30.4/arch/x86/kernel/kprobes.c
9419--- linux-2.6.30.4/arch/x86/kernel/kprobes.c 2009-07-24 17:47:51.000000000 -0400
9420+++ linux-2.6.30.4/arch/x86/kernel/kprobes.c 2009-07-30 09:48:09.948476455 -0400
2380c486
JR
9421@@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
9422 char op;
9423 s32 raddr;
9424 } __attribute__((packed)) * jop;
9425- jop = (struct __arch_jmp_op *)from;
9426+
9427+#ifdef CONFIG_PAX_KERNEXEC
9428+ unsigned long cr0;
9429+#endif
9430+
9431+ jop = (struct __arch_jmp_op *)(ktla_ktva(from));
9432+
9433+#ifdef CONFIG_PAX_KERNEXEC
9434+ pax_open_kernel(cr0);
9435+#endif
9436+
9437 jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
9438 jop->op = RELATIVEJUMP_INSTRUCTION;
9439+
9440+#ifdef CONFIG_PAX_KERNEXEC
9441+ pax_close_kernel(cr0);
9442+#endif
9443+
9444 }
9445
9446 /*
9447@@ -345,16 +360,29 @@ static void __kprobes fix_riprel(struct
9448
9449 static void __kprobes arch_copy_kprobe(struct kprobe *p)
9450 {
9451- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
9452+
9453+#ifdef CONFIG_PAX_KERNEXEC
9454+ unsigned long cr0;
9455+#endif
9456+
9457+#ifdef CONFIG_PAX_KERNEXEC
9458+ pax_open_kernel(cr0);
9459+#endif
9460+
9461+ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
9462+
9463+#ifdef CONFIG_PAX_KERNEXEC
9464+ pax_close_kernel(cr0);
9465+#endif
9466
9467 fix_riprel(p);
9468
9469- if (can_boost(p->addr))
9470+ if (can_boost(ktla_ktva(p->addr)))
9471 p->ainsn.boostable = 0;
9472 else
9473 p->ainsn.boostable = -1;
9474
9475- p->opcode = *p->addr;
9476+ p->opcode = *(ktla_ktva(p->addr));
9477 }
9478
9479 int __kprobes arch_prepare_kprobe(struct kprobe *p)
9480@@ -432,7 +460,7 @@ static void __kprobes prepare_singlestep
9481 if (p->opcode == BREAKPOINT_INSTRUCTION)
9482 regs->ip = (unsigned long)p->addr;
9483 else
9484- regs->ip = (unsigned long)p->ainsn.insn;
9485+ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
9486 }
9487
9488 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
9489@@ -453,7 +481,7 @@ static void __kprobes setup_singlestep(s
9490 if (p->ainsn.boostable == 1 && !p->post_handler) {
9491 /* Boost up -- we can execute copied instructions directly */
9492 reset_current_kprobe();
9493- regs->ip = (unsigned long)p->ainsn.insn;
9494+ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
9495 preempt_enable_no_resched();
9496 return;
9497 }
9498@@ -523,7 +551,7 @@ static int __kprobes kprobe_handler(stru
9499 struct kprobe_ctlblk *kcb;
9500
9501 addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
9502- if (*addr != BREAKPOINT_INSTRUCTION) {
9503+ if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) {
9504 /*
9505 * The breakpoint instruction was removed right
9506 * after we hit it. Another cpu has removed
017d2877 9507@@ -775,7 +803,7 @@ static void __kprobes resume_execution(s
2380c486
JR
9508 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
9509 {
9510 unsigned long *tos = stack_addr(regs);
9511- unsigned long copy_ip = (unsigned long)p->ainsn.insn;
9512+ unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
9513 unsigned long orig_ip = (unsigned long)p->addr;
9514 kprobe_opcode_t *insn = p->ainsn.insn;
9515
017d2877 9516@@ -958,7 +986,7 @@ int __kprobes kprobe_exceptions_notify(s
2380c486
JR
9517 struct die_args *args = data;
9518 int ret = NOTIFY_DONE;
9519
9520- if (args->regs && user_mode_vm(args->regs))
9521+ if (args->regs && user_mode(args->regs))
9522 return ret;
9523
9524 switch (val) {
017d2877
AM
9525diff -urNp linux-2.6.30.4/arch/x86/kernel/ldt.c linux-2.6.30.4/arch/x86/kernel/ldt.c
9526--- linux-2.6.30.4/arch/x86/kernel/ldt.c 2009-07-24 17:47:51.000000000 -0400
9527+++ linux-2.6.30.4/arch/x86/kernel/ldt.c 2009-07-30 09:48:09.950015875 -0400
2380c486
JR
9528@@ -66,13 +66,13 @@ static int alloc_ldt(mm_context_t *pc, i
9529 if (reload) {
9530 #ifdef CONFIG_SMP
9531 preempt_disable();
9532- load_LDT(pc);
9533+ load_LDT_nolock(pc);
9534 if (!cpus_equal(current->mm->cpu_vm_mask,
9535 cpumask_of_cpu(smp_processor_id())))
9536 smp_call_function(flush_ldt, current->mm, 1);
9537 preempt_enable();
9538 #else
9539- load_LDT(pc);
9540+ load_LDT_nolock(pc);
9541 #endif
9542 }
9543 if (oldsize) {
9544@@ -94,7 +94,7 @@ static inline int copy_ldt(mm_context_t
9545 return err;
9546
9547 for (i = 0; i < old->size; i++)
9548- write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);
9549+ write_ldt_entry(new->ldt, i, old->ldt + i);
9550 return 0;
9551 }
9552
9553@@ -115,6 +115,24 @@ int init_new_context(struct task_struct
9554 retval = copy_ldt(&mm->context, &old_mm->context);
9555 mutex_unlock(&old_mm->context.lock);
9556 }
9557+
9558+ if (tsk == current) {
9559+ mm->context.vdso = ~0UL;
9560+
9561+#ifdef CONFIG_X86_32
9562+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
9563+ mm->context.user_cs_base = 0UL;
9564+ mm->context.user_cs_limit = ~0UL;
9565+
9566+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
9567+ cpus_clear(mm->context.cpu_user_cs_mask);
9568+#endif
9569+
9570+#endif
9571+#endif
9572+
9573+ }
9574+
9575 return retval;
9576 }
9577
9578@@ -229,6 +247,13 @@ static int write_ldt(void __user *ptr, u
9579 }
9580 }
9581
9582+#ifdef CONFIG_PAX_SEGMEXEC
9583+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
9584+ error = -EINVAL;
9585+ goto out_unlock;
9586+ }
9587+#endif
9588+
9589 fill_ldt(&ldt, &ldt_info);
9590 if (oldmode)
9591 ldt.avl = 0;
017d2877
AM
9592diff -urNp linux-2.6.30.4/arch/x86/kernel/machine_kexec_32.c linux-2.6.30.4/arch/x86/kernel/machine_kexec_32.c
9593--- linux-2.6.30.4/arch/x86/kernel/machine_kexec_32.c 2009-07-24 17:47:51.000000000 -0400
9594+++ linux-2.6.30.4/arch/x86/kernel/machine_kexec_32.c 2009-07-30 09:48:09.950015875 -0400
2380c486
JR
9595@@ -26,7 +26,7 @@
9596 #include <asm/system.h>
9597 #include <asm/cacheflush.h>
9598
9599-static void set_idt(void *newidt, __u16 limit)
9600+static void set_idt(struct desc_struct *newidt, __u16 limit)
9601 {
9602 struct desc_ptr curidt;
9603
9604@@ -38,7 +38,7 @@ static void set_idt(void *newidt, __u16
9605 }
9606
9607
9608-static void set_gdt(void *newgdt, __u16 limit)
9609+static void set_gdt(struct desc_struct *newgdt, __u16 limit)
9610 {
9611 struct desc_ptr curgdt;
9612
017d2877 9613@@ -217,7 +217,7 @@ void machine_kexec(struct kimage *image)
2380c486
JR
9614 }
9615
9616 control_page = page_address(image->control_code_page);
9617- memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
9618+ memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
9619
9620 relocate_kernel_ptr = control_page;
9621 page_list[PA_CONTROL_PAGE] = __pa(control_page);
017d2877
AM
9622diff -urNp linux-2.6.30.4/arch/x86/kernel/module_32.c linux-2.6.30.4/arch/x86/kernel/module_32.c
9623--- linux-2.6.30.4/arch/x86/kernel/module_32.c 2009-07-24 17:47:51.000000000 -0400
9624+++ linux-2.6.30.4/arch/x86/kernel/module_32.c 2009-07-30 09:48:09.950015875 -0400
2380c486
JR
9625@@ -23,6 +23,9 @@
9626 #include <linux/kernel.h>
9627 #include <linux/bug.h>
9628
9629+#include <asm/desc.h>
9630+#include <asm/pgtable.h>
9631+
9632 #if 0
9633 #define DEBUGP printk
9634 #else
9635@@ -33,9 +36,31 @@ void *module_alloc(unsigned long size)
9636 {
9637 if (size == 0)
9638 return NULL;
9639+
9640+#ifdef CONFIG_PAX_KERNEXEC
9641+ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
9642+#else
9643 return vmalloc_exec(size);
9644+#endif
9645+
9646 }
9647
9648+#ifdef CONFIG_PAX_KERNEXEC
9649+void *module_alloc_exec(unsigned long size)
9650+{
9651+ struct vm_struct *area;
9652+
9653+ if (size == 0)
9654+ return NULL;
9655+
9656+ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
9657+ if (area)
9658+ return area->addr;
9659+
9660+ return NULL;
9661+}
9662+EXPORT_SYMBOL(module_alloc_exec);
9663+#endif
9664
9665 /* Free memory returned from module_alloc */
9666 void module_free(struct module *mod, void *module_region)
9667@@ -45,6 +70,45 @@ void module_free(struct module *mod, voi
017d2877 9668 table entries. */
2380c486
JR
9669 }
9670
9671+#ifdef CONFIG_PAX_KERNEXEC
9672+void module_free_exec(struct module *mod, void *module_region)
9673+{
9674+ struct vm_struct **p, *tmp;
9675+
9676+ if (!module_region)
9677+ return;
9678+
9679+ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
9680+ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
9681+ WARN_ON(1);
9682+ return;
9683+ }
9684+
9685+ write_lock(&vmlist_lock);
9686+ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
9687+ if (tmp->addr == module_region)
9688+ break;
9689+
9690+ if (tmp) {
9691+ unsigned long cr0;
9692+
9693+ pax_open_kernel(cr0);
9694+ memset(tmp->addr, 0xCC, tmp->size);
9695+ pax_close_kernel(cr0);
9696+
9697+ *p = tmp->next;
9698+ kfree(tmp);
9699+ }
9700+ write_unlock(&vmlist_lock);
9701+
9702+ if (!tmp) {
9703+ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
9704+ module_region);
9705+ WARN_ON(1);
9706+ }
9707+}
9708+#endif
9709+
9710 /* We don't need anything special. */
9711 int module_frob_arch_sections(Elf_Ehdr *hdr,
9712 Elf_Shdr *sechdrs,
9713@@ -63,14 +127,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
9714 unsigned int i;
9715 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
9716 Elf32_Sym *sym;
9717- uint32_t *location;
9718+ uint32_t *plocation, location;
9719+
9720+#ifdef CONFIG_PAX_KERNEXEC
9721+ unsigned long cr0;
9722+#endif
9723
9724 DEBUGP("Applying relocate section %u to %u\n", relsec,
9725 sechdrs[relsec].sh_info);
9726 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
9727 /* This is where to make the change */
9728- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
9729- + rel[i].r_offset;
9730+ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
9731+ location = (uint32_t)plocation;
9732+ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
9733+ plocation = ktla_ktva((void *)plocation);
9734 /* This is the symbol it is referring to. Note that all
9735 undefined symbols have been resolved. */
9736 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
9737@@ -78,12 +148,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
9738
9739 switch (ELF32_R_TYPE(rel[i].r_info)) {
9740 case R_386_32:
9741+
9742+#ifdef CONFIG_PAX_KERNEXEC
9743+ pax_open_kernel(cr0);
9744+#endif
9745+
9746 /* We add the value into the location given */
9747- *location += sym->st_value;
9748+ *plocation += sym->st_value;
9749+
9750+#ifdef CONFIG_PAX_KERNEXEC
9751+ pax_close_kernel(cr0);
9752+#endif
9753+
9754 break;
9755 case R_386_PC32:
9756+
9757+#ifdef CONFIG_PAX_KERNEXEC
9758+ pax_open_kernel(cr0);
9759+#endif
9760+
9761 /* Add the value, subtract its postition */
9762- *location += sym->st_value - (uint32_t)location;
9763+ *plocation += sym->st_value - location;
9764+
9765+#ifdef CONFIG_PAX_KERNEXEC
9766+ pax_close_kernel(cr0);
9767+#endif
9768+
9769 break;
9770 default:
9771 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
017d2877
AM
9772diff -urNp linux-2.6.30.4/arch/x86/kernel/module_64.c linux-2.6.30.4/arch/x86/kernel/module_64.c
9773--- linux-2.6.30.4/arch/x86/kernel/module_64.c 2009-07-24 17:47:51.000000000 -0400
9774+++ linux-2.6.30.4/arch/x86/kernel/module_64.c 2009-07-30 09:48:09.950015875 -0400
2380c486 9775@@ -40,7 +40,7 @@ void module_free(struct module *mod, voi
017d2877 9776 table entries. */
2380c486
JR
9777 }
9778
9779-void *module_alloc(unsigned long size)
9780+static void *__module_alloc(unsigned long size, pgprot_t prot)
9781 {
9782 struct vm_struct *area;
9783
9784@@ -54,8 +54,31 @@ void *module_alloc(unsigned long size)
9785 if (!area)
9786 return NULL;
9787
9788- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
9789+ return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
9790+}
9791+
9792+#ifdef CONFIG_PAX_KERNEXEC
9793+void *module_alloc(unsigned long size)
9794+{
9795+ return __module_alloc(size, PAGE_KERNEL);
9796+}
9797+
9798+void module_free_exec(struct module *mod, void *module_region)
9799+{
9800+ module_free(mod, module_region);
9801+}
9802+
9803+void *module_alloc_exec(unsigned long size)
9804+{
9805+ return __module_alloc(size, PAGE_KERNEL_RX);
9806 }
9807+#else
9808+void *module_alloc(unsigned long size)
9809+{
9810+ return __module_alloc(size, PAGE_KERNEL_EXEC);
9811+}
9812+#endif
9813+
9814 #endif
9815
9816 /* We don't need anything special. */
017d2877 9817@@ -79,6 +102,10 @@ int apply_relocate_add(Elf64_Shdr *sechd
2380c486 9818 void *loc;
017d2877
AM
9819 u64 val;
9820
2380c486
JR
9821+#ifdef CONFIG_PAX_KERNEXEC
9822+ unsigned long cr0;
9823+#endif
017d2877 9824+
2380c486
JR
9825 DEBUGP("Applying relocate section %u to %u\n", relsec,
9826 sechdrs[relsec].sh_info);
017d2877 9827 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
2380c486
JR
9828@@ -101,21 +128,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
9829 case R_X86_64_NONE:
9830 break;
9831 case R_X86_64_64:
9832+
9833+#ifdef CONFIG_PAX_KERNEXEC
9834+ pax_open_kernel(cr0);
9835+#endif
9836+
9837 *(u64 *)loc = val;
9838+
9839+#ifdef CONFIG_PAX_KERNEXEC
9840+ pax_close_kernel(cr0);
9841+#endif
9842+
9843 break;
9844 case R_X86_64_32:
9845+
9846+#ifdef CONFIG_PAX_KERNEXEC
9847+ pax_open_kernel(cr0);
9848+#endif
9849+
9850 *(u32 *)loc = val;
9851+
9852+#ifdef CONFIG_PAX_KERNEXEC
9853+ pax_close_kernel(cr0);
9854+#endif
9855+
9856 if (val != *(u32 *)loc)
9857 goto overflow;
9858 break;
9859 case R_X86_64_32S:
9860+
9861+#ifdef CONFIG_PAX_KERNEXEC
9862+ pax_open_kernel(cr0);
9863+#endif
9864+
9865 *(s32 *)loc = val;
9866+
9867+#ifdef CONFIG_PAX_KERNEXEC
9868+ pax_close_kernel(cr0);
9869+#endif
9870+
9871 if ((s64)val != *(s32 *)loc)
9872 goto overflow;
9873 break;
017d2877 9874 case R_X86_64_PC32:
2380c486
JR
9875 val -= (u64)loc;
9876+
9877+#ifdef CONFIG_PAX_KERNEXEC
9878+ pax_open_kernel(cr0);
9879+#endif
9880+
9881 *(u32 *)loc = val;
9882+
9883+#ifdef CONFIG_PAX_KERNEXEC
9884+ pax_close_kernel(cr0);
9885+#endif
9886+
9887 #if 0
9888 if ((s64)val != *(s32 *)loc)
017d2877
AM
9889 goto overflow;
9890diff -urNp linux-2.6.30.4/arch/x86/kernel/paravirt.c linux-2.6.30.4/arch/x86/kernel/paravirt.c
9891--- linux-2.6.30.4/arch/x86/kernel/paravirt.c 2009-07-24 17:47:51.000000000 -0400
9892+++ linux-2.6.30.4/arch/x86/kernel/paravirt.c 2009-07-30 09:48:09.950702241 -0400
9893@@ -54,7 +54,7 @@ u64 _paravirt_ident_64(u64 x)
9894 return x;
2380c486
JR
9895 }
9896
9897-static void __init default_banner(void)
9898+static void default_banner(void)
9899 {
9900 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
9901 pv_info.name);
017d2877 9902@@ -183,7 +183,7 @@ unsigned paravirt_patch_insns(void *insn
2380c486
JR
9903 if (insn_len > len || start == NULL)
9904 insn_len = len;
9905 else
9906- memcpy(insnbuf, start, insn_len);
9907+ memcpy(insnbuf, ktla_ktva(start), insn_len);
9908
9909 return insn_len;
9910 }
017d2877 9911@@ -313,21 +313,21 @@ void arch_flush_lazy_cpu_mode(void)
2380c486
JR
9912 preempt_enable();
9913 }
9914
9915-struct pv_info pv_info = {
9916+struct pv_info pv_info __read_only = {
9917 .name = "bare hardware",
9918 .paravirt_enabled = 0,
9919 .kernel_rpl = 0,
9920 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
9921 };
9922
9923-struct pv_init_ops pv_init_ops = {
9924+struct pv_init_ops pv_init_ops __read_only = {
9925 .patch = native_patch,
9926 .banner = default_banner,
9927 .arch_setup = paravirt_nop,
9928 .memory_setup = machine_specific_memory_setup,
9929 };
9930
9931-struct pv_time_ops pv_time_ops = {
9932+struct pv_time_ops pv_time_ops __read_only = {
9933 .time_init = hpet_time_init,
9934 .get_wallclock = native_get_wallclock,
9935 .set_wallclock = native_set_wallclock,
017d2877 9936@@ -335,7 +335,7 @@ struct pv_time_ops pv_time_ops = {
2380c486
JR
9937 .get_tsc_khz = native_calibrate_tsc,
9938 };
9939
9940-struct pv_irq_ops pv_irq_ops = {
9941+struct pv_irq_ops pv_irq_ops __read_only = {
9942 .init_IRQ = native_init_IRQ,
017d2877
AM
9943 .save_fl = __PV_IS_CALLEE_SAVE(native_save_fl),
9944 .restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl),
9945@@ -348,7 +348,7 @@ struct pv_irq_ops pv_irq_ops = {
2380c486
JR
9946 #endif
9947 };
9948
9949-struct pv_cpu_ops pv_cpu_ops = {
9950+struct pv_cpu_ops pv_cpu_ops __read_only = {
9951 .cpuid = native_cpuid,
9952 .get_debugreg = native_get_debugreg,
9953 .set_debugreg = native_set_debugreg,
017d2877 9954@@ -410,7 +410,7 @@ struct pv_cpu_ops pv_cpu_ops = {
2380c486
JR
9955 },
9956 };
9957
9958-struct pv_apic_ops pv_apic_ops = {
9959+struct pv_apic_ops pv_apic_ops __read_only = {
9960 #ifdef CONFIG_X86_LOCAL_APIC
9961 .setup_boot_clock = setup_boot_APIC_clock,
9962 .setup_secondary_clock = setup_secondary_APIC_clock,
017d2877
AM
9963@@ -426,7 +426,7 @@ struct pv_apic_ops pv_apic_ops = {
9964 #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64)
2380c486 9965 #endif
2380c486
JR
9966
9967-struct pv_mmu_ops pv_mmu_ops = {
9968+struct pv_mmu_ops pv_mmu_ops __read_only = {
9969 #ifndef CONFIG_X86_64
9970 .pagetable_setup_start = native_pagetable_setup_start,
9971 .pagetable_setup_done = native_pagetable_setup_done,
017d2877
AM
9972diff -urNp linux-2.6.30.4/arch/x86/kernel/paravirt-spinlocks.c linux-2.6.30.4/arch/x86/kernel/paravirt-spinlocks.c
9973--- linux-2.6.30.4/arch/x86/kernel/paravirt-spinlocks.c 2009-07-24 17:47:51.000000000 -0400
9974+++ linux-2.6.30.4/arch/x86/kernel/paravirt-spinlocks.c 2009-07-30 09:48:09.950702241 -0400
2380c486
JR
9975@@ -13,7 +13,7 @@ default_spin_lock_flags(raw_spinlock_t *
9976 __raw_spin_lock(lock);
9977 }
9978
9979-struct pv_lock_ops pv_lock_ops = {
9980+struct pv_lock_ops pv_lock_ops __read_only = {
9981 #ifdef CONFIG_SMP
9982 .spin_is_locked = __ticket_spin_is_locked,
9983 .spin_is_contended = __ticket_spin_is_contended,
017d2877
AM
9984diff -urNp linux-2.6.30.4/arch/x86/kernel/process_32.c linux-2.6.30.4/arch/x86/kernel/process_32.c
9985--- linux-2.6.30.4/arch/x86/kernel/process_32.c 2009-07-24 17:47:51.000000000 -0400
9986+++ linux-2.6.30.4/arch/x86/kernel/process_32.c 2009-07-30 09:48:09.951950745 -0400
9987@@ -73,6 +73,7 @@ EXPORT_PER_CPU_SYMBOL(current_task);
2380c486
JR
9988 unsigned long thread_saved_pc(struct task_struct *tsk)
9989 {
9990 return ((unsigned long *)tsk->thread.sp)[3];
9991+//XXX return tsk->thread.eip;
9992 }
9993
9994 #ifndef CONFIG_SMP
017d2877 9995@@ -135,7 +136,7 @@ void __show_regs(struct pt_regs *regs, i
2380c486
JR
9996 unsigned short ss, gs;
9997 const char *board;
9998
9999- if (user_mode_vm(regs)) {
10000+ if (user_mode(regs)) {
10001 sp = regs->sp;
10002 ss = regs->ss & 0xffff;
017d2877
AM
10003 gs = get_user_gs(regs);
10004@@ -216,8 +217,8 @@ int kernel_thread(int (*fn)(void *), voi
2380c486
JR
10005 regs.bx = (unsigned long) fn;
10006 regs.dx = (unsigned long) arg;
10007
10008- regs.ds = __USER_DS;
10009- regs.es = __USER_DS;
10010+ regs.ds = __KERNEL_DS;
10011+ regs.es = __KERNEL_DS;
10012 regs.fs = __KERNEL_PERCPU;
017d2877 10013 regs.gs = __KERNEL_STACK_CANARY;
2380c486 10014 regs.orig_ax = -1;
017d2877 10015@@ -253,7 +254,7 @@ int copy_thread(unsigned long clone_flag
2380c486
JR
10016 struct task_struct *tsk;
10017 int err;
10018
10019- childregs = task_pt_regs(p);
10020+ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
10021 *childregs = *regs;
10022 childregs->ax = 0;
10023 childregs->sp = sp;
017d2877 10024@@ -282,6 +283,7 @@ int copy_thread(unsigned long clone_flag
2380c486
JR
10025 * Set a new TLS for the child thread?
10026 */
10027 if (clone_flags & CLONE_SETTLS)
10028+//XXX needs set_fs()?
10029 err = do_set_thread_area(p, -1,
10030 (struct user_desc __user *)childregs->si, 0);
10031
017d2877 10032@@ -351,7 +353,7 @@ __switch_to(struct task_struct *prev_p,
2380c486
JR
10033 struct thread_struct *prev = &prev_p->thread,
10034 *next = &next_p->thread;
10035 int cpu = smp_processor_id();
10036- struct tss_struct *tss = &per_cpu(init_tss, cpu);
10037+ struct tss_struct *tss = init_tss + cpu;
10038
10039 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
10040
017d2877 10041@@ -379,6 +381,11 @@ __switch_to(struct task_struct *prev_p,
2380c486 10042 */
017d2877 10043 lazy_save_gs(prev->gs);
2380c486
JR
10044
10045+#ifdef CONFIG_PAX_MEMORY_UDEREF
10046+ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
10047+ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
10048+#endif
10049+
10050 /*
10051 * Load the per-thread Thread-Local Storage descriptor.
10052 */
017d2877 10053@@ -497,15 +504,27 @@ unsigned long get_wchan(struct task_stru
2380c486
JR
10054 return 0;
10055 }
10056
10057-unsigned long arch_align_stack(unsigned long sp)
10058+#ifdef CONFIG_PAX_RANDKSTACK
10059+asmlinkage void pax_randomize_kstack(void)
10060 {
10061- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
10062- sp -= get_random_int() % 8192;
10063- return sp & ~0xf;
10064-}
10065+ struct thread_struct *thread = &current->thread;
10066+ unsigned long time;
10067
10068-unsigned long arch_randomize_brk(struct mm_struct *mm)
10069-{
10070- unsigned long range_end = mm->brk + 0x02000000;
10071- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
10072+ if (!randomize_va_space)
10073+ return;
10074+
10075+ rdtscl(time);
10076+
10077+ /* P4 seems to return a 0 LSB, ignore it */
10078+#ifdef CONFIG_MPENTIUM4
10079+ time &= 0x1EUL;
10080+ time <<= 2;
10081+#else
10082+ time &= 0xFUL;
10083+ time <<= 3;
10084+#endif
10085+
10086+ thread->sp0 ^= time;
10087+ load_sp0(init_tss + smp_processor_id(), thread);
10088 }
10089+#endif
017d2877
AM
10090diff -urNp linux-2.6.30.4/arch/x86/kernel/process_64.c linux-2.6.30.4/arch/x86/kernel/process_64.c
10091--- linux-2.6.30.4/arch/x86/kernel/process_64.c 2009-07-24 17:47:51.000000000 -0400
10092+++ linux-2.6.30.4/arch/x86/kernel/process_64.c 2009-07-30 09:48:09.951950745 -0400
10093@@ -97,7 +97,7 @@ static void __exit_idle(void)
de855c5d
AM
10094 void exit_idle(void)
10095 {
10096 /* idle loop has pid 0 */
10097- if (current->pid)
10098+ if (task_pid_nr(current))
10099 return;
10100 __exit_idle();
10101 }
017d2877 10102@@ -176,7 +176,7 @@ void __show_regs(struct pt_regs *regs, i
de855c5d
AM
10103 if (!board)
10104 board = "";
10105 printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n",
10106- current->pid, current->comm, print_tainted(),
10107+ task_pid_nr(current), current->comm, print_tainted(),
10108 init_utsname()->release,
10109 (int)strcspn(init_utsname()->version, " "),
10110 init_utsname()->version, board);
017d2877 10111@@ -386,7 +386,7 @@ __switch_to(struct task_struct *prev_p,
2380c486
JR
10112 struct thread_struct *prev = &prev_p->thread;
10113 struct thread_struct *next = &next_p->thread;
10114 int cpu = smp_processor_id();
10115- struct tss_struct *tss = &per_cpu(init_tss, cpu);
10116+ struct tss_struct *tss = init_tss + cpu;
10117 unsigned fsindex, gsindex;
10118
10119 /* we're going to use this soon, after a few expensive things */
017d2877 10120@@ -545,12 +545,11 @@ unsigned long get_wchan(struct task_stru
2380c486
JR
10121 if (!p || p == current || p->state == TASK_RUNNING)
10122 return 0;
10123 stack = (unsigned long)task_stack_page(p);
10124- if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
10125+ if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64))
10126 return 0;
10127 fp = *(u64 *)(p->thread.sp);
10128 do {
10129- if (fp < (unsigned long)stack ||
10130- fp >= (unsigned long)stack+THREAD_SIZE)
10131+ if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64))
10132 return 0;
10133 ip = *(u64 *)(fp+8);
10134 if (!in_sched_functions(ip))
017d2877 10135@@ -659,16 +658,3 @@ long sys_arch_prctl(int code, unsigned l
2380c486
JR
10136 {
10137 return do_arch_prctl(current, code, addr);
10138 }
10139-
10140-unsigned long arch_align_stack(unsigned long sp)
10141-{
10142- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
10143- sp -= get_random_int() % 8192;
10144- return sp & ~0xf;
10145-}
10146-
10147-unsigned long arch_randomize_brk(struct mm_struct *mm)
10148-{
10149- unsigned long range_end = mm->brk + 0x02000000;
10150- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
10151-}
017d2877
AM
10152diff -urNp linux-2.6.30.4/arch/x86/kernel/process.c linux-2.6.30.4/arch/x86/kernel/process.c
10153--- linux-2.6.30.4/arch/x86/kernel/process.c 2009-07-24 17:47:51.000000000 -0400
10154+++ linux-2.6.30.4/arch/x86/kernel/process.c 2009-07-30 09:48:09.950702241 -0400
10155@@ -71,7 +71,7 @@ void exit_thread(void)
10156 unsigned long *bp = t->io_bitmap_ptr;
10157
10158 if (bp) {
10159- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
10160+ struct tss_struct *tss = init_tss + get_cpu();
10161
10162 t->io_bitmap_ptr = NULL;
10163 clear_thread_flag(TIF_IO_BITMAP);
10164@@ -105,6 +105,9 @@ void flush_thread(void)
10165
10166 clear_tsk_thread_flag(tsk, TIF_DEBUG);
10167
10168+#ifndef CONFIG_CC_STACKPROTECTOR
10169+ loadsegment(gs, 0);
10170+#endif
10171 tsk->thread.debugreg0 = 0;
10172 tsk->thread.debugreg1 = 0;
10173 tsk->thread.debugreg2 = 0;
10174diff -urNp linux-2.6.30.4/arch/x86/kernel/ptrace.c linux-2.6.30.4/arch/x86/kernel/ptrace.c
10175--- linux-2.6.30.4/arch/x86/kernel/ptrace.c 2009-07-24 17:47:51.000000000 -0400
10176+++ linux-2.6.30.4/arch/x86/kernel/ptrace.c 2009-07-30 09:48:09.952643339 -0400
10177@@ -1374,7 +1374,7 @@ void send_sigtrap(struct task_struct *ts
2380c486
JR
10178 info.si_code = si_code;
10179
10180 /* User-mode ip? */
10181- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
10182+ info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
10183
10184 /* Send us the fake SIGTRAP */
10185 force_sig_info(SIGTRAP, &info, tsk);
017d2877
AM
10186diff -urNp linux-2.6.30.4/arch/x86/kernel/reboot.c linux-2.6.30.4/arch/x86/kernel/reboot.c
10187--- linux-2.6.30.4/arch/x86/kernel/reboot.c 2009-07-24 17:47:51.000000000 -0400
10188+++ linux-2.6.30.4/arch/x86/kernel/reboot.c 2009-07-30 09:48:09.952643339 -0400
10189@@ -31,7 +31,7 @@ void (*pm_power_off)(void);
2380c486
JR
10190 EXPORT_SYMBOL(pm_power_off);
10191
10192 static const struct desc_ptr no_idt = {};
10193-static int reboot_mode;
10194+static unsigned short reboot_mode;
10195 enum reboot_type reboot_type = BOOT_KBD;
10196 int reboot_force;
10197
017d2877
AM
10198@@ -249,7 +249,7 @@ static struct dmi_system_id __initdata r
10199 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"),
2380c486
JR
10200 },
10201 },
10202- { }
10203+ { NULL, NULL, {{0, {0}}}, NULL}
10204 };
10205
10206 static int __init reboot_init(void)
017d2877 10207@@ -265,12 +265,12 @@ core_initcall(reboot_init);
2380c486
JR
10208 controller to pulse the CPU reset line, which is more thorough, but
10209 doesn't work with at least one type of 486 motherboard. It is easy
10210 to stop this code working; hence the copious comments. */
10211-static const unsigned long long
10212-real_mode_gdt_entries [3] =
10213+static struct desc_struct
10214+real_mode_gdt_entries [3] __read_only =
10215 {
10216- 0x0000000000000000ULL, /* Null descriptor */
10217- 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
10218- 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
10219+ {{{0x00000000, 0x00000000}}}, /* Null descriptor */
10220+ {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
10221+ {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
10222 };
10223
10224 static const struct desc_ptr
017d2877 10225@@ -319,7 +319,7 @@ static const unsigned char jump_to_bios
2380c486
JR
10226 * specified by the code and length parameters.
10227 * We assume that length will aways be less that 100!
10228 */
10229-void machine_real_restart(const unsigned char *code, int length)
10230+void machine_real_restart(const unsigned char *code, unsigned int length)
10231 {
10232 local_irq_disable();
10233
017d2877 10234@@ -339,8 +339,8 @@ void machine_real_restart(const unsigned
2380c486
JR
10235 /* Remap the kernel at virtual address zero, as well as offset zero
10236 from the kernel segment. This assumes the kernel segment starts at
10237 virtual address PAGE_OFFSET. */
10238- memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
10239- sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
10240+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
10241+ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
10242
10243 /*
10244 * Use `swapper_pg_dir' as our page directory.
017d2877 10245@@ -352,16 +352,15 @@ void machine_real_restart(const unsigned
2380c486
JR
10246 boot)". This seems like a fairly standard thing that gets set by
10247 REBOOT.COM programs, and the previous reset routine did this
10248 too. */
10249- *((unsigned short *)0x472) = reboot_mode;
10250+ *(unsigned short *)(__va(0x472)) = reboot_mode;
10251
10252 /* For the switch to real mode, copy some code to low memory. It has
10253 to be in the first 64k because it is running in 16-bit mode, and it
10254 has to have the same physical and virtual address, because it turns
10255 off paging. Copy it near the end of the first page, out of the way
10256 of BIOS variables. */
10257- memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
10258- real_mode_switch, sizeof (real_mode_switch));
10259- memcpy((void *)(0x1000 - 100), code, length);
10260+ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
10261+ memcpy(__va(0x1000 - 100), code, length);
10262
10263 /* Set up the IDT for real mode. */
10264 load_idt(&real_mode_idt);
017d2877
AM
10265diff -urNp linux-2.6.30.4/arch/x86/kernel/setup.c linux-2.6.30.4/arch/x86/kernel/setup.c
10266--- linux-2.6.30.4/arch/x86/kernel/setup.c 2009-07-30 20:32:40.383618032 -0400
10267+++ linux-2.6.30.4/arch/x86/kernel/setup.c 2009-07-30 20:32:47.940599318 -0400
10268@@ -740,14 +740,14 @@ void __init setup_arch(char **cmdline_p)
2380c486
JR
10269
10270 if (!boot_params.hdr.root_flags)
10271 root_mountflags &= ~MS_RDONLY;
10272- init_mm.start_code = (unsigned long) _text;
10273- init_mm.end_code = (unsigned long) _etext;
10274+ init_mm.start_code = ktla_ktva((unsigned long) _text);
10275+ init_mm.end_code = ktla_ktva((unsigned long) _etext);
10276 init_mm.end_data = (unsigned long) _edata;
017d2877 10277 init_mm.brk = _brk_end;
2380c486
JR
10278
10279- code_resource.start = virt_to_phys(_text);
10280- code_resource.end = virt_to_phys(_etext)-1;
10281- data_resource.start = virt_to_phys(_etext);
10282+ code_resource.start = virt_to_phys(ktla_ktva(_text));
10283+ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
10284+ data_resource.start = virt_to_phys(_data);
10285 data_resource.end = virt_to_phys(_edata)-1;
10286 bss_resource.start = virt_to_phys(&__bss_start);
10287 bss_resource.end = virt_to_phys(&__bss_stop)-1;
017d2877
AM
10288diff -urNp linux-2.6.30.4/arch/x86/kernel/setup_percpu.c linux-2.6.30.4/arch/x86/kernel/setup_percpu.c
10289--- linux-2.6.30.4/arch/x86/kernel/setup_percpu.c 2009-07-24 17:47:51.000000000 -0400
10290+++ linux-2.6.30.4/arch/x86/kernel/setup_percpu.c 2009-07-30 09:48:09.957530438 -0400
10291@@ -25,19 +25,17 @@
10292 # define DBG(x...)
2380c486 10293 #endif
017d2877
AM
10294
10295+#ifdef CONFIG_SMP
10296 DEFINE_PER_CPU(int, cpu_number);
10297 EXPORT_PER_CPU_SYMBOL(cpu_number);
2380c486 10298+#endif
2380c486 10299
017d2877
AM
10300-#ifdef CONFIG_X86_64
10301 #define BOOT_PERCPU_OFFSET ((unsigned long)__per_cpu_load)
10302-#else
10303-#define BOOT_PERCPU_OFFSET 0
10304-#endif
10305
10306 DEFINE_PER_CPU(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET;
10307 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
10308
10309-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = {
10310+unsigned long __per_cpu_offset[NR_CPUS] __read_only = {
10311 [0 ... NR_CPUS-1] = BOOT_PERCPU_OFFSET,
10312 };
10313 EXPORT_SYMBOL(__per_cpu_offset);
10314@@ -336,13 +334,16 @@ out_free_ar:
10315 static inline void setup_percpu_segment(int cpu)
10316 {
10317 #ifdef CONFIG_X86_32
10318- struct desc_struct gdt;
10319+ struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
10320+ unsigned long base, limit;
10321
10322- pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
10323- 0x2 | DESCTYPE_S, 0x8);
10324- gdt.s = 1;
10325- write_gdt_entry(get_cpu_gdt_table(cpu),
10326- GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
10327+ base = per_cpu_offset(cpu);
10328+ limit = PERCPU_ENOUGH_ROOM - 1;
10329+ if (limit < 64*1024)
10330+ pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
10331+ else
10332+ pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
10333+ write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
10334 #endif
10335 }
10336
10337@@ -381,6 +382,11 @@ void __init setup_per_cpu_areas(void)
10338 /* alrighty, percpu areas up and running */
10339 delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
10340 for_each_possible_cpu(cpu) {
10341+#ifdef CONFIG_CC_STACKPROTECTOR
10342+#ifdef CONFIG_x86_32
10343+ unsigned long canary = per_cpu(stack_canary, cpu);
10344+#endif
10345+#endif
10346 per_cpu_offset(cpu) = delta + cpu * pcpu_unit_size;
10347 per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
10348 per_cpu(cpu_number, cpu) = cpu;
10349@@ -408,6 +414,12 @@ void __init setup_per_cpu_areas(void)
10350 early_per_cpu_map(x86_cpu_to_node_map, cpu);
10351 #endif
10352 #endif
10353+#ifdef CONFIG_CC_STACKPROTECTOR
10354+#ifdef CONFIG_x86_32
10355+ if (cpu == boot_cpu_id)
10356+ per_cpu(stack_canary, cpu) = canary;
10357+#endif
10358+#endif
10359 /*
10360 * Up to this point, the boot CPU has been using .data.init
10361 * area. Reload any changed state for the boot CPU.
10362diff -urNp linux-2.6.30.4/arch/x86/kernel/signal.c linux-2.6.30.4/arch/x86/kernel/signal.c
10363--- linux-2.6.30.4/arch/x86/kernel/signal.c 2009-07-24 17:47:51.000000000 -0400
10364+++ linux-2.6.30.4/arch/x86/kernel/signal.c 2009-07-30 09:48:09.958625901 -0400
10365@@ -198,7 +198,7 @@ static unsigned long align_sigframe(unsi
de855c5d
AM
10366 * Align the stack pointer according to the i386 ABI,
10367 * i.e. so that on function entry ((sp + 4) & 15) == 0.
10368 */
10369- sp = ((sp + 4) & -16ul) - 4;
10370+ sp = ((sp - 12) & -16ul) - 4;
017d2877
AM
10371 #else /* !CONFIG_X86_32 */
10372 sp = round_down(sp, 16) - 8;
10373 #endif
10374@@ -308,9 +308,9 @@ __setup_frame(int sig, struct k_sigactio
2380c486
JR
10375 }
10376
10377 if (current->mm->context.vdso)
10378- restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
10379+ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
10380 else
10381- restorer = &frame->retcode;
10382+ restorer = (void __user *)&frame->retcode;
10383 if (ka->sa.sa_flags & SA_RESTORER)
10384 restorer = ka->sa.sa_restorer;
10385
017d2877
AM
10386@@ -378,7 +378,7 @@ static int __setup_rt_frame(int sig, str
10387 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
2380c486 10388
017d2877
AM
10389 /* Set up to return from userspace. */
10390- restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
10391+ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
10392 if (ka->sa.sa_flags & SA_RESTORER)
10393 restorer = ka->sa.sa_restorer;
10394 put_user_ex(restorer, &frame->pretcode);
10395@@ -790,7 +790,7 @@ static void do_signal(struct pt_regs *re
2380c486
JR
10396 * X86_32: vm86 regs switched out by assembly code before reaching
10397 * here, so testing against kernel CS suffices.
10398 */
10399- if (!user_mode(regs))
10400+ if (!user_mode_novm(regs))
10401 return;
10402
10403 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
017d2877
AM
10404diff -urNp linux-2.6.30.4/arch/x86/kernel/smpboot.c linux-2.6.30.4/arch/x86/kernel/smpboot.c
10405--- linux-2.6.30.4/arch/x86/kernel/smpboot.c 2009-07-24 17:47:51.000000000 -0400
10406+++ linux-2.6.30.4/arch/x86/kernel/smpboot.c 2009-07-30 09:48:09.958625901 -0400
10407@@ -685,6 +685,10 @@ static int __cpuinit do_boot_cpu(int api
10408 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
2380c486 10409 };
017d2877 10410
2380c486
JR
10411+#ifdef CONFIG_PAX_KERNEXEC
10412+ unsigned long cr0;
10413+#endif
10414+
10415 INIT_WORK(&c_idle.work, do_fork_idle);
10416
017d2877
AM
10417 alternatives_smp_switch(1);
10418@@ -727,7 +731,17 @@ do_rest:
10419 (unsigned long)task_stack_page(c_idle.idle) -
10420 KERNEL_STACK_OFFSET + THREAD_SIZE;
2380c486
JR
10421 #endif
10422+
10423+#ifdef CONFIG_PAX_KERNEXEC
10424+ pax_open_kernel(cr0);
10425+#endif
10426+
10427 early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
10428+
10429+#ifdef CONFIG_PAX_KERNEXEC
10430+ pax_close_kernel(cr0);
10431+#endif
10432+
10433 initial_code = (unsigned long)start_secondary;
10434 stack_start.sp = (void *) c_idle.idle->thread.sp;
10435
017d2877
AM
10436diff -urNp linux-2.6.30.4/arch/x86/kernel/step.c linux-2.6.30.4/arch/x86/kernel/step.c
10437--- linux-2.6.30.4/arch/x86/kernel/step.c 2009-07-24 17:47:51.000000000 -0400
10438+++ linux-2.6.30.4/arch/x86/kernel/step.c 2009-07-30 09:48:09.958625901 -0400
2380c486
JR
10439@@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
10440 * and APM bios ones we just ignore here.
10441 */
10442 if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
10443- u32 *desc;
10444+ struct desc_struct *desc;
10445 unsigned long base;
10446
10447- seg &= ~7UL;
10448+ seg >>= 3;
10449
10450 mutex_lock(&child->mm->context.lock);
10451- if (unlikely((seg >> 3) >= child->mm->context.size))
10452- addr = -1L; /* bogus selector, access would fault */
10453+ if (unlikely(seg >= child->mm->context.size))
10454+ addr = -EINVAL;
10455 else {
10456- desc = child->mm->context.ldt + seg;
10457- base = ((desc[0] >> 16) |
10458- ((desc[1] & 0xff) << 16) |
10459- (desc[1] & 0xff000000));
10460+ desc = &child->mm->context.ldt[seg];
10461+ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
10462
10463 /* 16-bit code segment? */
10464- if (!((desc[1] >> 22) & 1))
10465+ if (!((desc->b >> 22) & 1))
10466 addr &= 0xffff;
10467 addr += base;
10468 }
10469@@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
10470 unsigned char opcode[15];
10471 unsigned long addr = convert_ip_to_linear(child, regs);
10472
10473+ if (addr == -EINVAL)
10474+ return 0;
10475+
10476 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
10477 for (i = 0; i < copied; i++) {
10478 switch (opcode[i]) {
10479@@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
10480
10481 #ifdef CONFIG_X86_64
10482 case 0x40 ... 0x4f:
10483- if (regs->cs != __USER_CS)
10484+ if ((regs->cs & 0xffff) != __USER_CS)
10485 /* 32-bit mode: register increment */
10486 return 0;
10487 /* 64-bit mode: REX prefix */
017d2877
AM
10488diff -urNp linux-2.6.30.4/arch/x86/kernel/syscall_table_32.S linux-2.6.30.4/arch/x86/kernel/syscall_table_32.S
10489--- linux-2.6.30.4/arch/x86/kernel/syscall_table_32.S 2009-07-24 17:47:51.000000000 -0400
10490+++ linux-2.6.30.4/arch/x86/kernel/syscall_table_32.S 2009-07-30 09:48:09.959782846 -0400
2380c486
JR
10491@@ -1,3 +1,4 @@
10492+.section .rodata,"a",@progbits
10493 ENTRY(sys_call_table)
10494 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
10495 .long sys_exit
017d2877
AM
10496diff -urNp linux-2.6.30.4/arch/x86/kernel/sys_i386_32.c linux-2.6.30.4/arch/x86/kernel/sys_i386_32.c
10497--- linux-2.6.30.4/arch/x86/kernel/sys_i386_32.c 2009-07-24 17:47:51.000000000 -0400
10498+++ linux-2.6.30.4/arch/x86/kernel/sys_i386_32.c 2009-07-30 09:48:09.958625901 -0400
2380c486
JR
10499@@ -24,6 +24,21 @@
10500
10501 #include <asm/syscalls.h>
10502
10503+int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
10504+{
10505+ unsigned long pax_task_size = TASK_SIZE;
10506+
10507+#ifdef CONFIG_PAX_SEGMEXEC
10508+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
10509+ pax_task_size = SEGMEXEC_TASK_SIZE;
10510+#endif
10511+
10512+ if (len > pax_task_size || addr > pax_task_size - len)
10513+ return -EINVAL;
10514+
10515+ return 0;
10516+}
10517+
10518 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
10519 unsigned long prot, unsigned long flags,
10520 unsigned long fd, unsigned long pgoff)
10521@@ -83,6 +98,205 @@ out:
10522 return err;
10523 }
10524
10525+unsigned long
10526+arch_get_unmapped_area(struct file *filp, unsigned long addr,
10527+ unsigned long len, unsigned long pgoff, unsigned long flags)
10528+{
10529+ struct mm_struct *mm = current->mm;
10530+ struct vm_area_struct *vma;
10531+ unsigned long start_addr, pax_task_size = TASK_SIZE;
10532+
10533+#ifdef CONFIG_PAX_SEGMEXEC
10534+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
10535+ pax_task_size = SEGMEXEC_TASK_SIZE;
10536+#endif
10537+
10538+ if (len > pax_task_size)
10539+ return -ENOMEM;
10540+
10541+ if (flags & MAP_FIXED)
10542+ return addr;
10543+
10544+#ifdef CONFIG_PAX_RANDMMAP
10545+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
10546+#endif
10547+
10548+ if (addr) {
10549+ addr = PAGE_ALIGN(addr);
10550+ vma = find_vma(mm, addr);
10551+ if (pax_task_size - len >= addr &&
10552+ (!vma || addr + len <= vma->vm_start))
10553+ return addr;
10554+ }
10555+ if (len > mm->cached_hole_size) {
10556+ start_addr = addr = mm->free_area_cache;
10557+ } else {
10558+ start_addr = addr = mm->mmap_base;
10559+ mm->cached_hole_size = 0;
10560+ }
10561+
10562+#ifdef CONFIG_PAX_PAGEEXEC
10563+ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
10564+ start_addr = 0x00110000UL;
10565+
10566+#ifdef CONFIG_PAX_RANDMMAP
10567+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10568+ start_addr += mm->delta_mmap & 0x03FFF000UL;
10569+#endif
10570+
10571+ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
10572+ start_addr = addr = mm->mmap_base;
10573+ else
10574+ addr = start_addr;
10575+ }
10576+#endif
10577+
10578+full_search:
10579+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
10580+ /* At this point: (!vma || addr < vma->vm_end). */
10581+ if (pax_task_size - len < addr) {
10582+ /*
10583+ * Start a new search - just in case we missed
10584+ * some holes.
10585+ */
10586+ if (start_addr != mm->mmap_base) {
10587+ start_addr = addr = mm->mmap_base;
10588+ mm->cached_hole_size = 0;
10589+ goto full_search;
10590+ }
10591+ return -ENOMEM;
10592+ }
10593+ if (!vma || addr + len <= vma->vm_start) {
10594+ /*
10595+ * Remember the place where we stopped the search:
10596+ */
10597+ mm->free_area_cache = addr + len;
10598+ return addr;
10599+ }
10600+ if (addr + mm->cached_hole_size < vma->vm_start)
10601+ mm->cached_hole_size = vma->vm_start - addr;
10602+ addr = vma->vm_end;
10603+ if (mm->start_brk <= addr && addr < mm->mmap_base) {
10604+ start_addr = addr = mm->mmap_base;
10605+ mm->cached_hole_size = 0;
10606+ goto full_search;
10607+ }
10608+ }
10609+}
10610+
10611+unsigned long
10612+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
10613+ const unsigned long len, const unsigned long pgoff,
10614+ const unsigned long flags)
10615+{
10616+ struct vm_area_struct *vma;
10617+ struct mm_struct *mm = current->mm;
10618+ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
10619+
10620+#ifdef CONFIG_PAX_SEGMEXEC
10621+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
10622+ pax_task_size = SEGMEXEC_TASK_SIZE;
10623+#endif
10624+
10625+ /* requested length too big for entire address space */
10626+ if (len > pax_task_size)
10627+ return -ENOMEM;
10628+
10629+ if (flags & MAP_FIXED)
10630+ return addr;
10631+
10632+#ifdef CONFIG_PAX_PAGEEXEC
10633+ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
10634+ goto bottomup;
10635+#endif
10636+
10637+#ifdef CONFIG_PAX_RANDMMAP
10638+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
10639+#endif
10640+
10641+ /* requesting a specific address */
10642+ if (addr) {
10643+ addr = PAGE_ALIGN(addr);
10644+ vma = find_vma(mm, addr);
10645+ if (pax_task_size - len >= addr &&
10646+ (!vma || addr + len <= vma->vm_start))
10647+ return addr;
10648+ }
10649+
10650+ /* check if free_area_cache is useful for us */
10651+ if (len <= mm->cached_hole_size) {
10652+ mm->cached_hole_size = 0;
10653+ mm->free_area_cache = mm->mmap_base;
10654+ }
10655+
10656+ /* either no address requested or can't fit in requested address hole */
10657+ addr = mm->free_area_cache;
10658+
10659+ /* make sure it can fit in the remaining address space */
10660+ if (addr > len) {
10661+ vma = find_vma(mm, addr-len);
10662+ if (!vma || addr <= vma->vm_start)
10663+ /* remember the address as a hint for next time */
10664+ return (mm->free_area_cache = addr-len);
10665+ }
10666+
10667+ if (mm->mmap_base < len)
10668+ goto bottomup;
10669+
10670+ addr = mm->mmap_base-len;
10671+
10672+ do {
10673+ /*
10674+ * Lookup failure means no vma is above this address,
10675+ * else if new region fits below vma->vm_start,
10676+ * return with success:
10677+ */
10678+ vma = find_vma(mm, addr);
10679+ if (!vma || addr+len <= vma->vm_start)
10680+ /* remember the address as a hint for next time */
10681+ return (mm->free_area_cache = addr);
10682+
10683+ /* remember the largest hole we saw so far */
10684+ if (addr + mm->cached_hole_size < vma->vm_start)
10685+ mm->cached_hole_size = vma->vm_start - addr;
10686+
10687+ /* try just below the current vma->vm_start */
10688+ addr = vma->vm_start-len;
10689+ } while (len < vma->vm_start);
10690+
10691+bottomup:
10692+ /*
10693+ * A failed mmap() very likely causes application failure,
10694+ * so fall back to the bottom-up function here. This scenario
10695+ * can happen with large stack limits and large mmap()
10696+ * allocations.
10697+ */
10698+
10699+#ifdef CONFIG_PAX_SEGMEXEC
10700+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
10701+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
10702+ else
10703+#endif
10704+
10705+ mm->mmap_base = TASK_UNMAPPED_BASE;
10706+
10707+#ifdef CONFIG_PAX_RANDMMAP
10708+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10709+ mm->mmap_base += mm->delta_mmap;
10710+#endif
10711+
10712+ mm->free_area_cache = mm->mmap_base;
10713+ mm->cached_hole_size = ~0UL;
10714+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
10715+ /*
10716+ * Restore the topdown base:
10717+ */
10718+ mm->mmap_base = base;
10719+ mm->free_area_cache = base;
10720+ mm->cached_hole_size = ~0UL;
10721+
10722+ return addr;
10723+}
10724
10725 struct sel_arg_struct {
10726 unsigned long n;
017d2877
AM
10727diff -urNp linux-2.6.30.4/arch/x86/kernel/sys_x86_64.c linux-2.6.30.4/arch/x86/kernel/sys_x86_64.c
10728--- linux-2.6.30.4/arch/x86/kernel/sys_x86_64.c 2009-07-24 17:47:51.000000000 -0400
10729+++ linux-2.6.30.4/arch/x86/kernel/sys_x86_64.c 2009-07-30 09:48:09.959782846 -0400
2380c486
JR
10730@@ -47,8 +47,8 @@ out:
10731 return error;
10732 }
10733
10734-static void find_start_end(unsigned long flags, unsigned long *begin,
10735- unsigned long *end)
10736+static void find_start_end(struct mm_struct *mm, unsigned long flags,
10737+ unsigned long *begin, unsigned long *end)
10738 {
10739 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
10740 unsigned long new_begin;
10741@@ -67,7 +67,7 @@ static void find_start_end(unsigned long
10742 *begin = new_begin;
10743 }
10744 } else {
10745- *begin = TASK_UNMAPPED_BASE;
10746+ *begin = mm->mmap_base;
10747 *end = TASK_SIZE;
10748 }
10749 }
10750@@ -84,11 +84,15 @@ arch_get_unmapped_area(struct file *filp
10751 if (flags & MAP_FIXED)
10752 return addr;
10753
10754- find_start_end(flags, &begin, &end);
10755+ find_start_end(mm, flags, &begin, &end);
10756
10757 if (len > end)
10758 return -ENOMEM;
10759
10760+#ifdef CONFIG_PAX_RANDMMAP
10761+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
10762+#endif
10763+
10764 if (addr) {
10765 addr = PAGE_ALIGN(addr);
10766 vma = find_vma(mm, addr);
10767@@ -143,7 +147,7 @@ arch_get_unmapped_area_topdown(struct fi
10768 {
10769 struct vm_area_struct *vma;
10770 struct mm_struct *mm = current->mm;
10771- unsigned long addr = addr0;
10772+ unsigned long base = mm->mmap_base, addr = addr0;
10773
10774 /* requested length too big for entire address space */
10775 if (len > TASK_SIZE)
10776@@ -156,6 +160,10 @@ arch_get_unmapped_area_topdown(struct fi
10777 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
10778 goto bottomup;
10779
10780+#ifdef CONFIG_PAX_RANDMMAP
10781+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
10782+#endif
10783+
10784 /* requesting a specific address */
10785 if (addr) {
10786 addr = PAGE_ALIGN(addr);
10787@@ -213,13 +221,21 @@ bottomup:
10788 * can happen with large stack limits and large mmap()
10789 * allocations.
10790 */
10791+ mm->mmap_base = TASK_UNMAPPED_BASE;
10792+
10793+#ifdef CONFIG_PAX_RANDMMAP
10794+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10795+ mm->mmap_base += mm->delta_mmap;
10796+#endif
10797+
10798+ mm->free_area_cache = mm->mmap_base;
10799 mm->cached_hole_size = ~0UL;
10800- mm->free_area_cache = TASK_UNMAPPED_BASE;
10801 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
10802 /*
10803 * Restore the topdown base:
10804 */
10805- mm->free_area_cache = mm->mmap_base;
10806+ mm->mmap_base = base;
10807+ mm->free_area_cache = base;
10808 mm->cached_hole_size = ~0UL;
10809
10810 return addr;
017d2877
AM
10811diff -urNp linux-2.6.30.4/arch/x86/kernel/time_32.c linux-2.6.30.4/arch/x86/kernel/time_32.c
10812--- linux-2.6.30.4/arch/x86/kernel/time_32.c 2009-07-24 17:47:51.000000000 -0400
10813+++ linux-2.6.30.4/arch/x86/kernel/time_32.c 2009-07-30 09:48:09.959782846 -0400
2380c486
JR
10814@@ -47,22 +47,32 @@ unsigned long profile_pc(struct pt_regs
10815 unsigned long pc = instruction_pointer(regs);
10816
10817 #ifdef CONFIG_SMP
10818- if (!user_mode_vm(regs) && in_lock_functions(pc)) {
10819+ if (!user_mode(regs) && in_lock_functions(pc)) {
10820 #ifdef CONFIG_FRAME_POINTER
10821- return *(unsigned long *)(regs->bp + sizeof(long));
10822+ return ktla_ktva(*(unsigned long *)(regs->bp + sizeof(long)));
10823 #else
10824 unsigned long *sp = (unsigned long *)&regs->sp;
10825
10826 /* Return address is either directly at stack pointer
10827 or above a saved flags. Eflags has bits 22-31 zero,
10828 kernel addresses don't. */
10829+
10830+#ifdef CONFIG_PAX_KERNEXEC
10831+ return ktla_ktva(sp[0]);
10832+#else
10833 if (sp[0] >> 22)
10834 return sp[0];
10835 if (sp[1] >> 22)
10836 return sp[1];
10837 #endif
10838+
10839+#endif
10840 }
10841 #endif
10842+
10843+ if (!user_mode(regs))
10844+ pc = ktla_ktva(pc);
10845+
10846 return pc;
10847 }
10848 EXPORT_SYMBOL(profile_pc);
017d2877
AM
10849diff -urNp linux-2.6.30.4/arch/x86/kernel/time_64.c linux-2.6.30.4/arch/x86/kernel/time_64.c
10850--- linux-2.6.30.4/arch/x86/kernel/time_64.c 2009-07-24 17:47:51.000000000 -0400
10851+++ linux-2.6.30.4/arch/x86/kernel/time_64.c 2009-07-30 09:48:09.960740129 -0400
de855c5d
AM
10852@@ -25,8 +25,6 @@
10853 #include <asm/time.h>
10854 #include <asm/timer.h>
10855
10856-volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
10857-
10858 unsigned long profile_pc(struct pt_regs *regs)
10859 {
10860 unsigned long pc = instruction_pointer(regs);
10861@@ -34,7 +32,7 @@ unsigned long profile_pc(struct pt_regs
2380c486
JR
10862 /* Assume the lock function has either no stack frame or a copy
10863 of flags from PUSHF
10864 Eflags always has bits 22 and up cleared unlike kernel addresses. */
10865- if (!user_mode_vm(regs) && in_lock_functions(pc)) {
10866+ if (!user_mode(regs) && in_lock_functions(pc)) {
10867 #ifdef CONFIG_FRAME_POINTER
10868 return *(unsigned long *)(regs->bp + sizeof(long));
10869 #else
017d2877
AM
10870diff -urNp linux-2.6.30.4/arch/x86/kernel/tls.c linux-2.6.30.4/arch/x86/kernel/tls.c
10871--- linux-2.6.30.4/arch/x86/kernel/tls.c 2009-07-24 17:47:51.000000000 -0400
10872+++ linux-2.6.30.4/arch/x86/kernel/tls.c 2009-07-30 09:48:09.960740129 -0400
2380c486
JR
10873@@ -85,6 +85,11 @@ int do_set_thread_area(struct task_struc
10874 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
10875 return -EINVAL;
10876
10877+#ifdef CONFIG_PAX_SEGMEXEC
10878+ if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
10879+ return -EINVAL;
10880+#endif
10881+
10882 set_tls_desc(p, idx, &info, 1);
10883
10884 return 0;
017d2877
AM
10885diff -urNp linux-2.6.30.4/arch/x86/kernel/traps.c linux-2.6.30.4/arch/x86/kernel/traps.c
10886--- linux-2.6.30.4/arch/x86/kernel/traps.c 2009-07-24 17:47:51.000000000 -0400
10887+++ linux-2.6.30.4/arch/x86/kernel/traps.c 2009-07-30 09:48:09.961532028 -0400
10888@@ -70,14 +70,6 @@ asmlinkage int system_call(void);
2380c486
JR
10889
10890 /* Do we ignore FPU interrupts ? */
10891 char ignore_fpu_irq;
10892-
10893-/*
10894- * The IDT has to be page-aligned to simplify the Pentium
10895- * F0 0F bug workaround.. We have a special link segment
10896- * for this.
10897- */
10898-gate_desc idt_table[256]
10899- __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
10900 #endif
10901
10902 DECLARE_BITMAP(used_vectors, NR_VECTORS);
017d2877 10903@@ -115,7 +107,7 @@ static inline void preempt_conditional_c
2380c486
JR
10904 static inline void
10905 die_if_kernel(const char *str, struct pt_regs *regs, long err)
10906 {
10907- if (!user_mode_vm(regs))
10908+ if (!user_mode(regs))
10909 die(str, regs, err);
10910 }
017d2877
AM
10911 #endif
10912@@ -127,7 +119,7 @@ do_trap(int trapnr, int signr, char *str
2380c486
JR
10913 struct task_struct *tsk = current;
10914
10915 #ifdef CONFIG_X86_32
10916- if (regs->flags & X86_VM_MASK) {
10917+ if (v8086_mode(regs)) {
10918 /*
10919 * traps 0, 1, 3, 4, and 5 should be forwarded to vm86.
10920 * On nmi (interrupt 2), do_trap should not be called.
017d2877 10921@@ -138,7 +130,7 @@ do_trap(int trapnr, int signr, char *str
2380c486
JR
10922 }
10923 #endif
10924
10925- if (!user_mode(regs))
10926+ if (!user_mode_novm(regs))
10927 goto kernel_trap;
10928
10929 #ifdef CONFIG_X86_32
017d2877 10930@@ -161,7 +153,7 @@ trap_signal:
de855c5d
AM
10931 printk_ratelimit()) {
10932 printk(KERN_INFO
10933 "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
10934- tsk->comm, tsk->pid, str,
10935+ tsk->comm, task_pid_nr(tsk), str,
10936 regs->ip, regs->sp, error_code);
10937 print_vma_addr(" in ", regs->ip);
10938 printk("\n");
017d2877 10939@@ -180,6 +172,12 @@ kernel_trap:
2380c486
JR
10940 tsk->thread.trap_no = trapnr;
10941 die(str, regs, error_code);
10942 }
10943+
10944+#ifdef CONFIG_PAX_REFCOUNT
10945+ if (trapnr == 4)
10946+ pax_report_refcount_overflow(regs);
10947+#endif
10948+
10949 return;
10950
10951 #ifdef CONFIG_X86_32
017d2877
AM
10952@@ -268,14 +266,30 @@ do_general_protection(struct pt_regs *re
10953 conditional_sti(regs);
2380c486 10954
017d2877 10955 #ifdef CONFIG_X86_32
2380c486
JR
10956- if (regs->flags & X86_VM_MASK)
10957+ if (v8086_mode(regs))
10958 goto gp_in_vm86;
10959 #endif
10960
10961 tsk = current;
10962- if (!user_mode(regs))
10963+ if (!user_mode_novm(regs))
10964 goto gp_in_kernel;
10965
10966+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
10967+ if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
10968+ struct mm_struct *mm = tsk->mm;
10969+ unsigned long limit;
10970+
10971+ down_write(&mm->mmap_sem);
10972+ limit = mm->context.user_cs_limit;
10973+ if (limit < TASK_SIZE) {
10974+ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
10975+ up_write(&mm->mmap_sem);
10976+ return;
10977+ }
10978+ up_write(&mm->mmap_sem);
10979+ }
10980+#endif
10981+
10982 tsk->thread.error_code = error_code;
10983 tsk->thread.trap_no = 13;
10984
017d2877 10985@@ -308,6 +322,13 @@ gp_in_kernel:
2380c486
JR
10986 if (notify_die(DIE_GPF, "general protection fault", regs,
10987 error_code, 13, SIGSEGV) == NOTIFY_STOP)
10988 return;
10989+
10990+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
10991+ if ((regs->cs & 0xFFFF) == __KERNEL_CS)
10992+ die("PAX: suspicious general protection fault", regs, error_code);
10993+ else
10994+#endif
10995+
10996 die("general protection fault", regs, error_code);
10997 }
10998
017d2877 10999@@ -554,7 +575,7 @@ dotraplinkage void __kprobes do_debug(st
2380c486
JR
11000 }
11001
11002 #ifdef CONFIG_X86_32
11003- if (regs->flags & X86_VM_MASK)
11004+ if (v8086_mode(regs))
11005 goto debug_vm86;
11006 #endif
11007
017d2877 11008@@ -566,7 +587,7 @@ dotraplinkage void __kprobes do_debug(st
2380c486
JR
11009 * kernel space (but re-enable TF when returning to user mode).
11010 */
11011 if (condition & DR_STEP) {
11012- if (!user_mode(regs))
11013+ if (!user_mode_novm(regs))
11014 goto clear_TF_reenable;
11015 }
11016
017d2877 11017@@ -753,7 +774,7 @@ do_simd_coprocessor_error(struct pt_regs
2380c486
JR
11018 * Handle strange cache flush from user space exception
11019 * in all other cases. This is undocumented behaviour.
11020 */
11021- if (regs->flags & X86_VM_MASK) {
11022+ if (v8086_mode(regs)) {
11023 handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
11024 return;
11025 }
017d2877 11026@@ -782,19 +803,14 @@ do_spurious_interrupt_bug(struct pt_regs
2380c486
JR
11027 #ifdef CONFIG_X86_32
11028 unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
11029 {
11030- struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
11031 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
11032 unsigned long new_kesp = kesp - base;
11033 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
11034- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
11035+ struct desc_struct ss;
11036
11037 /* Set up base for espfix segment */
11038- desc &= 0x00f0ff0000000000ULL;
11039- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
11040- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
11041- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
11042- (lim_pages & 0xffff);
11043- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
11044+ pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
11045+ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
11046
11047 return new_kesp;
11048 }
017d2877
AM
11049diff -urNp linux-2.6.30.4/arch/x86/kernel/tsc.c linux-2.6.30.4/arch/x86/kernel/tsc.c
11050--- linux-2.6.30.4/arch/x86/kernel/tsc.c 2009-07-24 17:47:51.000000000 -0400
11051+++ linux-2.6.30.4/arch/x86/kernel/tsc.c 2009-07-30 09:48:09.961532028 -0400
11052@@ -772,7 +772,7 @@ static struct dmi_system_id __initdata b
2380c486
JR
11053 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
11054 },
11055 },
11056- {}
11057+ { NULL, NULL, {{0, {0}}}, NULL}
11058 };
11059
11060 static void __init check_system_tsc_reliable(void)
017d2877
AM
11061diff -urNp linux-2.6.30.4/arch/x86/kernel/vm86_32.c linux-2.6.30.4/arch/x86/kernel/vm86_32.c
11062--- linux-2.6.30.4/arch/x86/kernel/vm86_32.c 2009-07-24 17:47:51.000000000 -0400
11063+++ linux-2.6.30.4/arch/x86/kernel/vm86_32.c 2009-07-30 09:48:09.961532028 -0400
2380c486
JR
11064@@ -148,7 +148,7 @@ struct pt_regs *save_v86_state(struct ke
11065 do_exit(SIGSEGV);
11066 }
11067
11068- tss = &per_cpu(init_tss, get_cpu());
11069+ tss = init_tss + get_cpu();
11070 current->thread.sp0 = current->thread.saved_sp0;
11071 current->thread.sysenter_cs = __KERNEL_CS;
11072 load_sp0(tss, &current->thread);
017d2877 11073@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
2380c486 11074 tsk->thread.saved_fs = info->regs32->fs;
017d2877 11075 tsk->thread.saved_gs = get_user_gs(info->regs32);
2380c486
JR
11076
11077- tss = &per_cpu(init_tss, get_cpu());
11078+ tss = init_tss + get_cpu();
11079 tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
11080 if (cpu_has_sep)
11081 tsk->thread.sysenter_cs = 0;
017d2877
AM
11082diff -urNp linux-2.6.30.4/arch/x86/kernel/vmi_32.c linux-2.6.30.4/arch/x86/kernel/vmi_32.c
11083--- linux-2.6.30.4/arch/x86/kernel/vmi_32.c 2009-07-24 17:47:51.000000000 -0400
11084+++ linux-2.6.30.4/arch/x86/kernel/vmi_32.c 2009-07-30 09:48:09.962543704 -0400
2380c486
JR
11085@@ -102,18 +102,43 @@ static unsigned patch_internal(int call,
11086 {
11087 u64 reloc;
11088 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
11089+
11090+#ifdef CONFIG_PAX_KERNEXEC
11091+ unsigned long cr0;
11092+#endif
11093+
11094 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
11095 switch(rel->type) {
11096 case VMI_RELOCATION_CALL_REL:
11097 BUG_ON(len < 5);
11098+
11099+#ifdef CONFIG_PAX_KERNEXEC
11100+ pax_open_kernel(cr0);
11101+#endif
11102+
11103 *(char *)insnbuf = MNEM_CALL;
11104 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
11105+
11106+#ifdef CONFIG_PAX_KERNEXEC
11107+ pax_close_kernel(cr0);
11108+#endif
11109+
11110 return 5;
11111
11112 case VMI_RELOCATION_JUMP_REL:
11113 BUG_ON(len < 5);
11114+
11115+#ifdef CONFIG_PAX_KERNEXEC
11116+ pax_open_kernel(cr0);
11117+#endif
11118+
11119 *(char *)insnbuf = MNEM_JMP;
11120 patch_offset(insnbuf, ip, (unsigned long)rel->eip);
11121+
11122+#ifdef CONFIG_PAX_KERNEXEC
11123+ pax_close_kernel(cr0);
11124+#endif
11125+
11126 return 5;
11127
11128 case VMI_RELOCATION_NOP:
017d2877 11129@@ -404,13 +429,13 @@ static void vmi_set_pud(pud_t *pudp, pud
2380c486
JR
11130
11131 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
11132 {
11133- const pte_t pte = { .pte = 0 };
11134+ const pte_t pte = __pte(0ULL);
11135 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
11136 }
11137
11138 static void vmi_pmd_clear(pmd_t *pmd)
11139 {
11140- const pte_t pte = { .pte = 0 };
11141+ const pte_t pte = __pte(0ULL);
11142 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
11143 }
11144 #endif
017d2877 11145@@ -438,8 +463,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
2380c486
JR
11146 ap.ss = __KERNEL_DS;
11147 ap.esp = (unsigned long) start_esp;
11148
11149- ap.ds = __USER_DS;
11150- ap.es = __USER_DS;
11151+ ap.ds = __KERNEL_DS;
11152+ ap.es = __KERNEL_DS;
11153 ap.fs = __KERNEL_PERCPU;
11154 ap.gs = 0;
11155
017d2877 11156@@ -634,12 +659,20 @@ static inline int __init activate_vmi(vo
2380c486
JR
11157 u64 reloc;
11158 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
11159
11160+#ifdef CONFIG_PAX_KERNEXEC
11161+ unsigned long cr0;
11162+#endif
11163+
11164 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
11165 printk(KERN_ERR "VMI ROM failed to initialize!");
11166 return 0;
11167 }
11168 savesegment(cs, kernel_cs);
11169
11170+#ifdef CONFIG_PAX_KERNEXEC
11171+ pax_open_kernel(cr0);
11172+#endif
11173+
11174 pv_info.paravirt_enabled = 1;
11175 pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
11176 pv_info.name = "vmi";
017d2877 11177@@ -830,6 +863,10 @@ static inline int __init activate_vmi(vo
2380c486
JR
11178
11179 para_fill(pv_irq_ops.safe_halt, Halt);
11180
11181+#ifdef CONFIG_PAX_KERNEXEC
11182+ pax_close_kernel(cr0);
11183+#endif
11184+
11185 /*
11186 * Alternative instruction rewriting doesn't happen soon enough
11187 * to convert VMI_IRET to a call instead of a jump; so we have
017d2877
AM
11188diff -urNp linux-2.6.30.4/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.30.4/arch/x86/kernel/vmlinux_32.lds.S
11189--- linux-2.6.30.4/arch/x86/kernel/vmlinux_32.lds.S 2009-07-24 17:47:51.000000000 -0400
11190+++ linux-2.6.30.4/arch/x86/kernel/vmlinux_32.lds.S 2009-07-30 09:48:09.962543704 -0400
2380c486 11191@@ -15,6 +15,20 @@
017d2877 11192 #include <asm/page_types.h>
2380c486
JR
11193 #include <asm/cache.h>
11194 #include <asm/boot.h>
11195+#include <asm/segment.h>
11196+
11197+#ifdef CONFIG_X86_PAE
11198+#define PMD_SHIFT 21
11199+#else
11200+#define PMD_SHIFT 22
11201+#endif
11202+#define PMD_SIZE (1 << PMD_SHIFT)
11203+
11204+#ifdef CONFIG_PAX_KERNEXEC
11205+#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
11206+#else
11207+#define __KERNEL_TEXT_OFFSET 0
11208+#endif
11209
11210 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
11211 OUTPUT_ARCH(i386)
11212@@ -22,82 +36,23 @@ ENTRY(phys_startup_32)
11213 jiffies = jiffies_64;
11214
11215 PHDRS {
11216- text PT_LOAD FLAGS(5); /* R_E */
11217- data PT_LOAD FLAGS(7); /* RWE */
11218- note PT_NOTE FLAGS(0); /* ___ */
11219+ initdata PT_LOAD FLAGS(6); /* RW_ */
11220+ percpu PT_LOAD FLAGS(6); /* RW_ */
11221+ inittext PT_LOAD FLAGS(5); /* R_E */
11222+ text PT_LOAD FLAGS(5); /* R_E */
11223+ rodata PT_LOAD FLAGS(4); /* R__ */
11224+ data PT_LOAD FLAGS(6); /* RW_ */
11225+ note PT_NOTE FLAGS(0); /* ___ */
11226 }
11227 SECTIONS
11228 {
11229- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
11230- phys_startup_32 = startup_32 - LOAD_OFFSET;
017d2877
AM
11231+ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
11232
2380c486
JR
11233- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
11234- _text = .; /* Text and read-only data */
11235- *(.text.head)
11236- } :text = 0x9090
11237-
11238- /* read-only */
11239- .text : AT(ADDR(.text) - LOAD_OFFSET) {
11240- . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
11241- *(.text.page_aligned)
11242- TEXT_TEXT
11243- SCHED_TEXT
11244- LOCK_TEXT
11245- KPROBES_TEXT
11246- IRQENTRY_TEXT
11247- *(.fixup)
11248- *(.gnu.warning)
11249- _etext = .; /* End of text section */
11250- } :text = 0x9090
11251-
11252- NOTES :text :note
017d2877 11253-
2380c486
JR
11254- . = ALIGN(16); /* Exception table */
11255- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
11256- __start___ex_table = .;
11257- *(__ex_table)
11258- __stop___ex_table = .;
11259- } :text = 0x9090
11260-
11261- RODATA
11262-
11263- /* writeable */
11264- . = ALIGN(PAGE_SIZE);
11265- .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
11266- DATA_DATA
11267- CONSTRUCTORS
11268- } :data
11269-
11270- . = ALIGN(PAGE_SIZE);
11271- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
11272- __nosave_begin = .;
11273- *(.data.nosave)
11274- . = ALIGN(PAGE_SIZE);
11275- __nosave_end = .;
11276- }
11277-
11278- . = ALIGN(PAGE_SIZE);
11279- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
11280- *(.data.page_aligned)
11281- *(.data.idt)
11282- }
11283-
11284- . = ALIGN(32);
11285- .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
11286- *(.data.cacheline_aligned)
11287- }
11288-
11289- /* rarely changed data like cpu maps */
11290- . = ALIGN(32);
11291- .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
11292- *(.data.read_mostly)
11293- _edata = .; /* End of data section */
11294- }
11295-
11296- . = ALIGN(THREAD_SIZE); /* init_task */
11297- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
11298- *(.data.init_task)
11299- }
11300+ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
11301+ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
11302+ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
11303+ *(.text.startup)
11304+ } :initdata
11305
11306 /* might get freed after init */
11307 . = ALIGN(PAGE_SIZE);
11308@@ -115,14 +70,8 @@ SECTIONS
11309 . = ALIGN(PAGE_SIZE);
11310
11311 /* will be freed after init */
11312- . = ALIGN(PAGE_SIZE); /* Init code and data */
11313- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
11314- __init_begin = .;
11315- _sinittext = .;
11316- INIT_TEXT
11317- _einittext = .;
11318- }
11319 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
11320+ __init_begin = .;
11321 INIT_DATA
11322 }
11323 . = ALIGN(16);
11324@@ -162,11 +111,6 @@ SECTIONS
11325 *(.parainstructions)
11326 __parainstructions_end = .;
11327 }
11328- /* .exit.text is discard at runtime, not link time, to deal with references
11329- from .altinstructions and .eh_frame */
11330- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
11331- EXIT_TEXT
11332- }
11333 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
11334 EXIT_DATA
11335 }
017d2877
AM
11336@@ -178,12 +122,130 @@ SECTIONS
11337 __initramfs_end = .;
2380c486
JR
11338 }
11339 #endif
017d2877 11340- PERCPU(PAGE_SIZE)
2380c486 11341 . = ALIGN(PAGE_SIZE);
017d2877
AM
11342+ PERCPU_VADDR(0, :percpu)
11343+ . = ALIGN(PAGE_SIZE);
11344+ /* freed after init ends here */
11345+
2380c486
JR
11346+ . = ALIGN(PAGE_SIZE); /* Init code and data */
11347+ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
11348+ _sinittext = .;
11349+ INIT_TEXT
11350+ _einittext = .;
11351+ } :inittext
11352+
11353+ /* .exit.text is discard at runtime, not link time, to deal with references
11354+ from .altinstructions and .eh_frame */
11355+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
11356+ EXIT_TEXT
11357+ }
11358+
11359+ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
11360+ BYTE(0)
11361+ . = ALIGN(2*PMD_SIZE) - 1;
11362+ }
11363+
017d2877
AM
11364 /* freed after init ends here */
11365
2380c486
JR
11366+ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
11367+ __init_end = . + __KERNEL_TEXT_OFFSET;
11368+ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
11369+ _text = .; /* Text and read-only data */
11370+ *(.text.head)
11371+ } :text = 0x9090
11372+
11373+ /* read-only */
11374+ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
11375+ . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
11376+ *(.text.page_aligned)
11377+ TEXT_TEXT
11378+ SCHED_TEXT
11379+ LOCK_TEXT
11380+ KPROBES_TEXT
11381+ IRQENTRY_TEXT
11382+ *(.fixup)
11383+ *(.gnu.warning)
11384+ _etext = .; /* End of text section */
11385+ } :text = 0x9090
11386+
11387+ . += __KERNEL_TEXT_OFFSET;
11388+
11389+ . = ALIGN(4096);
11390+ NOTES :rodata :note
11391+
11392+ . = ALIGN(16); /* Exception table */
11393+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
11394+ __start___ex_table = .;
11395+ *(__ex_table)
11396+ __stop___ex_table = .;
11397+ } :rodata
11398+
11399+ RO_DATA(PAGE_SIZE)
11400+
11401+ . = ALIGN(PAGE_SIZE);
11402+ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
11403+ *(.idt)
11404+ . = ALIGN(PAGE_SIZE);
11405+ *(.empty_zero_page)
11406+ *(.swapper_pg_pmd)
11407+ *(.swapper_pg_dir)
11408+
11409+#if defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_MODULES)
11410+ . = ALIGN(PMD_SIZE);
11411+#endif
11412+
11413+ }
11414+
11415+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
11416+ . = ALIGN(PAGE_SIZE);
11417+ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
11418+ MODULES_VADDR = .;
11419+ BYTE(0)
11420+ . += (6 * 1024 * 1024);
11421+ . = ALIGN(PMD_SIZE);
11422+ MODULES_END = . - 1;
11423+ }
11424+#endif
11425+
11426+ /* writeable */
11427+ . = ALIGN(PAGE_SIZE);
11428+ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
11429+ _data = .;
11430+ DATA_DATA
11431+ CONSTRUCTORS
11432+ } :data
11433+
11434+ . = ALIGN(PAGE_SIZE);
11435+ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
11436+ __nosave_begin = .;
11437+ *(.data.nosave)
11438+ . = ALIGN(PAGE_SIZE);
11439+ __nosave_end = .;
11440+ }
11441+
11442+ . = ALIGN(PAGE_SIZE);
11443+ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
11444+ *(.data.page_aligned)
11445+ }
11446+
11447+ . = ALIGN(32);
11448+ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
11449+ *(.data.cacheline_aligned)
11450+ }
11451+
11452+ /* rarely changed data like cpu maps */
11453+ . = ALIGN(32);
11454+ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
11455+ *(.data.read_mostly)
11456+ _edata = .; /* End of data section */
11457+ }
11458+
11459+ . = ALIGN(THREAD_SIZE); /* init_task */
11460+ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
11461+ *(.data.init_task)
11462+ }
11463+
11464 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
11465- __init_end = .;
11466 __bss_start = .; /* BSS */
11467 *(.bss.page_aligned)
11468 *(.bss)
017d2877
AM
11469diff -urNp linux-2.6.30.4/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.30.4/arch/x86/kernel/vmlinux_64.lds.S
11470--- linux-2.6.30.4/arch/x86/kernel/vmlinux_64.lds.S 2009-07-24 17:47:51.000000000 -0400
11471+++ linux-2.6.30.4/arch/x86/kernel/vmlinux_64.lds.S 2009-07-30 19:56:23.500027109 -0400
11472@@ -13,11 +13,11 @@
de855c5d
AM
11473 OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
11474 OUTPUT_ARCH(i386:x86-64)
11475 ENTRY(phys_startup_64)
11476-jiffies_64 = jiffies;
11477+jiffies = jiffies_64;
2380c486
JR
11478 PHDRS {
11479 text PT_LOAD FLAGS(5); /* R_E */
11480- data PT_LOAD FLAGS(7); /* RWE */
de855c5d 11481- user PT_LOAD FLAGS(7); /* RWE */
2380c486 11482+ data PT_LOAD FLAGS(6); /* RW_ */
017d2877 11483+ user PT_LOAD FLAGS(5); /* R_E */
2380c486 11484 data.init PT_LOAD FLAGS(7); /* RWE */
017d2877
AM
11485 #ifdef CONFIG_SMP
11486 percpu PT_LOAD FLAGS(7); /* RWE */
11487@@ -54,14 +54,18 @@ SECTIONS
2380c486
JR
11488 __stop___ex_table = .;
11489 } :text = 0x9090
11490
11491- RODATA
11492+ RO_DATA(PAGE_SIZE)
11493
11494+#ifdef CONFIG_PAX_KERNEXEC
11495+ . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
11496+#else
11497 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
11498+#endif
11499 /* Data */
11500+ _data = .;
11501 .data : AT(ADDR(.data) - LOAD_OFFSET) {
11502 DATA_DATA
11503 CONSTRUCTORS
017d2877 11504- _edata = .; /* End of data section */
2380c486
JR
11505 } :data
11506
017d2877
AM
11507
11508@@ -75,9 +79,28 @@ SECTIONS
11509 *(.data.read_mostly)
11510 }
11511
11512+ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
11513+ . = ALIGN(THREAD_SIZE); /* init_task */
11514+ *(.data.init_task)
11515+ }
11516+
11517+ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
11518+ . = ALIGN(PAGE_SIZE);
11519+ *(.data.page_aligned)
11520+ }
11521+
11522+ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
11523+ . = ALIGN(PAGE_SIZE);
11524+ __nosave_begin = .;
11525+ *(.data.nosave)
11526+ . = ALIGN(PAGE_SIZE);
11527+ __nosave_end = .;
11528+ _edata = .; /* End of data section */
11529+ }
11530+
11531 #define VSYSCALL_ADDR (-10*1024*1024)
11532-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
11533-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
11534+#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
11535+#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
11536
11537 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
11538 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
11539@@ -108,10 +131,6 @@ SECTIONS
de855c5d
AM
11540 .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) }
11541 vgetcpu_mode = VVIRT(.vgetcpu_mode);
11542
11543- . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
11544- .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) }
11545- jiffies = VVIRT(.jiffies);
11546-
11547 .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3))
11548 { *(.vsyscall_3) }
11549
017d2877
AM
11550@@ -125,16 +144,6 @@ SECTIONS
11551 #undef VVIRT_OFFSET
11552 #undef VVIRT
de855c5d 11553
017d2877
AM
11554- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
11555- . = ALIGN(THREAD_SIZE); /* init_task */
11556- *(.data.init_task)
11557- }:data.init
11558-
11559- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
11560- . = ALIGN(PAGE_SIZE);
11561- *(.data.page_aligned)
11562- }
11563-
2380c486 11564 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
017d2877
AM
11565 /* might get freed after init */
11566 . = ALIGN(PAGE_SIZE);
11567@@ -144,7 +153,7 @@ SECTIONS
11568 __smp_locks_end = .;
11569 . = ALIGN(PAGE_SIZE);
11570 __smp_alt_end = .;
2380c486 11571- }
de855c5d 11572+ }:data.init
017d2877
AM
11573
11574 . = ALIGN(PAGE_SIZE); /* Init code and data */
11575 __init_begin = .; /* paired with __init_end */
11576@@ -233,27 +242,20 @@ SECTIONS
2380c486
JR
11577 . = ALIGN(PAGE_SIZE);
11578 __init_end = .;
11579
017d2877
AM
11580- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
11581- . = ALIGN(PAGE_SIZE);
11582- __nosave_begin = .;
11583- *(.data.nosave)
11584- . = ALIGN(PAGE_SIZE);
11585- __nosave_end = .;
11586- } :data.init2 /* use another section data.init2, see PERCPU_VADDR() above */
2380c486 11587-
2380c486 11588 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
017d2877
AM
11589 . = ALIGN(PAGE_SIZE);
11590 __bss_start = .; /* BSS */
2380c486
JR
11591 *(.bss.page_aligned)
11592 *(.bss)
017d2877
AM
11593 __bss_stop = .;
11594- }
11595+ } :data.init2
11596
11597 .brk : AT(ADDR(.brk) - LOAD_OFFSET) {
11598 . = ALIGN(PAGE_SIZE);
11599 __brk_base = . ;
11600 . += 64 * 1024 ; /* 64k alignment slop space */
11601 *(.brk_reservation) /* areas brk users have reserved */
2380c486 11602+ . = ALIGN(2*1024*1024);
017d2877
AM
11603 __brk_limit = . ;
11604 }
2380c486 11605
017d2877
AM
11606@@ -276,7 +278,6 @@ SECTIONS
11607 * for the boot processor.
11608 */
11609 #define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load
11610-INIT_PER_CPU(gdt_page);
11611 INIT_PER_CPU(irq_stack_union);
11612
11613 /*
11614diff -urNp linux-2.6.30.4/arch/x86/kernel/vsyscall_64.c linux-2.6.30.4/arch/x86/kernel/vsyscall_64.c
11615--- linux-2.6.30.4/arch/x86/kernel/vsyscall_64.c 2009-07-24 17:47:51.000000000 -0400
11616+++ linux-2.6.30.4/arch/x86/kernel/vsyscall_64.c 2009-07-30 09:48:09.963690654 -0400
de855c5d
AM
11617@@ -79,6 +79,7 @@ void update_vsyscall(struct timespec *wa
11618
11619 write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags);
11620 /* copy vsyscall data */
11621+ strlcpy(vsyscall_gtod_data.clock.name, clock->name, sizeof vsyscall_gtod_data.clock.name);
11622 vsyscall_gtod_data.clock.vread = clock->vread;
11623 vsyscall_gtod_data.clock.cycle_last = clock->cycle_last;
11624 vsyscall_gtod_data.clock.mask = clock->mask;
017d2877 11625@@ -201,7 +202,7 @@ vgetcpu(unsigned *cpu, unsigned *node, s
de855c5d
AM
11626 We do this here because otherwise user space would do it on
11627 its own in a likely inferior way (no access to jiffies).
11628 If you don't like it pass NULL. */
11629- if (tcache && tcache->blob[0] == (j = __jiffies)) {
11630+ if (tcache && tcache->blob[0] == (j = jiffies)) {
11631 p = tcache->blob[1];
11632 } else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
11633 /* Load per CPU data from RDTSCP */
017d2877 11634@@ -240,13 +241,13 @@ static ctl_table kernel_table2[] = {
2380c486
JR
11635 .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
11636 .mode = 0644,
11637 .proc_handler = vsyscall_sysctl_change },
11638- {}
11639+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11640 };
11641
11642 static ctl_table kernel_root_table2[] = {
11643 { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
11644 .child = kernel_table2 },
11645- {}
11646+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11647 };
11648 #endif
11649
017d2877
AM
11650diff -urNp linux-2.6.30.4/arch/x86/kernel/x8664_ksyms_64.c linux-2.6.30.4/arch/x86/kernel/x8664_ksyms_64.c
11651--- linux-2.6.30.4/arch/x86/kernel/x8664_ksyms_64.c 2009-07-24 17:47:51.000000000 -0400
11652+++ linux-2.6.30.4/arch/x86/kernel/x8664_ksyms_64.c 2009-07-30 09:48:09.963690654 -0400
de855c5d
AM
11653@@ -30,8 +30,6 @@ EXPORT_SYMBOL(__put_user_8);
11654
11655 EXPORT_SYMBOL(copy_user_generic);
11656 EXPORT_SYMBOL(__copy_user_nocache);
11657-EXPORT_SYMBOL(copy_from_user);
11658-EXPORT_SYMBOL(copy_to_user);
11659 EXPORT_SYMBOL(__copy_from_user_inatomic);
11660
11661 EXPORT_SYMBOL(copy_page);
017d2877
AM
11662diff -urNp linux-2.6.30.4/arch/x86/kvm/svm.c linux-2.6.30.4/arch/x86/kvm/svm.c
11663--- linux-2.6.30.4/arch/x86/kvm/svm.c 2009-07-24 17:47:51.000000000 -0400
11664+++ linux-2.6.30.4/arch/x86/kvm/svm.c 2009-07-30 09:48:09.964534231 -0400
11665@@ -2226,7 +2226,19 @@ static void reload_tss(struct kvm_vcpu *
2380c486
JR
11666 int cpu = raw_smp_processor_id();
11667
11668 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
11669+
11670+#ifdef CONFIG_PAX_KERNEXEC
11671+ unsigned long cr0;
11672+
11673+ pax_open_kernel(cr0);
11674+#endif
11675+
11676 svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
11677+
11678+#ifdef CONFIG_PAX_KERNEXEC
11679+ pax_close_kernel(cr0);
11680+#endif
11681+
11682 load_TR_desc();
11683 }
11684
017d2877 11685@@ -2622,7 +2634,7 @@ static int svm_get_mt_mask_shift(void)
2380c486
JR
11686 return 0;
11687 }
11688
11689-static struct kvm_x86_ops svm_x86_ops = {
11690+static const struct kvm_x86_ops svm_x86_ops = {
11691 .cpu_has_kvm_support = has_svm,
11692 .disabled_by_bios = is_disabled,
11693 .hardware_setup = svm_hardware_setup,
017d2877
AM
11694diff -urNp linux-2.6.30.4/arch/x86/kvm/vmx.c linux-2.6.30.4/arch/x86/kvm/vmx.c
11695--- linux-2.6.30.4/arch/x86/kvm/vmx.c 2009-07-24 17:47:51.000000000 -0400
11696+++ linux-2.6.30.4/arch/x86/kvm/vmx.c 2009-07-30 09:48:09.965634801 -0400
11697@@ -506,9 +506,23 @@ static void reload_tss(void)
2380c486
JR
11698 struct descriptor_table gdt;
11699 struct desc_struct *descs;
11700
11701+#ifdef CONFIG_PAX_KERNEXEC
11702+ unsigned long cr0;
11703+#endif
11704+
11705 kvm_get_gdt(&gdt);
11706 descs = (void *)gdt.base;
11707+
11708+#ifdef CONFIG_PAX_KERNEXEC
11709+ pax_open_kernel(cr0);
11710+#endif
11711+
11712 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
11713+
11714+#ifdef CONFIG_PAX_KERNEXEC
11715+ pax_close_kernel(cr0);
11716+#endif
11717+
11718 load_TR_desc();
11719 }
11720
017d2877 11721@@ -2192,7 +2206,7 @@ static int vmx_vcpu_setup(struct vcpu_vm
2380c486
JR
11722 vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */
11723
11724 asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return));
11725- vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */
11726+ vmcs_writel(HOST_RIP, ktla_ktva(kvm_vmx_return)); /* 22.2.5 */
11727 vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0);
11728 vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0);
11729 vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0);
017d2877 11730@@ -3494,6 +3508,12 @@ static void vmx_vcpu_run(struct kvm_vcpu
2380c486
JR
11731 "jmp .Lkvm_vmx_return \n\t"
11732 ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
11733 ".Lkvm_vmx_return: "
11734+
11735+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
11736+ "ljmp %[cs],$.Lkvm_vmx_return2\n\t"
11737+ ".Lkvm_vmx_return2: "
11738+#endif
11739+
11740 /* Save guest registers, load host registers, keep flags */
11741 "xchg %0, (%%"R"sp) \n\t"
11742 "mov %%"R"ax, %c[rax](%0) \n\t"
017d2877 11743@@ -3540,6 +3560,11 @@ static void vmx_vcpu_run(struct kvm_vcpu
2380c486
JR
11744 [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
11745 #endif
11746 [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
11747+
11748+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
11749+ ,[cs]"i"(__KERNEL_CS)
11750+#endif
11751+
11752 : "cc", "memory"
11753 , R"bx", R"di", R"si"
11754 #ifdef CONFIG_X86_64
017d2877 11755@@ -3558,7 +3583,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
2380c486
JR
11756
11757 vmx_update_window_states(vcpu);
11758
11759- asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
11760+ asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
11761 vmx->launched = 1;
11762
11763 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
017d2877 11764@@ -3694,7 +3719,7 @@ static int vmx_get_mt_mask_shift(void)
2380c486
JR
11765 return VMX_EPT_MT_EPTE_SHIFT;
11766 }
11767
11768-static struct kvm_x86_ops vmx_x86_ops = {
11769+static const struct kvm_x86_ops vmx_x86_ops = {
11770 .cpu_has_kvm_support = cpu_has_kvm_support,
11771 .disabled_by_bios = vmx_disabled_by_bios,
11772 .hardware_setup = hardware_setup,
017d2877
AM
11773diff -urNp linux-2.6.30.4/arch/x86/kvm/x86.c linux-2.6.30.4/arch/x86/kvm/x86.c
11774--- linux-2.6.30.4/arch/x86/kvm/x86.c 2009-07-24 17:47:51.000000000 -0400
11775+++ linux-2.6.30.4/arch/x86/kvm/x86.c 2009-07-30 09:48:09.966523935 -0400
11776@@ -73,44 +73,44 @@ static int kvm_dev_ioctl_get_supported_c
11777 struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
11778 u32 function, u32 index);
2380c486
JR
11779
11780-struct kvm_x86_ops *kvm_x86_ops;
11781+const struct kvm_x86_ops *kvm_x86_ops;
11782 EXPORT_SYMBOL_GPL(kvm_x86_ops);
11783
11784 struct kvm_stats_debugfs_item debugfs_entries[] = {
11785- { "pf_fixed", VCPU_STAT(pf_fixed) },
11786- { "pf_guest", VCPU_STAT(pf_guest) },
11787- { "tlb_flush", VCPU_STAT(tlb_flush) },
11788- { "invlpg", VCPU_STAT(invlpg) },
11789- { "exits", VCPU_STAT(exits) },
11790- { "io_exits", VCPU_STAT(io_exits) },
11791- { "mmio_exits", VCPU_STAT(mmio_exits) },
11792- { "signal_exits", VCPU_STAT(signal_exits) },
11793- { "irq_window", VCPU_STAT(irq_window_exits) },
11794- { "nmi_window", VCPU_STAT(nmi_window_exits) },
11795- { "halt_exits", VCPU_STAT(halt_exits) },
11796- { "halt_wakeup", VCPU_STAT(halt_wakeup) },
11797- { "hypercalls", VCPU_STAT(hypercalls) },
11798- { "request_irq", VCPU_STAT(request_irq_exits) },
11799- { "request_nmi", VCPU_STAT(request_nmi_exits) },
11800- { "irq_exits", VCPU_STAT(irq_exits) },
11801- { "host_state_reload", VCPU_STAT(host_state_reload) },
11802- { "efer_reload", VCPU_STAT(efer_reload) },
11803- { "fpu_reload", VCPU_STAT(fpu_reload) },
11804- { "insn_emulation", VCPU_STAT(insn_emulation) },
11805- { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
11806- { "irq_injections", VCPU_STAT(irq_injections) },
11807- { "nmi_injections", VCPU_STAT(nmi_injections) },
11808- { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
11809- { "mmu_pte_write", VM_STAT(mmu_pte_write) },
11810- { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
11811- { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
11812- { "mmu_flooded", VM_STAT(mmu_flooded) },
11813- { "mmu_recycled", VM_STAT(mmu_recycled) },
11814- { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
11815- { "mmu_unsync", VM_STAT(mmu_unsync) },
11816- { "mmu_unsync_global", VM_STAT(mmu_unsync_global) },
11817- { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
11818- { "largepages", VM_STAT(lpages) },
11819+ { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
11820+ { "pf_guest", VCPU_STAT(pf_guest), NULL },
11821+ { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
11822+ { "invlpg", VCPU_STAT(invlpg), NULL },
11823+ { "exits", VCPU_STAT(exits), NULL },
11824+ { "io_exits", VCPU_STAT(io_exits), NULL },
11825+ { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
11826+ { "signal_exits", VCPU_STAT(signal_exits), NULL },
11827+ { "irq_window", VCPU_STAT(irq_window_exits), NULL },
11828+ { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
11829+ { "halt_exits", VCPU_STAT(halt_exits), NULL },
11830+ { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
11831+ { "hypercalls", VCPU_STAT(hypercalls), NULL },
11832+ { "request_irq", VCPU_STAT(request_irq_exits), NULL },
11833+ { "request_nmi", VCPU_STAT(request_nmi_exits), NULL },
11834+ { "irq_exits", VCPU_STAT(irq_exits), NULL },
11835+ { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
11836+ { "efer_reload", VCPU_STAT(efer_reload), NULL },
11837+ { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
11838+ { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
11839+ { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
11840+ { "irq_injections", VCPU_STAT(irq_injections), NULL },
11841+ { "nmi_injections", VCPU_STAT(nmi_injections), NULL },
11842+ { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
11843+ { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
11844+ { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
11845+ { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
11846+ { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
11847+ { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
11848+ { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
11849+ { "mmu_unsync", VM_STAT(mmu_unsync), NULL },
11850+ { "mmu_unsync_global", VM_STAT(mmu_unsync_global), NULL },
11851+ { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
11852+ { "largepages", VM_STAT(lpages), NULL },
11853 { NULL }
11854 };
11855
017d2877 11856@@ -1417,7 +1417,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
2380c486
JR
11857 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
11858 struct kvm_interrupt *irq)
11859 {
11860- if (irq->irq < 0 || irq->irq >= 256)
11861+ if (irq->irq >= 256)
11862 return -EINVAL;
11863 if (irqchip_in_kernel(vcpu->kvm))
11864 return -ENXIO;
017d2877
AM
11865@@ -2731,10 +2731,10 @@ static struct notifier_block kvmclock_cp
11866 .notifier_call = kvmclock_cpufreq_notifier
11867 };
2380c486
JR
11868
11869-int kvm_arch_init(void *opaque)
11870+int kvm_arch_init(const void *opaque)
11871 {
017d2877 11872 int r, cpu;
2380c486
JR
11873- struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
11874+ const struct kvm_x86_ops *ops = (const struct kvm_x86_ops *)opaque;
11875
11876 if (kvm_x86_ops) {
11877 printk(KERN_ERR "kvm: already loaded the other module\n");
017d2877
AM
11878diff -urNp linux-2.6.30.4/arch/x86/lib/checksum_32.S linux-2.6.30.4/arch/x86/lib/checksum_32.S
11879--- linux-2.6.30.4/arch/x86/lib/checksum_32.S 2009-07-24 17:47:51.000000000 -0400
11880+++ linux-2.6.30.4/arch/x86/lib/checksum_32.S 2009-07-30 09:48:09.967600435 -0400
2380c486
JR
11881@@ -28,7 +28,8 @@
11882 #include <linux/linkage.h>
11883 #include <asm/dwarf2.h>
11884 #include <asm/errno.h>
11885-
11886+#include <asm/segment.h>
11887+
11888 /*
11889 * computes a partial checksum, e.g. for TCP/UDP fragments
11890 */
11891@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
11892
11893 #define ARGBASE 16
11894 #define FP 12
11895-
11896-ENTRY(csum_partial_copy_generic)
11897+
11898+ENTRY(csum_partial_copy_generic_to_user)
11899 CFI_STARTPROC
11900+ pushl $(__USER_DS)
11901+ CFI_ADJUST_CFA_OFFSET 4
11902+ popl %es
11903+ CFI_ADJUST_CFA_OFFSET -4
11904+ jmp csum_partial_copy_generic
11905+
11906+ENTRY(csum_partial_copy_generic_from_user)
11907+ pushl $(__USER_DS)
11908+ CFI_ADJUST_CFA_OFFSET 4
11909+ popl %ds
11910+ CFI_ADJUST_CFA_OFFSET -4
11911+
11912+ENTRY(csum_partial_copy_generic)
11913 subl $4,%esp
11914 CFI_ADJUST_CFA_OFFSET 4
11915 pushl %edi
11916@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
11917 jmp 4f
11918 SRC(1: movw (%esi), %bx )
11919 addl $2, %esi
11920-DST( movw %bx, (%edi) )
11921+DST( movw %bx, %es:(%edi) )
11922 addl $2, %edi
11923 addw %bx, %ax
11924 adcl $0, %eax
11925@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
11926 SRC(1: movl (%esi), %ebx )
11927 SRC( movl 4(%esi), %edx )
11928 adcl %ebx, %eax
11929-DST( movl %ebx, (%edi) )
11930+DST( movl %ebx, %es:(%edi) )
11931 adcl %edx, %eax
11932-DST( movl %edx, 4(%edi) )
11933+DST( movl %edx, %es:4(%edi) )
11934
11935 SRC( movl 8(%esi), %ebx )
11936 SRC( movl 12(%esi), %edx )
11937 adcl %ebx, %eax
11938-DST( movl %ebx, 8(%edi) )
11939+DST( movl %ebx, %es:8(%edi) )
11940 adcl %edx, %eax
11941-DST( movl %edx, 12(%edi) )
11942+DST( movl %edx, %es:12(%edi) )
11943
11944 SRC( movl 16(%esi), %ebx )
11945 SRC( movl 20(%esi), %edx )
11946 adcl %ebx, %eax
11947-DST( movl %ebx, 16(%edi) )
11948+DST( movl %ebx, %es:16(%edi) )
11949 adcl %edx, %eax
11950-DST( movl %edx, 20(%edi) )
11951+DST( movl %edx, %es:20(%edi) )
11952
11953 SRC( movl 24(%esi), %ebx )
11954 SRC( movl 28(%esi), %edx )
11955 adcl %ebx, %eax
11956-DST( movl %ebx, 24(%edi) )
11957+DST( movl %ebx, %es:24(%edi) )
11958 adcl %edx, %eax
11959-DST( movl %edx, 28(%edi) )
11960+DST( movl %edx, %es:28(%edi) )
11961
11962 lea 32(%esi), %esi
11963 lea 32(%edi), %edi
11964@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
11965 shrl $2, %edx # This clears CF
11966 SRC(3: movl (%esi), %ebx )
11967 adcl %ebx, %eax
11968-DST( movl %ebx, (%edi) )
11969+DST( movl %ebx, %es:(%edi) )
11970 lea 4(%esi), %esi
11971 lea 4(%edi), %edi
11972 dec %edx
11973@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
11974 jb 5f
11975 SRC( movw (%esi), %cx )
11976 leal 2(%esi), %esi
11977-DST( movw %cx, (%edi) )
11978+DST( movw %cx, %es:(%edi) )
11979 leal 2(%edi), %edi
11980 je 6f
11981 shll $16,%ecx
11982 SRC(5: movb (%esi), %cl )
11983-DST( movb %cl, (%edi) )
11984+DST( movb %cl, %es:(%edi) )
11985 6: addl %ecx, %eax
11986 adcl $0, %eax
11987 7:
11988@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
11989
11990 6001:
11991 movl ARGBASE+20(%esp), %ebx # src_err_ptr
11992- movl $-EFAULT, (%ebx)
11993+ movl $-EFAULT, %ss:(%ebx)
11994
11995 # zero the complete destination - computing the rest
11996 # is too much work
11997@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
11998
11999 6002:
12000 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
12001- movl $-EFAULT,(%ebx)
12002+ movl $-EFAULT,%ss:(%ebx)
12003 jmp 5000b
12004
12005 .previous
12006
12007+ pushl %ss
12008+ CFI_ADJUST_CFA_OFFSET 4
12009+ popl %ds
12010+ CFI_ADJUST_CFA_OFFSET -4
12011+ pushl %ss
12012+ CFI_ADJUST_CFA_OFFSET 4
12013+ popl %es
12014+ CFI_ADJUST_CFA_OFFSET -4
12015 popl %ebx
12016 CFI_ADJUST_CFA_OFFSET -4
12017 CFI_RESTORE ebx
12018@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
12019 CFI_ADJUST_CFA_OFFSET -4
12020 ret
12021 CFI_ENDPROC
12022-ENDPROC(csum_partial_copy_generic)
12023+ENDPROC(csum_partial_copy_generic_to_user)
12024
12025 #else
12026
12027 /* Version for PentiumII/PPro */
12028
12029 #define ROUND1(x) \
12030+ nop; nop; nop; \
12031 SRC(movl x(%esi), %ebx ) ; \
12032 addl %ebx, %eax ; \
12033- DST(movl %ebx, x(%edi) ) ;
12034+ DST(movl %ebx, %es:x(%edi)) ;
12035
12036 #define ROUND(x) \
12037+ nop; nop; nop; \
12038 SRC(movl x(%esi), %ebx ) ; \
12039 adcl %ebx, %eax ; \
12040- DST(movl %ebx, x(%edi) ) ;
12041+ DST(movl %ebx, %es:x(%edi)) ;
12042
12043 #define ARGBASE 12
12044-
12045-ENTRY(csum_partial_copy_generic)
12046+
12047+ENTRY(csum_partial_copy_generic_to_user)
12048 CFI_STARTPROC
12049+ pushl $(__USER_DS)
12050+ CFI_ADJUST_CFA_OFFSET 4
12051+ popl %es
12052+ CFI_ADJUST_CFA_OFFSET -4
12053+ jmp csum_partial_copy_generic
12054+
12055+ENTRY(csum_partial_copy_generic_from_user)
12056+ pushl $(__USER_DS)
12057+ CFI_ADJUST_CFA_OFFSET 4
12058+ popl %ds
12059+ CFI_ADJUST_CFA_OFFSET -4
12060+
12061+ENTRY(csum_partial_copy_generic)
12062 pushl %ebx
12063 CFI_ADJUST_CFA_OFFSET 4
12064 CFI_REL_OFFSET ebx, 0
12065@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
12066 subl %ebx, %edi
12067 lea -1(%esi),%edx
12068 andl $-32,%edx
12069- lea 3f(%ebx,%ebx), %ebx
12070+ lea 3f(%ebx,%ebx,2), %ebx
12071 testl %esi, %esi
12072 jmp *%ebx
12073 1: addl $64,%esi
12074@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
12075 jb 5f
12076 SRC( movw (%esi), %dx )
12077 leal 2(%esi), %esi
12078-DST( movw %dx, (%edi) )
12079+DST( movw %dx, %es:(%edi) )
12080 leal 2(%edi), %edi
12081 je 6f
12082 shll $16,%edx
12083 5:
12084 SRC( movb (%esi), %dl )
12085-DST( movb %dl, (%edi) )
12086+DST( movb %dl, %es:(%edi) )
12087 6: addl %edx, %eax
12088 adcl $0, %eax
12089 7:
12090 .section .fixup, "ax"
12091 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
12092- movl $-EFAULT, (%ebx)
12093+ movl $-EFAULT, %ss:(%ebx)
12094 # zero the complete destination (computing the rest is too much work)
12095 movl ARGBASE+8(%esp),%edi # dst
12096 movl ARGBASE+12(%esp),%ecx # len
12097@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
12098 rep; stosb
12099 jmp 7b
12100 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
12101- movl $-EFAULT, (%ebx)
12102+ movl $-EFAULT, %ss:(%ebx)
12103 jmp 7b
12104 .previous
12105
12106+ pushl %ss
12107+ CFI_ADJUST_CFA_OFFSET 4
12108+ popl %ds
12109+ CFI_ADJUST_CFA_OFFSET -4
12110+ pushl %ss
12111+ CFI_ADJUST_CFA_OFFSET 4
12112+ popl %es
12113+ CFI_ADJUST_CFA_OFFSET -4
12114 popl %esi
12115 CFI_ADJUST_CFA_OFFSET -4
12116 CFI_RESTORE esi
12117@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
12118 CFI_RESTORE ebx
12119 ret
12120 CFI_ENDPROC
12121-ENDPROC(csum_partial_copy_generic)
12122+ENDPROC(csum_partial_copy_generic_to_user)
12123
12124 #undef ROUND
12125 #undef ROUND1
017d2877
AM
12126diff -urNp linux-2.6.30.4/arch/x86/lib/clear_page_64.S linux-2.6.30.4/arch/x86/lib/clear_page_64.S
12127--- linux-2.6.30.4/arch/x86/lib/clear_page_64.S 2009-07-24 17:47:51.000000000 -0400
12128+++ linux-2.6.30.4/arch/x86/lib/clear_page_64.S 2009-07-30 09:48:09.967600435 -0400
2380c486
JR
12129@@ -44,7 +44,7 @@ ENDPROC(clear_page)
12130
12131 #include <asm/cpufeature.h>
12132
12133- .section .altinstr_replacement,"ax"
12134+ .section .altinstr_replacement,"a"
12135 1: .byte 0xeb /* jmp <disp8> */
12136 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
12137 2:
017d2877
AM
12138diff -urNp linux-2.6.30.4/arch/x86/lib/copy_page_64.S linux-2.6.30.4/arch/x86/lib/copy_page_64.S
12139--- linux-2.6.30.4/arch/x86/lib/copy_page_64.S 2009-07-24 17:47:51.000000000 -0400
12140+++ linux-2.6.30.4/arch/x86/lib/copy_page_64.S 2009-07-30 09:48:09.967600435 -0400
2380c486
JR
12141@@ -104,7 +104,7 @@ ENDPROC(copy_page)
12142
12143 #include <asm/cpufeature.h>
12144
12145- .section .altinstr_replacement,"ax"
12146+ .section .altinstr_replacement,"a"
12147 1: .byte 0xeb /* jmp <disp8> */
12148 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
12149 2:
017d2877
AM
12150diff -urNp linux-2.6.30.4/arch/x86/lib/copy_user_64.S linux-2.6.30.4/arch/x86/lib/copy_user_64.S
12151--- linux-2.6.30.4/arch/x86/lib/copy_user_64.S 2009-07-24 17:47:51.000000000 -0400
12152+++ linux-2.6.30.4/arch/x86/lib/copy_user_64.S 2009-07-30 09:48:09.967600435 -0400
2380c486
JR
12153@@ -21,7 +21,7 @@
12154 .byte 0xe9 /* 32bit jump */
12155 .long \orig-1f /* by default jump to orig */
12156 1:
12157- .section .altinstr_replacement,"ax"
12158+ .section .altinstr_replacement,"a"
12159 2: .byte 0xe9 /* near jump with 32bit immediate */
12160 .long \alt-1b /* offset */ /* or alternatively to alt */
12161 .previous
de855c5d
AM
12162@@ -64,31 +64,6 @@
12163 #endif
12164 .endm
12165
12166-/* Standard copy_to_user with segment limit checking */
12167-ENTRY(copy_to_user)
12168- CFI_STARTPROC
12169- GET_THREAD_INFO(%rax)
12170- movq %rdi,%rcx
12171- addq %rdx,%rcx
12172- jc bad_to_user
12173- cmpq TI_addr_limit(%rax),%rcx
12174- jae bad_to_user
12175- ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
12176- CFI_ENDPROC
12177-
12178-/* Standard copy_from_user with segment limit checking */
12179-ENTRY(copy_from_user)
12180- CFI_STARTPROC
12181- GET_THREAD_INFO(%rax)
12182- movq %rsi,%rcx
12183- addq %rdx,%rcx
12184- jc bad_from_user
12185- cmpq TI_addr_limit(%rax),%rcx
12186- jae bad_from_user
12187- ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
12188- CFI_ENDPROC
12189-ENDPROC(copy_from_user)
12190-
12191 ENTRY(copy_user_generic)
12192 CFI_STARTPROC
12193 ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
12194@@ -106,6 +81,8 @@ ENDPROC(__copy_from_user_inatomic)
2380c486
JR
12195 ENTRY(bad_from_user)
12196 bad_from_user:
12197 CFI_STARTPROC
12198+ testl %edx,%edx
12199+ js bad_to_user
12200 movl %edx,%ecx
12201 xorl %eax,%eax
12202 rep
017d2877
AM
12203diff -urNp linux-2.6.30.4/arch/x86/lib/getuser.S linux-2.6.30.4/arch/x86/lib/getuser.S
12204--- linux-2.6.30.4/arch/x86/lib/getuser.S 2009-07-24 17:47:51.000000000 -0400
12205+++ linux-2.6.30.4/arch/x86/lib/getuser.S 2009-07-30 09:48:09.967600435 -0400
2380c486
JR
12206@@ -33,6 +33,7 @@
12207 #include <asm/asm-offsets.h>
12208 #include <asm/thread_info.h>
12209 #include <asm/asm.h>
12210+#include <asm/segment.h>
12211
12212 .text
12213 ENTRY(__get_user_1)
12214@@ -40,7 +41,19 @@ ENTRY(__get_user_1)
12215 GET_THREAD_INFO(%_ASM_DX)
12216 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
12217 jae bad_get_user
12218+
12219+#ifdef CONFIG_X86_32
12220+ pushl $(__USER_DS)
12221+ popl %ds
12222+#endif
12223+
12224 1: movzb (%_ASM_AX),%edx
12225+
12226+#ifdef CONFIG_X86_32
12227+ pushl %ss
12228+ pop %ds
12229+#endif
12230+
12231 xor %eax,%eax
12232 ret
12233 CFI_ENDPROC
12234@@ -53,7 +66,19 @@ ENTRY(__get_user_2)
12235 GET_THREAD_INFO(%_ASM_DX)
12236 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
12237 jae bad_get_user
12238+
12239+#ifdef CONFIG_X86_32
12240+ pushl $(__USER_DS)
12241+ popl %ds
12242+#endif
12243+
12244 2: movzwl -1(%_ASM_AX),%edx
12245+
12246+#ifdef CONFIG_X86_32
12247+ pushl %ss
12248+ pop %ds
12249+#endif
12250+
12251 xor %eax,%eax
12252 ret
12253 CFI_ENDPROC
12254@@ -66,7 +91,19 @@ ENTRY(__get_user_4)
12255 GET_THREAD_INFO(%_ASM_DX)
12256 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
12257 jae bad_get_user
12258+
12259+#ifdef CONFIG_X86_32
12260+ pushl $(__USER_DS)
12261+ popl %ds
12262+#endif
12263+
12264 3: mov -3(%_ASM_AX),%edx
12265+
12266+#ifdef CONFIG_X86_32
12267+ pushl %ss
12268+ pop %ds
12269+#endif
12270+
12271 xor %eax,%eax
12272 ret
12273 CFI_ENDPROC
12274@@ -89,6 +126,12 @@ ENDPROC(__get_user_8)
12275
12276 bad_get_user:
12277 CFI_STARTPROC
12278+
12279+#ifdef CONFIG_X86_32
12280+ pushl %ss
12281+ pop %ds
12282+#endif
12283+
12284 xor %edx,%edx
12285 mov $(-EFAULT),%_ASM_AX
12286 ret
017d2877
AM
12287diff -urNp linux-2.6.30.4/arch/x86/lib/memcpy_64.S linux-2.6.30.4/arch/x86/lib/memcpy_64.S
12288--- linux-2.6.30.4/arch/x86/lib/memcpy_64.S 2009-07-24 17:47:51.000000000 -0400
12289+++ linux-2.6.30.4/arch/x86/lib/memcpy_64.S 2009-07-30 09:48:09.968548540 -0400
12290@@ -128,7 +128,7 @@ ENDPROC(__memcpy)
12291 * It is also a lot simpler. Use this when possible:
12292 */
2380c486 12293
017d2877
AM
12294- .section .altinstr_replacement, "ax"
12295+ .section .altinstr_replacement, "a"
2380c486
JR
12296 1: .byte 0xeb /* jmp <disp8> */
12297 .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
12298 2:
017d2877
AM
12299diff -urNp linux-2.6.30.4/arch/x86/lib/memset_64.S linux-2.6.30.4/arch/x86/lib/memset_64.S
12300--- linux-2.6.30.4/arch/x86/lib/memset_64.S 2009-07-24 17:47:51.000000000 -0400
12301+++ linux-2.6.30.4/arch/x86/lib/memset_64.S 2009-07-30 09:48:09.968548540 -0400
2380c486
JR
12302@@ -118,7 +118,7 @@ ENDPROC(__memset)
12303
12304 #include <asm/cpufeature.h>
12305
12306- .section .altinstr_replacement,"ax"
12307+ .section .altinstr_replacement,"a"
12308 1: .byte 0xeb /* jmp <disp8> */
12309 .byte (memset_c - memset) - (2f - 1b) /* offset */
12310 2:
017d2877
AM
12311diff -urNp linux-2.6.30.4/arch/x86/lib/mmx_32.c linux-2.6.30.4/arch/x86/lib/mmx_32.c
12312--- linux-2.6.30.4/arch/x86/lib/mmx_32.c 2009-07-24 17:47:51.000000000 -0400
12313+++ linux-2.6.30.4/arch/x86/lib/mmx_32.c 2009-07-30 09:48:09.968548540 -0400
2380c486
JR
12314@@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
12315 {
12316 void *p;
12317 int i;
12318+ unsigned long cr0;
12319
12320 if (unlikely(in_interrupt()))
12321 return __memcpy(to, from, len);
12322@@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
12323 kernel_fpu_begin();
12324
12325 __asm__ __volatile__ (
12326- "1: prefetch (%0)\n" /* This set is 28 bytes */
12327- " prefetch 64(%0)\n"
12328- " prefetch 128(%0)\n"
12329- " prefetch 192(%0)\n"
12330- " prefetch 256(%0)\n"
12331+ "1: prefetch (%1)\n" /* This set is 28 bytes */
12332+ " prefetch 64(%1)\n"
12333+ " prefetch 128(%1)\n"
12334+ " prefetch 192(%1)\n"
12335+ " prefetch 256(%1)\n"
12336 "2: \n"
12337 ".section .fixup, \"ax\"\n"
12338- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
12339+ "3: \n"
12340+
12341+#ifdef CONFIG_PAX_KERNEXEC
12342+ " movl %%cr0, %0\n"
12343+ " movl %0, %%eax\n"
12344+ " andl $0xFFFEFFFF, %%eax\n"
12345+ " movl %%eax, %%cr0\n"
12346+#endif
12347+
12348+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
12349+
12350+#ifdef CONFIG_PAX_KERNEXEC
12351+ " movl %0, %%cr0\n"
12352+#endif
12353+
12354 " jmp 2b\n"
12355 ".previous\n"
12356 _ASM_EXTABLE(1b, 3b)
12357- : : "r" (from));
12358+ : "=&r" (cr0) : "r" (from) : "ax");
12359
12360 for ( ; i > 5; i--) {
12361 __asm__ __volatile__ (
12362- "1: prefetch 320(%0)\n"
12363- "2: movq (%0), %%mm0\n"
12364- " movq 8(%0), %%mm1\n"
12365- " movq 16(%0), %%mm2\n"
12366- " movq 24(%0), %%mm3\n"
12367- " movq %%mm0, (%1)\n"
12368- " movq %%mm1, 8(%1)\n"
12369- " movq %%mm2, 16(%1)\n"
12370- " movq %%mm3, 24(%1)\n"
12371- " movq 32(%0), %%mm0\n"
12372- " movq 40(%0), %%mm1\n"
12373- " movq 48(%0), %%mm2\n"
12374- " movq 56(%0), %%mm3\n"
12375- " movq %%mm0, 32(%1)\n"
12376- " movq %%mm1, 40(%1)\n"
12377- " movq %%mm2, 48(%1)\n"
12378- " movq %%mm3, 56(%1)\n"
12379+ "1: prefetch 320(%1)\n"
12380+ "2: movq (%1), %%mm0\n"
12381+ " movq 8(%1), %%mm1\n"
12382+ " movq 16(%1), %%mm2\n"
12383+ " movq 24(%1), %%mm3\n"
12384+ " movq %%mm0, (%2)\n"
12385+ " movq %%mm1, 8(%2)\n"
12386+ " movq %%mm2, 16(%2)\n"
12387+ " movq %%mm3, 24(%2)\n"
12388+ " movq 32(%1), %%mm0\n"
12389+ " movq 40(%1), %%mm1\n"
12390+ " movq 48(%1), %%mm2\n"
12391+ " movq 56(%1), %%mm3\n"
12392+ " movq %%mm0, 32(%2)\n"
12393+ " movq %%mm1, 40(%2)\n"
12394+ " movq %%mm2, 48(%2)\n"
12395+ " movq %%mm3, 56(%2)\n"
12396 ".section .fixup, \"ax\"\n"
12397- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
12398+ "3:\n"
12399+
12400+#ifdef CONFIG_PAX_KERNEXEC
12401+ " movl %%cr0, %0\n"
12402+ " movl %0, %%eax\n"
12403+ " andl $0xFFFEFFFF, %%eax\n"
12404+ " movl %%eax, %%cr0\n"
12405+#endif
12406+
12407+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
12408+
12409+#ifdef CONFIG_PAX_KERNEXEC
12410+ " movl %0, %%cr0\n"
12411+#endif
12412+
12413 " jmp 2b\n"
12414 ".previous\n"
12415 _ASM_EXTABLE(1b, 3b)
12416- : : "r" (from), "r" (to) : "memory");
12417+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
12418
12419 from += 64;
12420 to += 64;
12421@@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
12422 static void fast_copy_page(void *to, void *from)
12423 {
12424 int i;
12425+ unsigned long cr0;
12426
12427 kernel_fpu_begin();
12428
12429@@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
12430 * but that is for later. -AV
12431 */
12432 __asm__ __volatile__(
12433- "1: prefetch (%0)\n"
12434- " prefetch 64(%0)\n"
12435- " prefetch 128(%0)\n"
12436- " prefetch 192(%0)\n"
12437- " prefetch 256(%0)\n"
12438+ "1: prefetch (%1)\n"
12439+ " prefetch 64(%1)\n"
12440+ " prefetch 128(%1)\n"
12441+ " prefetch 192(%1)\n"
12442+ " prefetch 256(%1)\n"
12443 "2: \n"
12444 ".section .fixup, \"ax\"\n"
12445- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
12446+ "3: \n"
12447+
12448+#ifdef CONFIG_PAX_KERNEXEC
12449+ " movl %%cr0, %0\n"
12450+ " movl %0, %%eax\n"
12451+ " andl $0xFFFEFFFF, %%eax\n"
12452+ " movl %%eax, %%cr0\n"
12453+#endif
12454+
12455+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
12456+
12457+#ifdef CONFIG_PAX_KERNEXEC
12458+ " movl %0, %%cr0\n"
12459+#endif
12460+
12461 " jmp 2b\n"
12462 ".previous\n"
12463- _ASM_EXTABLE(1b, 3b) : : "r" (from));
12464+ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
12465
12466 for (i = 0; i < (4096-320)/64; i++) {
12467 __asm__ __volatile__ (
12468- "1: prefetch 320(%0)\n"
12469- "2: movq (%0), %%mm0\n"
12470- " movntq %%mm0, (%1)\n"
12471- " movq 8(%0), %%mm1\n"
12472- " movntq %%mm1, 8(%1)\n"
12473- " movq 16(%0), %%mm2\n"
12474- " movntq %%mm2, 16(%1)\n"
12475- " movq 24(%0), %%mm3\n"
12476- " movntq %%mm3, 24(%1)\n"
12477- " movq 32(%0), %%mm4\n"
12478- " movntq %%mm4, 32(%1)\n"
12479- " movq 40(%0), %%mm5\n"
12480- " movntq %%mm5, 40(%1)\n"
12481- " movq 48(%0), %%mm6\n"
12482- " movntq %%mm6, 48(%1)\n"
12483- " movq 56(%0), %%mm7\n"
12484- " movntq %%mm7, 56(%1)\n"
12485+ "1: prefetch 320(%1)\n"
12486+ "2: movq (%1), %%mm0\n"
12487+ " movntq %%mm0, (%2)\n"
12488+ " movq 8(%1), %%mm1\n"
12489+ " movntq %%mm1, 8(%2)\n"
12490+ " movq 16(%1), %%mm2\n"
12491+ " movntq %%mm2, 16(%2)\n"
12492+ " movq 24(%1), %%mm3\n"
12493+ " movntq %%mm3, 24(%2)\n"
12494+ " movq 32(%1), %%mm4\n"
12495+ " movntq %%mm4, 32(%2)\n"
12496+ " movq 40(%1), %%mm5\n"
12497+ " movntq %%mm5, 40(%2)\n"
12498+ " movq 48(%1), %%mm6\n"
12499+ " movntq %%mm6, 48(%2)\n"
12500+ " movq 56(%1), %%mm7\n"
12501+ " movntq %%mm7, 56(%2)\n"
12502 ".section .fixup, \"ax\"\n"
12503- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
12504+ "3:\n"
12505+
12506+#ifdef CONFIG_PAX_KERNEXEC
12507+ " movl %%cr0, %0\n"
12508+ " movl %0, %%eax\n"
12509+ " andl $0xFFFEFFFF, %%eax\n"
12510+ " movl %%eax, %%cr0\n"
12511+#endif
12512+
12513+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
12514+
12515+#ifdef CONFIG_PAX_KERNEXEC
12516+ " movl %0, %%cr0\n"
12517+#endif
12518+
12519 " jmp 2b\n"
12520 ".previous\n"
12521- _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
12522+ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
12523
12524 from += 64;
12525 to += 64;
12526@@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
12527 static void fast_copy_page(void *to, void *from)
12528 {
12529 int i;
12530+ unsigned long cr0;
12531
12532 kernel_fpu_begin();
12533
12534 __asm__ __volatile__ (
12535- "1: prefetch (%0)\n"
12536- " prefetch 64(%0)\n"
12537- " prefetch 128(%0)\n"
12538- " prefetch 192(%0)\n"
12539- " prefetch 256(%0)\n"
12540+ "1: prefetch (%1)\n"
12541+ " prefetch 64(%1)\n"
12542+ " prefetch 128(%1)\n"
12543+ " prefetch 192(%1)\n"
12544+ " prefetch 256(%1)\n"
12545 "2: \n"
12546 ".section .fixup, \"ax\"\n"
12547- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
12548+ "3: \n"
12549+
12550+#ifdef CONFIG_PAX_KERNEXEC
12551+ " movl %%cr0, %0\n"
12552+ " movl %0, %%eax\n"
12553+ " andl $0xFFFEFFFF, %%eax\n"
12554+ " movl %%eax, %%cr0\n"
12555+#endif
12556+
12557+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
12558+
12559+#ifdef CONFIG_PAX_KERNEXEC
12560+ " movl %0, %%cr0\n"
12561+#endif
12562+
12563 " jmp 2b\n"
12564 ".previous\n"
12565- _ASM_EXTABLE(1b, 3b) : : "r" (from));
12566+ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
12567
12568 for (i = 0; i < 4096/64; i++) {
12569 __asm__ __volatile__ (
12570- "1: prefetch 320(%0)\n"
12571- "2: movq (%0), %%mm0\n"
12572- " movq 8(%0), %%mm1\n"
12573- " movq 16(%0), %%mm2\n"
12574- " movq 24(%0), %%mm3\n"
12575- " movq %%mm0, (%1)\n"
12576- " movq %%mm1, 8(%1)\n"
12577- " movq %%mm2, 16(%1)\n"
12578- " movq %%mm3, 24(%1)\n"
12579- " movq 32(%0), %%mm0\n"
12580- " movq 40(%0), %%mm1\n"
12581- " movq 48(%0), %%mm2\n"
12582- " movq 56(%0), %%mm3\n"
12583- " movq %%mm0, 32(%1)\n"
12584- " movq %%mm1, 40(%1)\n"
12585- " movq %%mm2, 48(%1)\n"
12586- " movq %%mm3, 56(%1)\n"
12587+ "1: prefetch 320(%1)\n"
12588+ "2: movq (%1), %%mm0\n"
12589+ " movq 8(%1), %%mm1\n"
12590+ " movq 16(%1), %%mm2\n"
12591+ " movq 24(%1), %%mm3\n"
12592+ " movq %%mm0, (%2)\n"
12593+ " movq %%mm1, 8(%2)\n"
12594+ " movq %%mm2, 16(%2)\n"
12595+ " movq %%mm3, 24(%2)\n"
12596+ " movq 32(%1), %%mm0\n"
12597+ " movq 40(%1), %%mm1\n"
12598+ " movq 48(%1), %%mm2\n"
12599+ " movq 56(%1), %%mm3\n"
12600+ " movq %%mm0, 32(%2)\n"
12601+ " movq %%mm1, 40(%2)\n"
12602+ " movq %%mm2, 48(%2)\n"
12603+ " movq %%mm3, 56(%2)\n"
12604 ".section .fixup, \"ax\"\n"
12605- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
12606+ "3:\n"
12607+
12608+#ifdef CONFIG_PAX_KERNEXEC
12609+ " movl %%cr0, %0\n"
12610+ " movl %0, %%eax\n"
12611+ " andl $0xFFFEFFFF, %%eax\n"
12612+ " movl %%eax, %%cr0\n"
12613+#endif
12614+
12615+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
12616+
12617+#ifdef CONFIG_PAX_KERNEXEC
12618+ " movl %0, %%cr0\n"
12619+#endif
12620+
12621 " jmp 2b\n"
12622 ".previous\n"
12623 _ASM_EXTABLE(1b, 3b)
12624- : : "r" (from), "r" (to) : "memory");
12625+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
12626
12627 from += 64;
12628 to += 64;
017d2877
AM
12629diff -urNp linux-2.6.30.4/arch/x86/lib/putuser.S linux-2.6.30.4/arch/x86/lib/putuser.S
12630--- linux-2.6.30.4/arch/x86/lib/putuser.S 2009-07-24 17:47:51.000000000 -0400
12631+++ linux-2.6.30.4/arch/x86/lib/putuser.S 2009-07-30 09:48:09.969494268 -0400
2380c486
JR
12632@@ -15,6 +15,7 @@
12633 #include <asm/thread_info.h>
12634 #include <asm/errno.h>
12635 #include <asm/asm.h>
12636+#include <asm/segment.h>
12637
12638
12639 /*
12640@@ -39,7 +40,19 @@ ENTRY(__put_user_1)
12641 ENTER
12642 cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
12643 jae bad_put_user
12644+
12645+#ifdef CONFIG_X86_32
12646+ pushl $(__USER_DS)
12647+ popl %ds
12648+#endif
12649+
12650 1: movb %al,(%_ASM_CX)
12651+
12652+#ifdef CONFIG_X86_32
12653+ pushl %ss
12654+ popl %ds
12655+#endif
12656+
12657 xor %eax,%eax
12658 EXIT
12659 ENDPROC(__put_user_1)
12660@@ -50,7 +63,19 @@ ENTRY(__put_user_2)
12661 sub $1,%_ASM_BX
12662 cmp %_ASM_BX,%_ASM_CX
12663 jae bad_put_user
12664+
12665+#ifdef CONFIG_X86_32
12666+ pushl $(__USER_DS)
12667+ popl %ds
12668+#endif
12669+
12670 2: movw %ax,(%_ASM_CX)
12671+
12672+#ifdef CONFIG_X86_32
12673+ pushl %ss
12674+ popl %ds
12675+#endif
12676+
12677 xor %eax,%eax
12678 EXIT
12679 ENDPROC(__put_user_2)
12680@@ -61,7 +86,19 @@ ENTRY(__put_user_4)
12681 sub $3,%_ASM_BX
12682 cmp %_ASM_BX,%_ASM_CX
12683 jae bad_put_user
12684+
12685+#ifdef CONFIG_X86_32
12686+ pushl $(__USER_DS)
12687+ popl %ds
12688+#endif
12689+
12690 3: movl %eax,(%_ASM_CX)
12691+
12692+#ifdef CONFIG_X86_32
12693+ pushl %ss
12694+ popl %ds
12695+#endif
12696+
12697 xor %eax,%eax
12698 EXIT
12699 ENDPROC(__put_user_4)
12700@@ -72,16 +109,34 @@ ENTRY(__put_user_8)
12701 sub $7,%_ASM_BX
12702 cmp %_ASM_BX,%_ASM_CX
12703 jae bad_put_user
12704+
12705+#ifdef CONFIG_X86_32
12706+ pushl $(__USER_DS)
12707+ popl %ds
12708+#endif
12709+
12710 4: mov %_ASM_AX,(%_ASM_CX)
12711 #ifdef CONFIG_X86_32
12712 5: movl %edx,4(%_ASM_CX)
12713 #endif
12714+
12715+#ifdef CONFIG_X86_32
12716+ pushl %ss
12717+ popl %ds
12718+#endif
12719+
12720 xor %eax,%eax
12721 EXIT
12722 ENDPROC(__put_user_8)
12723
12724 bad_put_user:
12725 CFI_STARTPROC
12726+
12727+#ifdef CONFIG_X86_32
12728+ pushl %ss
12729+ popl %ds
12730+#endif
12731+
12732 movl $-EFAULT,%eax
12733 EXIT
12734 END(bad_put_user)
017d2877
AM
12735diff -urNp linux-2.6.30.4/arch/x86/lib/usercopy_32.c linux-2.6.30.4/arch/x86/lib/usercopy_32.c
12736--- linux-2.6.30.4/arch/x86/lib/usercopy_32.c 2009-07-24 17:47:51.000000000 -0400
12737+++ linux-2.6.30.4/arch/x86/lib/usercopy_32.c 2009-07-30 09:48:09.969494268 -0400
2380c486
JR
12738@@ -36,31 +36,38 @@ static inline int __movsl_is_ok(unsigned
12739 * Copy a null terminated string from userspace.
12740 */
12741
12742-#define __do_strncpy_from_user(dst, src, count, res) \
12743-do { \
12744- int __d0, __d1, __d2; \
12745- might_fault(); \
12746- __asm__ __volatile__( \
12747- " testl %1,%1\n" \
12748- " jz 2f\n" \
12749- "0: lodsb\n" \
12750- " stosb\n" \
12751- " testb %%al,%%al\n" \
12752- " jz 1f\n" \
12753- " decl %1\n" \
12754- " jnz 0b\n" \
12755- "1: subl %1,%0\n" \
12756- "2:\n" \
12757- ".section .fixup,\"ax\"\n" \
12758- "3: movl %5,%0\n" \
12759- " jmp 2b\n" \
12760- ".previous\n" \
12761- _ASM_EXTABLE(0b,3b) \
12762- : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \
12763- "=&D" (__d2) \
12764- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
12765- : "memory"); \
12766-} while (0)
12767+static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
12768+{
12769+ int __d0, __d1, __d2;
12770+ long res = -EFAULT;
12771+
12772+ might_fault();
12773+ __asm__ __volatile__(
12774+ " movw %w10,%%ds\n"
12775+ " testl %1,%1\n"
12776+ " jz 2f\n"
12777+ "0: lodsb\n"
12778+ " stosb\n"
12779+ " testb %%al,%%al\n"
12780+ " jz 1f\n"
12781+ " decl %1\n"
12782+ " jnz 0b\n"
12783+ "1: subl %1,%0\n"
12784+ "2:\n"
12785+ " pushl %%ss\n"
12786+ " popl %%ds\n"
12787+ ".section .fixup,\"ax\"\n"
12788+ "3: movl %5,%0\n"
12789+ " jmp 2b\n"
12790+ ".previous\n"
12791+ _ASM_EXTABLE(0b,3b)
12792+ : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),
12793+ "=&D" (__d2)
12794+ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
12795+ "r"(__USER_DS)
12796+ : "memory");
12797+ return res;
12798+}
12799
12800 /**
12801 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
12802@@ -85,9 +92,7 @@ do { \
12803 long
12804 __strncpy_from_user(char *dst, const char __user *src, long count)
12805 {
12806- long res;
12807- __do_strncpy_from_user(dst, src, count, res);
12808- return res;
12809+ return __do_strncpy_from_user(dst, src, count);
12810 }
12811 EXPORT_SYMBOL(__strncpy_from_user);
12812
12813@@ -114,7 +119,7 @@ strncpy_from_user(char *dst, const char
12814 {
12815 long res = -EFAULT;
12816 if (access_ok(VERIFY_READ, src, 1))
12817- __do_strncpy_from_user(dst, src, count, res);
12818+ res = __do_strncpy_from_user(dst, src, count);
12819 return res;
12820 }
12821 EXPORT_SYMBOL(strncpy_from_user);
12822@@ -123,24 +128,30 @@ EXPORT_SYMBOL(strncpy_from_user);
12823 * Zero Userspace
12824 */
12825
12826-#define __do_clear_user(addr,size) \
12827-do { \
12828- int __d0; \
12829- might_fault(); \
12830- __asm__ __volatile__( \
12831- "0: rep; stosl\n" \
12832- " movl %2,%0\n" \
12833- "1: rep; stosb\n" \
12834- "2:\n" \
12835- ".section .fixup,\"ax\"\n" \
12836- "3: lea 0(%2,%0,4),%0\n" \
12837- " jmp 2b\n" \
12838- ".previous\n" \
12839- _ASM_EXTABLE(0b,3b) \
12840- _ASM_EXTABLE(1b,2b) \
12841- : "=&c"(size), "=&D" (__d0) \
12842- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
12843-} while (0)
12844+static unsigned long __do_clear_user(void __user *addr, unsigned long size)
12845+{
12846+ int __d0;
12847+
12848+ might_fault();
12849+ __asm__ __volatile__(
12850+ " movw %w6,%%es\n"
12851+ "0: rep; stosl\n"
12852+ " movl %2,%0\n"
12853+ "1: rep; stosb\n"
12854+ "2:\n"
12855+ " pushl %%ss\n"
12856+ " popl %%es\n"
12857+ ".section .fixup,\"ax\"\n"
12858+ "3: lea 0(%2,%0,4),%0\n"
12859+ " jmp 2b\n"
12860+ ".previous\n"
12861+ _ASM_EXTABLE(0b,3b)
12862+ _ASM_EXTABLE(1b,2b)
12863+ : "=&c"(size), "=&D" (__d0)
12864+ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
12865+ "r"(__USER_DS));
12866+ return size;
12867+}
12868
12869 /**
12870 * clear_user: - Zero a block of memory in user space.
12871@@ -157,7 +168,7 @@ clear_user(void __user *to, unsigned lon
12872 {
12873 might_fault();
12874 if (access_ok(VERIFY_WRITE, to, n))
12875- __do_clear_user(to, n);
12876+ n = __do_clear_user(to, n);
12877 return n;
12878 }
12879 EXPORT_SYMBOL(clear_user);
12880@@ -176,8 +187,7 @@ EXPORT_SYMBOL(clear_user);
12881 unsigned long
12882 __clear_user(void __user *to, unsigned long n)
12883 {
12884- __do_clear_user(to, n);
12885- return n;
12886+ return __do_clear_user(to, n);
12887 }
12888 EXPORT_SYMBOL(__clear_user);
12889
12890@@ -200,14 +210,17 @@ long strnlen_user(const char __user *s,
12891 might_fault();
12892
12893 __asm__ __volatile__(
12894+ " movw %w8,%%es\n"
12895 " testl %0, %0\n"
12896 " jz 3f\n"
12897- " andl %0,%%ecx\n"
12898+ " movl %0,%%ecx\n"
12899 "0: repne; scasb\n"
12900 " setne %%al\n"
12901 " subl %%ecx,%0\n"
12902 " addl %0,%%eax\n"
12903 "1:\n"
12904+ " pushl %%ss\n"
12905+ " popl %%es\n"
12906 ".section .fixup,\"ax\"\n"
12907 "2: xorl %%eax,%%eax\n"
12908 " jmp 1b\n"
12909@@ -219,7 +232,7 @@ long strnlen_user(const char __user *s,
12910 " .long 0b,2b\n"
12911 ".previous"
12912 :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp)
12913- :"0" (n), "1" (s), "2" (0), "3" (mask)
12914+ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
12915 :"cc");
12916 return res & mask;
12917 }
de855c5d 12918@@ -227,10 +240,121 @@ EXPORT_SYMBOL(strnlen_user);
2380c486
JR
12919
12920 #ifdef CONFIG_X86_INTEL_USERCOPY
12921 static unsigned long
12922-__copy_user_intel(void __user *to, const void *from, unsigned long size)
12923+__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
2380c486
JR
12924+{
12925+ int d0, d1;
12926+ __asm__ __volatile__(
de855c5d 12927+ " movw %w6, %%es\n"
2380c486
JR
12928+ " .align 2,0x90\n"
12929+ "1: movl 32(%4), %%eax\n"
12930+ " cmpl $67, %0\n"
12931+ " jbe 3f\n"
12932+ "2: movl 64(%4), %%eax\n"
12933+ " .align 2,0x90\n"
12934+ "3: movl 0(%4), %%eax\n"
12935+ "4: movl 4(%4), %%edx\n"
12936+ "5: movl %%eax, %%es:0(%3)\n"
12937+ "6: movl %%edx, %%es:4(%3)\n"
12938+ "7: movl 8(%4), %%eax\n"
12939+ "8: movl 12(%4),%%edx\n"
12940+ "9: movl %%eax, %%es:8(%3)\n"
12941+ "10: movl %%edx, %%es:12(%3)\n"
12942+ "11: movl 16(%4), %%eax\n"
12943+ "12: movl 20(%4), %%edx\n"
12944+ "13: movl %%eax, %%es:16(%3)\n"
12945+ "14: movl %%edx, %%es:20(%3)\n"
12946+ "15: movl 24(%4), %%eax\n"
12947+ "16: movl 28(%4), %%edx\n"
12948+ "17: movl %%eax, %%es:24(%3)\n"
12949+ "18: movl %%edx, %%es:28(%3)\n"
12950+ "19: movl 32(%4), %%eax\n"
12951+ "20: movl 36(%4), %%edx\n"
12952+ "21: movl %%eax, %%es:32(%3)\n"
12953+ "22: movl %%edx, %%es:36(%3)\n"
12954+ "23: movl 40(%4), %%eax\n"
12955+ "24: movl 44(%4), %%edx\n"
12956+ "25: movl %%eax, %%es:40(%3)\n"
12957+ "26: movl %%edx, %%es:44(%3)\n"
12958+ "27: movl 48(%4), %%eax\n"
12959+ "28: movl 52(%4), %%edx\n"
12960+ "29: movl %%eax, %%es:48(%3)\n"
12961+ "30: movl %%edx, %%es:52(%3)\n"
12962+ "31: movl 56(%4), %%eax\n"
12963+ "32: movl 60(%4), %%edx\n"
12964+ "33: movl %%eax, %%es:56(%3)\n"
12965+ "34: movl %%edx, %%es:60(%3)\n"
12966+ " addl $-64, %0\n"
12967+ " addl $64, %4\n"
12968+ " addl $64, %3\n"
12969+ " cmpl $63, %0\n"
12970+ " ja 1b\n"
12971+ "35: movl %0, %%eax\n"
12972+ " shrl $2, %0\n"
12973+ " andl $3, %%eax\n"
12974+ " cld\n"
12975+ "99: rep; movsl\n"
12976+ "36: movl %%eax, %0\n"
12977+ "37: rep; movsb\n"
12978+ "100:\n"
12979+ " pushl %%ss\n"
de855c5d 12980+ " popl %%es\n"
2380c486
JR
12981+ ".section .fixup,\"ax\"\n"
12982+ "101: lea 0(%%eax,%0,4),%0\n"
12983+ " jmp 100b\n"
12984+ ".previous\n"
12985+ ".section __ex_table,\"a\"\n"
12986+ " .align 4\n"
12987+ " .long 1b,100b\n"
12988+ " .long 2b,100b\n"
12989+ " .long 3b,100b\n"
12990+ " .long 4b,100b\n"
12991+ " .long 5b,100b\n"
12992+ " .long 6b,100b\n"
12993+ " .long 7b,100b\n"
12994+ " .long 8b,100b\n"
12995+ " .long 9b,100b\n"
12996+ " .long 10b,100b\n"
12997+ " .long 11b,100b\n"
12998+ " .long 12b,100b\n"
12999+ " .long 13b,100b\n"
13000+ " .long 14b,100b\n"
13001+ " .long 15b,100b\n"
13002+ " .long 16b,100b\n"
13003+ " .long 17b,100b\n"
13004+ " .long 18b,100b\n"
13005+ " .long 19b,100b\n"
13006+ " .long 20b,100b\n"
13007+ " .long 21b,100b\n"
13008+ " .long 22b,100b\n"
13009+ " .long 23b,100b\n"
13010+ " .long 24b,100b\n"
13011+ " .long 25b,100b\n"
13012+ " .long 26b,100b\n"
13013+ " .long 27b,100b\n"
13014+ " .long 28b,100b\n"
13015+ " .long 29b,100b\n"
13016+ " .long 30b,100b\n"
13017+ " .long 31b,100b\n"
13018+ " .long 32b,100b\n"
13019+ " .long 33b,100b\n"
13020+ " .long 34b,100b\n"
13021+ " .long 35b,100b\n"
13022+ " .long 36b,100b\n"
13023+ " .long 37b,100b\n"
13024+ " .long 99b,101b\n"
13025+ ".previous"
13026+ : "=&c"(size), "=&D" (d0), "=&S" (d1)
de855c5d
AM
13027+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
13028+ : "eax", "edx", "memory");
13029+ return size;
13030+}
13031+
13032+static unsigned long
13033+__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
13034 {
13035 int d0, d1;
13036 __asm__ __volatile__(
13037+ " movw %w6, %%ds\n"
13038 " .align 2,0x90\n"
13039 "1: movl 32(%4), %%eax\n"
13040 " cmpl $67, %0\n"
13041@@ -239,36 +363,36 @@ __copy_user_intel(void __user *to, const
13042 " .align 2,0x90\n"
13043 "3: movl 0(%4), %%eax\n"
13044 "4: movl 4(%4), %%edx\n"
13045- "5: movl %%eax, 0(%3)\n"
13046- "6: movl %%edx, 4(%3)\n"
13047+ "5: movl %%eax, %%es:0(%3)\n"
13048+ "6: movl %%edx, %%es:4(%3)\n"
13049 "7: movl 8(%4), %%eax\n"
13050 "8: movl 12(%4),%%edx\n"
13051- "9: movl %%eax, 8(%3)\n"
13052- "10: movl %%edx, 12(%3)\n"
13053+ "9: movl %%eax, %%es:8(%3)\n"
13054+ "10: movl %%edx, %%es:12(%3)\n"
13055 "11: movl 16(%4), %%eax\n"
13056 "12: movl 20(%4), %%edx\n"
13057- "13: movl %%eax, 16(%3)\n"
13058- "14: movl %%edx, 20(%3)\n"
13059+ "13: movl %%eax, %%es:16(%3)\n"
13060+ "14: movl %%edx, %%es:20(%3)\n"
13061 "15: movl 24(%4), %%eax\n"
13062 "16: movl 28(%4), %%edx\n"
13063- "17: movl %%eax, 24(%3)\n"
13064- "18: movl %%edx, 28(%3)\n"
13065+ "17: movl %%eax, %%es:24(%3)\n"
13066+ "18: movl %%edx, %%es:28(%3)\n"
13067 "19: movl 32(%4), %%eax\n"
13068 "20: movl 36(%4), %%edx\n"
13069- "21: movl %%eax, 32(%3)\n"
13070- "22: movl %%edx, 36(%3)\n"
13071+ "21: movl %%eax, %%es:32(%3)\n"
13072+ "22: movl %%edx, %%es:36(%3)\n"
13073 "23: movl 40(%4), %%eax\n"
13074 "24: movl 44(%4), %%edx\n"
13075- "25: movl %%eax, 40(%3)\n"
13076- "26: movl %%edx, 44(%3)\n"
13077+ "25: movl %%eax, %%es:40(%3)\n"
13078+ "26: movl %%edx, %%es:44(%3)\n"
13079 "27: movl 48(%4), %%eax\n"
13080 "28: movl 52(%4), %%edx\n"
13081- "29: movl %%eax, 48(%3)\n"
13082- "30: movl %%edx, 52(%3)\n"
13083+ "29: movl %%eax, %%es:48(%3)\n"
13084+ "30: movl %%edx, %%es:52(%3)\n"
13085 "31: movl 56(%4), %%eax\n"
13086 "32: movl 60(%4), %%edx\n"
13087- "33: movl %%eax, 56(%3)\n"
13088- "34: movl %%edx, 60(%3)\n"
13089+ "33: movl %%eax, %%es:56(%3)\n"
13090+ "34: movl %%edx, %%es:60(%3)\n"
13091 " addl $-64, %0\n"
13092 " addl $64, %4\n"
13093 " addl $64, %3\n"
13094@@ -282,6 +406,8 @@ __copy_user_intel(void __user *to, const
13095 "36: movl %%eax, %0\n"
13096 "37: rep; movsb\n"
13097 "100:\n"
13098+ " pushl %%ss\n"
13099+ " popl %%ds\n"
13100 ".section .fixup,\"ax\"\n"
13101 "101: lea 0(%%eax,%0,4),%0\n"
13102 " jmp 100b\n"
13103@@ -328,7 +454,7 @@ __copy_user_intel(void __user *to, const
13104 " .long 99b,101b\n"
13105 ".previous"
13106 : "=&c"(size), "=&D" (d0), "=&S" (d1)
13107- : "1"(to), "2"(from), "0"(size)
2380c486
JR
13108+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
13109 : "eax", "edx", "memory");
13110 return size;
13111 }
13112@@ -338,6 +464,7 @@ __copy_user_zeroing_intel(void *to, cons
13113 {
13114 int d0, d1;
13115 __asm__ __volatile__(
13116+ " movw %w6, %%ds\n"
13117 " .align 2,0x90\n"
13118 "0: movl 32(%4), %%eax\n"
13119 " cmpl $67, %0\n"
13120@@ -346,36 +473,36 @@ __copy_user_zeroing_intel(void *to, cons
13121 " .align 2,0x90\n"
13122 "2: movl 0(%4), %%eax\n"
13123 "21: movl 4(%4), %%edx\n"
13124- " movl %%eax, 0(%3)\n"
13125- " movl %%edx, 4(%3)\n"
13126+ " movl %%eax, %%es:0(%3)\n"
13127+ " movl %%edx, %%es:4(%3)\n"
13128 "3: movl 8(%4), %%eax\n"
13129 "31: movl 12(%4),%%edx\n"
13130- " movl %%eax, 8(%3)\n"
13131- " movl %%edx, 12(%3)\n"
13132+ " movl %%eax, %%es:8(%3)\n"
13133+ " movl %%edx, %%es:12(%3)\n"
13134 "4: movl 16(%4), %%eax\n"
13135 "41: movl 20(%4), %%edx\n"
13136- " movl %%eax, 16(%3)\n"
13137- " movl %%edx, 20(%3)\n"
13138+ " movl %%eax, %%es:16(%3)\n"
13139+ " movl %%edx, %%es:20(%3)\n"
13140 "10: movl 24(%4), %%eax\n"
13141 "51: movl 28(%4), %%edx\n"
13142- " movl %%eax, 24(%3)\n"
13143- " movl %%edx, 28(%3)\n"
13144+ " movl %%eax, %%es:24(%3)\n"
13145+ " movl %%edx, %%es:28(%3)\n"
13146 "11: movl 32(%4), %%eax\n"
13147 "61: movl 36(%4), %%edx\n"
13148- " movl %%eax, 32(%3)\n"
13149- " movl %%edx, 36(%3)\n"
13150+ " movl %%eax, %%es:32(%3)\n"
13151+ " movl %%edx, %%es:36(%3)\n"
13152 "12: movl 40(%4), %%eax\n"
13153 "71: movl 44(%4), %%edx\n"
13154- " movl %%eax, 40(%3)\n"
13155- " movl %%edx, 44(%3)\n"
13156+ " movl %%eax, %%es:40(%3)\n"
13157+ " movl %%edx, %%es:44(%3)\n"
13158 "13: movl 48(%4), %%eax\n"
13159 "81: movl 52(%4), %%edx\n"
13160- " movl %%eax, 48(%3)\n"
13161- " movl %%edx, 52(%3)\n"
13162+ " movl %%eax, %%es:48(%3)\n"
13163+ " movl %%edx, %%es:52(%3)\n"
13164 "14: movl 56(%4), %%eax\n"
13165 "91: movl 60(%4), %%edx\n"
13166- " movl %%eax, 56(%3)\n"
13167- " movl %%edx, 60(%3)\n"
13168+ " movl %%eax, %%es:56(%3)\n"
13169+ " movl %%edx, %%es:60(%3)\n"
13170 " addl $-64, %0\n"
13171 " addl $64, %4\n"
13172 " addl $64, %3\n"
13173@@ -389,6 +516,8 @@ __copy_user_zeroing_intel(void *to, cons
13174 " movl %%eax,%0\n"
13175 "7: rep; movsb\n"
13176 "8:\n"
13177+ " pushl %%ss\n"
13178+ " popl %%ds\n"
13179 ".section .fixup,\"ax\"\n"
13180 "9: lea 0(%%eax,%0,4),%0\n"
13181 "16: pushl %0\n"
13182@@ -423,7 +552,7 @@ __copy_user_zeroing_intel(void *to, cons
13183 " .long 7b,16b\n"
13184 ".previous"
13185 : "=&c"(size), "=&D" (d0), "=&S" (d1)
13186- : "1"(to), "2"(from), "0"(size)
13187+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
13188 : "eax", "edx", "memory");
13189 return size;
13190 }
13191@@ -439,6 +568,7 @@ static unsigned long __copy_user_zeroing
13192 int d0, d1;
13193
13194 __asm__ __volatile__(
13195+ " movw %w6, %%ds\n"
13196 " .align 2,0x90\n"
13197 "0: movl 32(%4), %%eax\n"
13198 " cmpl $67, %0\n"
13199@@ -447,36 +577,36 @@ static unsigned long __copy_user_zeroing
13200 " .align 2,0x90\n"
13201 "2: movl 0(%4), %%eax\n"
13202 "21: movl 4(%4), %%edx\n"
13203- " movnti %%eax, 0(%3)\n"
13204- " movnti %%edx, 4(%3)\n"
13205+ " movnti %%eax, %%es:0(%3)\n"
13206+ " movnti %%edx, %%es:4(%3)\n"
13207 "3: movl 8(%4), %%eax\n"
13208 "31: movl 12(%4),%%edx\n"
13209- " movnti %%eax, 8(%3)\n"
13210- " movnti %%edx, 12(%3)\n"
13211+ " movnti %%eax, %%es:8(%3)\n"
13212+ " movnti %%edx, %%es:12(%3)\n"
13213 "4: movl 16(%4), %%eax\n"
13214 "41: movl 20(%4), %%edx\n"
13215- " movnti %%eax, 16(%3)\n"
13216- " movnti %%edx, 20(%3)\n"
13217+ " movnti %%eax, %%es:16(%3)\n"
13218+ " movnti %%edx, %%es:20(%3)\n"
13219 "10: movl 24(%4), %%eax\n"
13220 "51: movl 28(%4), %%edx\n"
13221- " movnti %%eax, 24(%3)\n"
13222- " movnti %%edx, 28(%3)\n"
13223+ " movnti %%eax, %%es:24(%3)\n"
13224+ " movnti %%edx, %%es:28(%3)\n"
13225 "11: movl 32(%4), %%eax\n"
13226 "61: movl 36(%4), %%edx\n"
13227- " movnti %%eax, 32(%3)\n"
13228- " movnti %%edx, 36(%3)\n"
13229+ " movnti %%eax, %%es:32(%3)\n"
13230+ " movnti %%edx, %%es:36(%3)\n"
13231 "12: movl 40(%4), %%eax\n"
13232 "71: movl 44(%4), %%edx\n"
13233- " movnti %%eax, 40(%3)\n"
13234- " movnti %%edx, 44(%3)\n"
13235+ " movnti %%eax, %%es:40(%3)\n"
13236+ " movnti %%edx, %%es:44(%3)\n"
13237 "13: movl 48(%4), %%eax\n"
13238 "81: movl 52(%4), %%edx\n"
13239- " movnti %%eax, 48(%3)\n"
13240- " movnti %%edx, 52(%3)\n"
13241+ " movnti %%eax, %%es:48(%3)\n"
13242+ " movnti %%edx, %%es:52(%3)\n"
13243 "14: movl 56(%4), %%eax\n"
13244 "91: movl 60(%4), %%edx\n"
13245- " movnti %%eax, 56(%3)\n"
13246- " movnti %%edx, 60(%3)\n"
13247+ " movnti %%eax, %%es:56(%3)\n"
13248+ " movnti %%edx, %%es:60(%3)\n"
13249 " addl $-64, %0\n"
13250 " addl $64, %4\n"
13251 " addl $64, %3\n"
13252@@ -491,6 +621,8 @@ static unsigned long __copy_user_zeroing
13253 " movl %%eax,%0\n"
13254 "7: rep; movsb\n"
13255 "8:\n"
13256+ " pushl %%ss\n"
13257+ " popl %%ds\n"
13258 ".section .fixup,\"ax\"\n"
13259 "9: lea 0(%%eax,%0,4),%0\n"
13260 "16: pushl %0\n"
13261@@ -525,7 +657,7 @@ static unsigned long __copy_user_zeroing
13262 " .long 7b,16b\n"
13263 ".previous"
13264 : "=&c"(size), "=&D" (d0), "=&S" (d1)
13265- : "1"(to), "2"(from), "0"(size)
13266+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
13267 : "eax", "edx", "memory");
13268 return size;
13269 }
13270@@ -536,6 +668,7 @@ static unsigned long __copy_user_intel_n
13271 int d0, d1;
13272
13273 __asm__ __volatile__(
13274+ " movw %w6, %%ds\n"
13275 " .align 2,0x90\n"
13276 "0: movl 32(%4), %%eax\n"
13277 " cmpl $67, %0\n"
13278@@ -544,36 +677,36 @@ static unsigned long __copy_user_intel_n
13279 " .align 2,0x90\n"
13280 "2: movl 0(%4), %%eax\n"
13281 "21: movl 4(%4), %%edx\n"
13282- " movnti %%eax, 0(%3)\n"
13283- " movnti %%edx, 4(%3)\n"
13284+ " movnti %%eax, %%es:0(%3)\n"
13285+ " movnti %%edx, %%es:4(%3)\n"
13286 "3: movl 8(%4), %%eax\n"
13287 "31: movl 12(%4),%%edx\n"
13288- " movnti %%eax, 8(%3)\n"
13289- " movnti %%edx, 12(%3)\n"
13290+ " movnti %%eax, %%es:8(%3)\n"
13291+ " movnti %%edx, %%es:12(%3)\n"
13292 "4: movl 16(%4), %%eax\n"
13293 "41: movl 20(%4), %%edx\n"
13294- " movnti %%eax, 16(%3)\n"
13295- " movnti %%edx, 20(%3)\n"
13296+ " movnti %%eax, %%es:16(%3)\n"
13297+ " movnti %%edx, %%es:20(%3)\n"
13298 "10: movl 24(%4), %%eax\n"
13299 "51: movl 28(%4), %%edx\n"
13300- " movnti %%eax, 24(%3)\n"
13301- " movnti %%edx, 28(%3)\n"
13302+ " movnti %%eax, %%es:24(%3)\n"
13303+ " movnti %%edx, %%es:28(%3)\n"
13304 "11: movl 32(%4), %%eax\n"
13305 "61: movl 36(%4), %%edx\n"
13306- " movnti %%eax, 32(%3)\n"
13307- " movnti %%edx, 36(%3)\n"
13308+ " movnti %%eax, %%es:32(%3)\n"
13309+ " movnti %%edx, %%es:36(%3)\n"
13310 "12: movl 40(%4), %%eax\n"
13311 "71: movl 44(%4), %%edx\n"
13312- " movnti %%eax, 40(%3)\n"
13313- " movnti %%edx, 44(%3)\n"
13314+ " movnti %%eax, %%es:40(%3)\n"
13315+ " movnti %%edx, %%es:44(%3)\n"
13316 "13: movl 48(%4), %%eax\n"
13317 "81: movl 52(%4), %%edx\n"
13318- " movnti %%eax, 48(%3)\n"
13319- " movnti %%edx, 52(%3)\n"
13320+ " movnti %%eax, %%es:48(%3)\n"
13321+ " movnti %%edx, %%es:52(%3)\n"
13322 "14: movl 56(%4), %%eax\n"
13323 "91: movl 60(%4), %%edx\n"
13324- " movnti %%eax, 56(%3)\n"
13325- " movnti %%edx, 60(%3)\n"
13326+ " movnti %%eax, %%es:56(%3)\n"
13327+ " movnti %%edx, %%es:60(%3)\n"
13328 " addl $-64, %0\n"
13329 " addl $64, %4\n"
13330 " addl $64, %3\n"
13331@@ -588,6 +721,8 @@ static unsigned long __copy_user_intel_n
13332 " movl %%eax,%0\n"
13333 "7: rep; movsb\n"
13334 "8:\n"
13335+ " pushl %%ss\n"
13336+ " popl %%ds\n"
13337 ".section .fixup,\"ax\"\n"
13338 "9: lea 0(%%eax,%0,4),%0\n"
13339 "16: jmp 8b\n"
13340@@ -616,7 +751,7 @@ static unsigned long __copy_user_intel_n
13341 " .long 7b,16b\n"
13342 ".previous"
13343 : "=&c"(size), "=&D" (d0), "=&S" (d1)
13344- : "1"(to), "2"(from), "0"(size)
13345+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
13346 : "eax", "edx", "memory");
13347 return size;
13348 }
13349@@ -629,90 +764,146 @@ static unsigned long __copy_user_intel_n
13350 */
13351 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
13352 unsigned long size);
13353-unsigned long __copy_user_intel(void __user *to, const void *from,
13354+unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
13355+ unsigned long size);
13356+unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
13357 unsigned long size);
13358 unsigned long __copy_user_zeroing_intel_nocache(void *to,
13359 const void __user *from, unsigned long size);
13360 #endif /* CONFIG_X86_INTEL_USERCOPY */
13361
13362 /* Generic arbitrary sized copy. */
13363-#define __copy_user(to, from, size) \
13364-do { \
13365- int __d0, __d1, __d2; \
13366- __asm__ __volatile__( \
13367- " cmp $7,%0\n" \
13368- " jbe 1f\n" \
13369- " movl %1,%0\n" \
13370- " negl %0\n" \
13371- " andl $7,%0\n" \
13372- " subl %0,%3\n" \
13373- "4: rep; movsb\n" \
13374- " movl %3,%0\n" \
13375- " shrl $2,%0\n" \
13376- " andl $3,%3\n" \
13377- " .align 2,0x90\n" \
13378- "0: rep; movsl\n" \
13379- " movl %3,%0\n" \
13380- "1: rep; movsb\n" \
13381- "2:\n" \
13382- ".section .fixup,\"ax\"\n" \
13383- "5: addl %3,%0\n" \
13384- " jmp 2b\n" \
13385- "3: lea 0(%3,%0,4),%0\n" \
13386- " jmp 2b\n" \
13387- ".previous\n" \
13388- ".section __ex_table,\"a\"\n" \
13389- " .align 4\n" \
13390- " .long 4b,5b\n" \
13391- " .long 0b,3b\n" \
13392- " .long 1b,2b\n" \
13393- ".previous" \
13394- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
13395- : "3"(size), "0"(size), "1"(to), "2"(from) \
13396- : "memory"); \
13397-} while (0)
13398-
13399-#define __copy_user_zeroing(to, from, size) \
13400-do { \
13401- int __d0, __d1, __d2; \
13402- __asm__ __volatile__( \
13403- " cmp $7,%0\n" \
13404- " jbe 1f\n" \
13405- " movl %1,%0\n" \
13406- " negl %0\n" \
13407- " andl $7,%0\n" \
13408- " subl %0,%3\n" \
13409- "4: rep; movsb\n" \
13410- " movl %3,%0\n" \
13411- " shrl $2,%0\n" \
13412- " andl $3,%3\n" \
13413- " .align 2,0x90\n" \
13414- "0: rep; movsl\n" \
13415- " movl %3,%0\n" \
13416- "1: rep; movsb\n" \
13417- "2:\n" \
13418- ".section .fixup,\"ax\"\n" \
13419- "5: addl %3,%0\n" \
13420- " jmp 6f\n" \
13421- "3: lea 0(%3,%0,4),%0\n" \
13422- "6: pushl %0\n" \
13423- " pushl %%eax\n" \
13424- " xorl %%eax,%%eax\n" \
13425- " rep; stosb\n" \
13426- " popl %%eax\n" \
13427- " popl %0\n" \
13428- " jmp 2b\n" \
13429- ".previous\n" \
13430- ".section __ex_table,\"a\"\n" \
13431- " .align 4\n" \
13432- " .long 4b,5b\n" \
13433- " .long 0b,3b\n" \
13434- " .long 1b,6b\n" \
13435- ".previous" \
13436- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
13437- : "3"(size), "0"(size), "1"(to), "2"(from) \
13438- : "memory"); \
13439-} while (0)
13440+static unsigned long
13441+__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
13442+{
13443+ int __d0, __d1, __d2;
13444+
13445+ __asm__ __volatile__(
13446+ " movw %w8,%%es\n"
13447+ " cmp $7,%0\n"
13448+ " jbe 1f\n"
13449+ " movl %1,%0\n"
13450+ " negl %0\n"
13451+ " andl $7,%0\n"
13452+ " subl %0,%3\n"
13453+ "4: rep; movsb\n"
13454+ " movl %3,%0\n"
13455+ " shrl $2,%0\n"
13456+ " andl $3,%3\n"
13457+ " .align 2,0x90\n"
13458+ "0: rep; movsl\n"
13459+ " movl %3,%0\n"
13460+ "1: rep; movsb\n"
13461+ "2:\n"
13462+ " pushl %%ss\n"
13463+ " popl %%es\n"
13464+ ".section .fixup,\"ax\"\n"
13465+ "5: addl %3,%0\n"
13466+ " jmp 2b\n"
13467+ "3: lea 0(%3,%0,4),%0\n"
13468+ " jmp 2b\n"
13469+ ".previous\n"
13470+ ".section __ex_table,\"a\"\n"
13471+ " .align 4\n"
13472+ " .long 4b,5b\n"
13473+ " .long 0b,3b\n"
13474+ " .long 1b,2b\n"
13475+ ".previous"
13476+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
13477+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
13478+ : "memory");
13479+ return size;
13480+}
13481+
13482+static unsigned long
13483+__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
13484+{
13485+ int __d0, __d1, __d2;
13486+
13487+ __asm__ __volatile__(
13488+ " movw %w8,%%ds\n"
13489+ " cmp $7,%0\n"
13490+ " jbe 1f\n"
13491+ " movl %1,%0\n"
13492+ " negl %0\n"
13493+ " andl $7,%0\n"
13494+ " subl %0,%3\n"
13495+ "4: rep; movsb\n"
13496+ " movl %3,%0\n"
13497+ " shrl $2,%0\n"
13498+ " andl $3,%3\n"
13499+ " .align 2,0x90\n"
13500+ "0: rep; movsl\n"
13501+ " movl %3,%0\n"
13502+ "1: rep; movsb\n"
13503+ "2:\n"
13504+ " pushl %%ss\n"
13505+ " popl %%ds\n"
13506+ ".section .fixup,\"ax\"\n"
13507+ "5: addl %3,%0\n"
13508+ " jmp 2b\n"
13509+ "3: lea 0(%3,%0,4),%0\n"
13510+ " jmp 2b\n"
13511+ ".previous\n"
13512+ ".section __ex_table,\"a\"\n"
13513+ " .align 4\n"
13514+ " .long 4b,5b\n"
13515+ " .long 0b,3b\n"
13516+ " .long 1b,2b\n"
13517+ ".previous"
13518+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
13519+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
13520+ : "memory");
13521+ return size;
13522+}
13523+
13524+static unsigned long
13525+__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
13526+{
13527+ int __d0, __d1, __d2;
13528+
13529+ __asm__ __volatile__(
13530+ " movw %w8,%%ds\n"
13531+ " cmp $7,%0\n"
13532+ " jbe 1f\n"
13533+ " movl %1,%0\n"
13534+ " negl %0\n"
13535+ " andl $7,%0\n"
13536+ " subl %0,%3\n"
13537+ "4: rep; movsb\n"
13538+ " movl %3,%0\n"
13539+ " shrl $2,%0\n"
13540+ " andl $3,%3\n"
13541+ " .align 2,0x90\n"
13542+ "0: rep; movsl\n"
13543+ " movl %3,%0\n"
13544+ "1: rep; movsb\n"
13545+ "2:\n"
13546+ " pushl %%ss\n"
13547+ " popl %%ds\n"
13548+ ".section .fixup,\"ax\"\n"
13549+ "5: addl %3,%0\n"
13550+ " jmp 6f\n"
13551+ "3: lea 0(%3,%0,4),%0\n"
13552+ "6: pushl %0\n"
13553+ " pushl %%eax\n"
13554+ " xorl %%eax,%%eax\n"
13555+ " rep; stosb\n"
13556+ " popl %%eax\n"
13557+ " popl %0\n"
13558+ " jmp 2b\n"
13559+ ".previous\n"
13560+ ".section __ex_table,\"a\"\n"
13561+ " .align 4\n"
13562+ " .long 4b,5b\n"
13563+ " .long 0b,3b\n"
13564+ " .long 1b,6b\n"
13565+ ".previous"
13566+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
13567+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
13568+ : "memory");
13569+ return size;
13570+}
13571
13572 unsigned long __copy_to_user_ll(void __user *to, const void *from,
13573 unsigned long n)
13574@@ -775,9 +966,9 @@ survive:
13575 }
13576 #endif
13577 if (movsl_is_ok(to, from, n))
13578- __copy_user(to, from, n);
13579+ n = __generic_copy_to_user(to, from, n);
13580 else
13581- n = __copy_user_intel(to, from, n);
13582+ n = __generic_copy_to_user_intel(to, from, n);
13583 return n;
13584 }
13585 EXPORT_SYMBOL(__copy_to_user_ll);
13586@@ -786,7 +977,7 @@ unsigned long __copy_from_user_ll(void *
13587 unsigned long n)
13588 {
13589 if (movsl_is_ok(to, from, n))
13590- __copy_user_zeroing(to, from, n);
13591+ n = __copy_user_zeroing(to, from, n);
13592 else
13593 n = __copy_user_zeroing_intel(to, from, n);
13594 return n;
13595@@ -797,10 +988,9 @@ unsigned long __copy_from_user_ll_nozero
13596 unsigned long n)
13597 {
13598 if (movsl_is_ok(to, from, n))
13599- __copy_user(to, from, n);
13600+ n = __generic_copy_from_user(to, from, n);
13601 else
13602- n = __copy_user_intel((void __user *)to,
13603- (const void *)from, n);
13604+ n = __generic_copy_from_user_intel(to, from, n);
13605 return n;
13606 }
13607 EXPORT_SYMBOL(__copy_from_user_ll_nozero);
13608@@ -812,9 +1002,9 @@ unsigned long __copy_from_user_ll_nocach
13609 if (n > 64 && cpu_has_xmm2)
13610 n = __copy_user_zeroing_intel_nocache(to, from, n);
13611 else
13612- __copy_user_zeroing(to, from, n);
13613+ n = __copy_user_zeroing(to, from, n);
13614 #else
13615- __copy_user_zeroing(to, from, n);
13616+ n = __copy_user_zeroing(to, from, n);
13617 #endif
13618 return n;
13619 }
de855c5d 13620@@ -827,59 +1017,37 @@ unsigned long __copy_from_user_ll_nocach
2380c486
JR
13621 if (n > 64 && cpu_has_xmm2)
13622 n = __copy_user_intel_nocache(to, from, n);
13623 else
13624- __copy_user(to, from, n);
13625+ n = __generic_copy_from_user(to, from, n);
13626 #else
13627- __copy_user(to, from, n);
13628+ n = __generic_copy_from_user(to, from, n);
13629 #endif
13630 return n;
13631 }
de855c5d
AM
13632 EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero);
13633
13634-/**
13635- * copy_to_user: - Copy a block of data into user space.
13636- * @to: Destination address, in user space.
13637- * @from: Source address, in kernel space.
13638- * @n: Number of bytes to copy.
13639- *
13640- * Context: User context only. This function may sleep.
13641- *
13642- * Copy data from kernel space to user space.
13643- *
13644- * Returns number of bytes that could not be copied.
13645- * On success, this will be zero.
13646- */
13647-unsigned long
13648-copy_to_user(void __user *to, const void *from, unsigned long n)
2380c486
JR
13649+#ifdef CONFIG_PAX_MEMORY_UDEREF
13650+void __set_fs(mm_segment_t x, int cpu)
de855c5d
AM
13651 {
13652- if (access_ok(VERIFY_WRITE, to, n))
13653- n = __copy_to_user(to, from, n);
13654- return n;
2380c486
JR
13655+ unsigned long limit = x.seg;
13656+ struct desc_struct d;
13657+
13658+ current_thread_info()->addr_limit = x;
13659+ if (likely(limit))
13660+ limit = (limit - 1UL) >> PAGE_SHIFT;
13661+ pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
13662+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
de855c5d
AM
13663 }
13664-EXPORT_SYMBOL(copy_to_user);
13665
13666-/**
13667- * copy_from_user: - Copy a block of data from user space.
13668- * @to: Destination address, in kernel space.
13669- * @from: Source address, in user space.
13670- * @n: Number of bytes to copy.
13671- *
13672- * Context: User context only. This function may sleep.
13673- *
13674- * Copy data from user space to kernel space.
13675- *
13676- * Returns number of bytes that could not be copied.
13677- * On success, this will be zero.
13678- *
13679- * If some data could not be copied, this function will pad the copied
13680- * data to the requested size using zero bytes.
13681- */
13682-unsigned long
13683-copy_from_user(void *to, const void __user *from, unsigned long n)
2380c486 13684+void set_fs(mm_segment_t x)
de855c5d
AM
13685 {
13686- if (access_ok(VERIFY_READ, from, n))
13687- n = __copy_from_user(to, from, n);
13688- else
13689- memset(to, 0, n);
13690- return n;
2380c486
JR
13691+ __set_fs(x, get_cpu());
13692+ put_cpu_no_resched();
de855c5d
AM
13693 }
13694-EXPORT_SYMBOL(copy_from_user);
2380c486
JR
13695+#else
13696+void set_fs(mm_segment_t x)
13697+{
13698+ current_thread_info()->addr_limit = x;
13699+}
13700+#endif
13701+
13702+EXPORT_SYMBOL(set_fs);
017d2877
AM
13703diff -urNp linux-2.6.30.4/arch/x86/Makefile linux-2.6.30.4/arch/x86/Makefile
13704--- linux-2.6.30.4/arch/x86/Makefile 2009-07-24 17:47:51.000000000 -0400
13705+++ linux-2.6.30.4/arch/x86/Makefile 2009-07-30 09:48:09.917626356 -0400
13706@@ -198,3 +198,12 @@ define archhelp
13707 echo ' FDARGS="..." arguments for the booted kernel'
13708 echo ' FDINITRD=file initrd for the booted kernel'
13709 endef
2380c486
JR
13710+
13711+define OLD_LD
13712+
13713+*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
13714+*** Please upgrade your binutils to 2.18 or newer
13715+endef
13716+
13717+archprepare:
13718+ $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
017d2877
AM
13719diff -urNp linux-2.6.30.4/arch/x86/mm/extable.c linux-2.6.30.4/arch/x86/mm/extable.c
13720--- linux-2.6.30.4/arch/x86/mm/extable.c 2009-07-24 17:47:51.000000000 -0400
13721+++ linux-2.6.30.4/arch/x86/mm/extable.c 2009-07-30 09:48:09.970452952 -0400
2380c486
JR
13722@@ -1,14 +1,62 @@
13723 #include <linux/module.h>
13724 #include <linux/spinlock.h>
13725+#include <linux/sort.h>
13726 #include <asm/uaccess.h>
13727
13728+/*
13729+ * The exception table needs to be sorted so that the binary
13730+ * search that we use to find entries in it works properly.
13731+ * This is used both for the kernel exception table and for
13732+ * the exception tables of modules that get loaded.
13733+ */
13734+static int cmp_ex(const void *a, const void *b)
13735+{
13736+ const struct exception_table_entry *x = a, *y = b;
13737+
13738+ /* avoid overflow */
13739+ if (x->insn > y->insn)
13740+ return 1;
13741+ if (x->insn < y->insn)
13742+ return -1;
13743+ return 0;
13744+}
13745+
13746+static void swap_ex(void *a, void *b, int size)
13747+{
13748+ struct exception_table_entry t, *x = a, *y = b;
13749+
13750+#ifdef CONFIG_PAX_KERNEXEC
13751+ unsigned long cr0;
13752+#endif
13753+
13754+ t = *x;
13755+
13756+#ifdef CONFIG_PAX_KERNEXEC
13757+ pax_open_kernel(cr0);
13758+#endif
13759+
13760+ *x = *y;
13761+ *y = t;
13762+
13763+#ifdef CONFIG_PAX_KERNEXEC
13764+ pax_close_kernel(cr0);
13765+#endif
13766+
13767+}
13768+
13769+void sort_extable(struct exception_table_entry *start,
13770+ struct exception_table_entry *finish)
13771+{
13772+ sort(start, finish - start, sizeof(struct exception_table_entry),
13773+ cmp_ex, swap_ex);
13774+}
13775
13776 int fixup_exception(struct pt_regs *regs)
13777 {
13778 const struct exception_table_entry *fixup;
13779
13780 #ifdef CONFIG_PNPBIOS
13781- if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
13782+ if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
13783 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
13784 extern u32 pnp_bios_is_utter_crap;
13785 pnp_bios_is_utter_crap = 1;
017d2877
AM
13786diff -urNp linux-2.6.30.4/arch/x86/mm/fault.c linux-2.6.30.4/arch/x86/mm/fault.c
13787--- linux-2.6.30.4/arch/x86/mm/fault.c 2009-07-24 17:47:51.000000000 -0400
13788+++ linux-2.6.30.4/arch/x86/mm/fault.c 2009-07-30 11:10:48.941676108 -0400
13789@@ -27,6 +27,8 @@
13790 #include <linux/tty.h>
13791 #include <linux/smp.h>
13792 #include <linux/mm.h>
2380c486
JR
13793+#include <linux/unistd.h>
13794+#include <linux/compiler.h>
13795
017d2877
AM
13796 #include <asm-generic/sections.h>
13797
13798@@ -73,7 +75,7 @@ static inline int notify_page_fault(stru
2380c486
JR
13799 int ret = 0;
13800
13801 /* kprobe_running() needs smp_processor_id() */
017d2877
AM
13802- if (kprobes_built_in() && !user_mode_vm(regs)) {
13803+ if (kprobes_built_in() && !user_mode(regs)) {
2380c486
JR
13804 preempt_disable();
13805 if (kprobe_running() && kprobe_fault_handler(regs, 14))
13806 ret = 1;
017d2877
AM
13807@@ -193,6 +195,30 @@ force_sig_info_fault(int si_signo, int s
13808 force_sig_info(si_signo, &info, tsk);
2380c486
JR
13809 }
13810
13811+#ifdef CONFIG_PAX_EMUTRAMP
13812+static int pax_handle_fetch_fault(struct pt_regs *regs);
13813+#endif
13814+
13815+#ifdef CONFIG_PAX_PAGEEXEC
13816+static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
13817+{
13818+ pgd_t *pgd;
13819+ pud_t *pud;
13820+ pmd_t *pmd;
13821+
13822+ pgd = pgd_offset(mm, address);
13823+ if (!pgd_present(*pgd))
13824+ return NULL;
13825+ pud = pud_offset(pgd, address);
13826+ if (!pud_present(*pud))
13827+ return NULL;
13828+ pmd = pmd_offset(pud, address);
13829+ if (!pmd_present(*pmd))
13830+ return NULL;
13831+ return pmd;
13832+}
13833+#endif
13834+
017d2877
AM
13835 DEFINE_SPINLOCK(pgd_lock);
13836 LIST_HEAD(pgd_list);
13837
13838@@ -571,7 +597,7 @@ static int is_errata93(struct pt_regs *r
2380c486
JR
13839 static int is_errata100(struct pt_regs *regs, unsigned long address)
13840 {
13841 #ifdef CONFIG_X86_64
017d2877
AM
13842- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && (address >> 32))
13843+ if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) && (address >> 32))
2380c486
JR
13844 return 1;
13845 #endif
017d2877
AM
13846 return 0;
13847@@ -598,7 +624,7 @@ static int is_f00f_bug(struct pt_regs *r
13848 }
13849
13850 static const char nx_warning[] = KERN_CRIT
13851-"kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n";
13852+"kernel tried to execute NX-protected page - exploit attempt? (uid: %d, task: %s, pid: %d)\n";
13853
13854 static void
13855 show_fault_oops(struct pt_regs *regs, unsigned long error_code,
13856@@ -607,15 +633,31 @@ show_fault_oops(struct pt_regs *regs, un
13857 if (!oops_may_print())
13858 return;
2380c486 13859
2380c486
JR
13860- if (error_code & PF_INSTR) {
13861+ if (nx_enabled && (error_code & PF_INSTR)) {
13862 unsigned int level;
017d2877 13863
2380c486
JR
13864 pte_t *pte = lookup_address(address, &level);
13865
13866 if (pte && pte_present(*pte) && !pte_exec(*pte))
017d2877
AM
13867- printk(nx_warning, current_uid());
13868+ printk(nx_warning, current_uid(), current->comm, task_pid_nr(current));
13869 }
13870
2380c486
JR
13871+#ifdef CONFIG_PAX_KERNEXEC
13872+#ifdef CONFIG_MODULES
13873+ if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
13874+#else
13875+ if (init_mm.start_code <= address && address < init_mm.end_code)
13876+#endif
13877+ {
13878+ if (current->signal->curr_ip)
13879+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
13880+ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current_uid(), current_euid());
13881+ else
13882+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
13883+ current->comm, task_pid_nr(current), current_uid(), current_euid());
017d2877
AM
13884+ }
13885+#endif
13886+
13887 printk(KERN_ALERT "BUG: unable to handle kernel ");
13888 if (address < PAGE_SIZE)
13889 printk(KERN_CONT "NULL pointer dereference");
13890@@ -740,6 +782,68 @@ __bad_area_nosemaphore(struct pt_regs *r
13891 unsigned long address, int si_code)
13892 {
13893 struct task_struct *tsk = current;
13894+ struct mm_struct *mm = tsk->mm;
13895+
13896+#ifdef CONFIG_X86_64
13897+ if (mm && (error_code & PF_INSTR)) {
13898+ if (regs->ip == (unsigned long)vgettimeofday) {
13899+ regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, fallback_gettimeofday);
13900+ return;
13901+ } else if (regs->ip == (unsigned long)vtime) {
13902+ regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, fallback_time);
13903+ return;
13904+ } else if (regs->ip == (unsigned long)vgetcpu) {
13905+ regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, getcpu);
13906+ return;
13907+ }
13908+ }
13909+#endif
13910+
13911+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13912+ if (mm && (error_code & PF_USER)) {
13913+ unsigned long ip = regs->ip;
13914+
13915+ if (v8086_mode(regs))
13916+ ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
13917+
13918+ /*
13919+ * It's possible to have interrupts off here:
13920+ */
13921+ local_irq_enable();
13922+
13923+#ifdef CONFIG_PAX_PAGEEXEC
13924+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
13925+ ((nx_enabled && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && regs->ip == address))) {
13926+
13927+#ifdef CONFIG_PAX_EMUTRAMP
13928+ switch (pax_handle_fetch_fault(regs)) {
13929+ case 2:
13930+ return;
13931+ }
13932+#endif
13933+
13934+ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
13935+ do_group_exit(SIGKILL);
13936+ }
13937+#endif
13938+
13939+#ifdef CONFIG_PAX_SEGMEXEC
13940+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
13941+
13942+#ifdef CONFIG_PAX_EMUTRAMP
13943+ switch (pax_handle_fetch_fault(regs)) {
13944+ case 2:
13945+ return;
13946+ }
13947+#endif
13948+
13949+ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
13950+ do_group_exit(SIGKILL);
13951+ }
13952+#endif
13953+
13954+ }
13955+#endif
2380c486 13956
017d2877
AM
13957 /* User mode accesses just cause a SIGSEGV */
13958 if (error_code & PF_USER) {
13959@@ -874,6 +978,106 @@ static int spurious_fault_check(unsigned
13960 return 1;
13961 }
2380c486
JR
13962
13963+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
017d2877
AM
13964+static int pax_handle_pageexec_fault(struct pt_regs *regs, struct mm_struct *mm, unsigned long address, unsigned long error_code)
13965+{
2380c486
JR
13966+ pte_t *pte;
13967+ pmd_t *pmd;
13968+ spinlock_t *ptl;
13969+ unsigned char pte_mask;
2380c486 13970+
2380c486
JR
13971+ if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
13972+ !(mm->pax_flags & MF_PAX_PAGEEXEC))
017d2877 13973+ return 0;
2380c486
JR
13974+
13975+ /* PaX: it's our fault, let's handle it if we can */
13976+
13977+ /* PaX: take a look at read faults before acquiring any locks */
13978+ if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
13979+ /* instruction fetch attempt from a protected page in user mode */
13980+ up_read(&mm->mmap_sem);
13981+
13982+#ifdef CONFIG_PAX_EMUTRAMP
13983+ switch (pax_handle_fetch_fault(regs)) {
13984+ case 2:
017d2877 13985+ return 1;
2380c486
JR
13986+ }
13987+#endif
13988+
13989+ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
13990+ do_group_exit(SIGKILL);
13991+ }
13992+
13993+ pmd = pax_get_pmd(mm, address);
13994+ if (unlikely(!pmd))
017d2877 13995+ return 0;
2380c486
JR
13996+
13997+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
13998+ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
13999+ pte_unmap_unlock(pte, ptl);
017d2877 14000+ return 0;
2380c486
JR
14001+ }
14002+
14003+ if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
14004+ /* write attempt to a protected page in user mode */
14005+ pte_unmap_unlock(pte, ptl);
017d2877 14006+ return 0;
2380c486
JR
14007+ }
14008+
14009+#ifdef CONFIG_SMP
14010+ if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
14011+#else
14012+ if (likely(address > get_limit(regs->cs)))
14013+#endif
14014+ {
14015+ set_pte(pte, pte_mkread(*pte));
14016+ __flush_tlb_one(address);
14017+ pte_unmap_unlock(pte, ptl);
14018+ up_read(&mm->mmap_sem);
017d2877 14019+ return 1;
2380c486
JR
14020+ }
14021+
14022+ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
14023+
14024+ /*
14025+ * PaX: fill DTLB with user rights and retry
14026+ */
14027+ __asm__ __volatile__ (
14028+#ifdef CONFIG_PAX_MEMORY_UDEREF
14029+ "movw %w4,%%es\n"
14030+#endif
14031+ "orb %2,(%1)\n"
14032+#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
14033+/*
14034+ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
14035+ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
14036+ * page fault when examined during a TLB load attempt. this is true not only
14037+ * for PTEs holding a non-present entry but also present entries that will
14038+ * raise a page fault (such as those set up by PaX, or the copy-on-write
14039+ * mechanism). in effect it means that we do *not* need to flush the TLBs
14040+ * for our target pages since their PTEs are simply not in the TLBs at all.
14041+
14042+ * the best thing in omitting it is that we gain around 15-20% speed in the
14043+ * fast path of the page fault handler and can get rid of tracing since we
14044+ * can no longer flush unintended entries.
14045+ */
14046+ "invlpg (%0)\n"
14047+#endif
14048+ "testb $0,%%es:(%0)\n"
14049+ "xorb %3,(%1)\n"
14050+#ifdef CONFIG_PAX_MEMORY_UDEREF
14051+ "pushl %%ss\n"
14052+ "popl %%es\n"
14053+#endif
14054+ :
14055+ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
14056+ : "memory", "cc");
14057+ pte_unmap_unlock(pte, ptl);
14058+ up_read(&mm->mmap_sem);
017d2877
AM
14059+ return 1;
14060+}
14061+#endif
14062+
14063 /*
14064 * Handle a spurious fault caused by a stale TLB entry.
14065 *
14066@@ -940,6 +1144,9 @@ int show_unhandled_signals = 1;
14067 static inline int
14068 access_error(unsigned long error_code, int write, struct vm_area_struct *vma)
14069 {
14070+ if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
14071+ return 1;
14072+
14073 if (write) {
14074 /* write, present and write, not present: */
14075 if (unlikely(!(vma->vm_flags & VM_WRITE)))
14076@@ -973,19 +1180,18 @@ do_page_fault(struct pt_regs *regs, unsi
14077 {
14078 struct vm_area_struct *vma;
14079 struct task_struct *tsk;
14080- unsigned long address;
14081 struct mm_struct *mm;
14082 int write;
14083 int fault;
14084
14085+ /* Get the faulting address: */
14086+ const unsigned long address = read_cr2();
2380c486 14087+
017d2877
AM
14088 tsk = current;
14089 mm = tsk->mm;
14090
14091 prefetchw(&mm->mmap_sem);
14092
14093- /* Get the faulting address: */
14094- address = read_cr2();
14095-
14096 if (unlikely(kmmio_fault(regs, address)))
14097 return;
14098
14099@@ -1033,7 +1239,7 @@ do_page_fault(struct pt_regs *regs, unsi
14100 * User-mode registers count as a user access even for any
14101 * potential system fault or CPU buglet:
14102 */
14103- if (user_mode_vm(regs)) {
14104+ if (user_mode(regs)) {
14105 local_irq_enable();
14106 error_code |= PF_USER;
14107 } else {
14108@@ -1085,6 +1291,11 @@ do_page_fault(struct pt_regs *regs, unsi
14109 might_sleep();
14110 }
14111
14112+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
14113+ if (pax_handle_pageexec_fault(regs, mm, address, error_code))
14114+ return;
2380c486
JR
14115+#endif
14116+
14117 vma = find_vma(mm, address);
017d2877
AM
14118 if (unlikely(!vma)) {
14119 bad_area(regs, error_code, address);
14120@@ -1096,18 +1307,24 @@ do_page_fault(struct pt_regs *regs, unsi
14121 bad_area(regs, error_code, address);
14122 return;
14123 }
2380c486
JR
14124- if (error_code & PF_USER) {
14125- /*
14126- * Accessing the stack below %sp is always a bug.
14127- * The large cushion allows instructions like enter
017d2877 14128- * and pusha to work. ("enter $65535, $31" pushes
2380c486
JR
14129- * 32 pointers and then decrements %sp by 65535.)
14130- */
017d2877
AM
14131- if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
14132- bad_area(regs, error_code, address);
14133- return;
14134- }
2380c486
JR
14135+ /*
14136+ * Accessing the stack below %sp is always a bug.
14137+ * The large cushion allows instructions like enter
017d2877 14138+ * and pusha to work. ("enter $65535, $31" pushes
2380c486
JR
14139+ * 32 pointers and then decrements %sp by 65535.)
14140+ */
017d2877
AM
14141+ if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < task_pt_regs(tsk)->sp)) {
14142+ bad_area(regs, error_code, address);
14143+ return;
14144 }
2380c486
JR
14145+
14146+#ifdef CONFIG_PAX_SEGMEXEC
017d2877
AM
14147+ if (unlikely((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)) {
14148+ bad_area(regs, error_code, address);
14149+ return;
2380c486
JR
14150+ }
14151+#endif
14152+
017d2877
AM
14153 if (unlikely(expand_stack(vma, address))) {
14154 bad_area(regs, error_code, address);
14155 return;
14156@@ -1146,3 +1363,174 @@ good_area:
14157
14158 up_read(&mm->mmap_sem);
2380c486
JR
14159 }
14160+
14161+#ifdef CONFIG_PAX_EMUTRAMP
14162+static int pax_handle_fetch_fault_32(struct pt_regs *regs)
14163+{
14164+ int err;
14165+
14166+ do { /* PaX: gcc trampoline emulation #1 */
14167+ unsigned char mov1, mov2;
14168+ unsigned short jmp;
14169+ unsigned int addr1, addr2;
14170+
14171+#ifdef CONFIG_X86_64
14172+ if ((regs->ip + 11) >> 32)
14173+ break;
14174+#endif
14175+
14176+ err = get_user(mov1, (unsigned char __user *)regs->ip);
14177+ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
14178+ err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
14179+ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
14180+ err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
14181+
14182+ if (err)
14183+ break;
14184+
14185+ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
14186+ regs->cx = addr1;
14187+ regs->ax = addr2;
14188+ regs->ip = addr2;
14189+ return 2;
14190+ }
14191+ } while (0);
14192+
14193+ do { /* PaX: gcc trampoline emulation #2 */
14194+ unsigned char mov, jmp;
14195+ unsigned int addr1, addr2;
14196+
14197+#ifdef CONFIG_X86_64
14198+ if ((regs->ip + 9) >> 32)
14199+ break;
14200+#endif
14201+
14202+ err = get_user(mov, (unsigned char __user *)regs->ip);
14203+ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
14204+ err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
14205+ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
14206+
14207+ if (err)
14208+ break;
14209+
14210+ if (mov == 0xB9 && jmp == 0xE9) {
14211+ regs->cx = addr1;
14212+ regs->ip = (unsigned int)(regs->ip + addr2 + 10);
14213+ return 2;
14214+ }
14215+ } while (0);
14216+
14217+ return 1; /* PaX in action */
14218+}
14219+
14220+#ifdef CONFIG_X86_64
14221+static int pax_handle_fetch_fault_64(struct pt_regs *regs)
14222+{
14223+ int err;
14224+
14225+ do { /* PaX: gcc trampoline emulation #1 */
14226+ unsigned short mov1, mov2, jmp1;
14227+ unsigned char jmp2;
14228+ unsigned int addr1;
14229+ unsigned long addr2;
14230+
14231+ err = get_user(mov1, (unsigned short __user *)regs->ip);
14232+ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
14233+ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
14234+ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
14235+ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
14236+ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
14237+
14238+ if (err)
14239+ break;
14240+
14241+ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
14242+ regs->r11 = addr1;
14243+ regs->r10 = addr2;
14244+ regs->ip = addr1;
14245+ return 2;
14246+ }
14247+ } while (0);
14248+
14249+ do { /* PaX: gcc trampoline emulation #2 */
14250+ unsigned short mov1, mov2, jmp1;
14251+ unsigned char jmp2;
14252+ unsigned long addr1, addr2;
14253+
14254+ err = get_user(mov1, (unsigned short __user *)regs->ip);
14255+ err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
14256+ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
14257+ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
14258+ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
14259+ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
14260+
14261+ if (err)
14262+ break;
14263+
14264+ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
14265+ regs->r11 = addr1;
14266+ regs->r10 = addr2;
14267+ regs->ip = addr1;
14268+ return 2;
14269+ }
14270+ } while (0);
14271+
14272+ return 1; /* PaX in action */
14273+}
14274+#endif
14275+
14276+/*
14277+ * PaX: decide what to do with offenders (regs->ip = fault address)
14278+ *
14279+ * returns 1 when task should be killed
14280+ * 2 when gcc trampoline was detected
14281+ */
14282+static int pax_handle_fetch_fault(struct pt_regs *regs)
14283+{
14284+ if (v8086_mode(regs))
14285+ return 1;
14286+
14287+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
14288+ return 1;
14289+
14290+#ifdef CONFIG_X86_32
14291+ return pax_handle_fetch_fault_32(regs);
14292+#else
14293+ if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
14294+ return pax_handle_fetch_fault_32(regs);
14295+ else
14296+ return pax_handle_fetch_fault_64(regs);
14297+#endif
14298+}
14299+#endif
14300+
14301+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14302+void pax_report_insns(void *pc, void *sp)
14303+{
14304+ long i;
14305+
14306+ printk(KERN_ERR "PAX: bytes at PC: ");
14307+ for (i = 0; i < 20; i++) {
14308+ unsigned char c;
14309+ if (get_user(c, (unsigned char __user *)pc+i))
14310+ printk(KERN_CONT "?? ");
14311+ else
14312+ printk(KERN_CONT "%02x ", c);
14313+ }
14314+ printk("\n");
14315+
14316+ printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
14317+ for (i = -1; i < 80 / sizeof(long); i++) {
14318+ unsigned long c;
14319+ if (get_user(c, (unsigned long __user *)sp+i))
14320+#ifdef CONFIG_X86_32
14321+ printk(KERN_CONT "???????? ");
14322+#else
14323+ printk(KERN_CONT "???????????????? ");
14324+#endif
14325+ else
14326+ printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
14327+ }
14328+ printk("\n");
14329+}
14330+#endif
017d2877
AM
14331diff -urNp linux-2.6.30.4/arch/x86/mm/highmem_32.c linux-2.6.30.4/arch/x86/mm/highmem_32.c
14332--- linux-2.6.30.4/arch/x86/mm/highmem_32.c 2009-07-24 17:47:51.000000000 -0400
14333+++ linux-2.6.30.4/arch/x86/mm/highmem_32.c 2009-07-30 09:48:09.970452952 -0400
14334@@ -32,6 +32,10 @@ void *kmap_atomic_prot(struct page *page
2380c486
JR
14335 enum fixed_addresses idx;
14336 unsigned long vaddr;
14337
14338+#ifdef CONFIG_PAX_KERNEXEC
14339+ unsigned long cr0;
14340+#endif
14341+
14342 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
14343 pagefault_disable();
14344
017d2877 14345@@ -43,7 +47,17 @@ void *kmap_atomic_prot(struct page *page
2380c486
JR
14346 idx = type + KM_TYPE_NR*smp_processor_id();
14347 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
14348 BUG_ON(!pte_none(*(kmap_pte-idx)));
14349+
14350+#ifdef CONFIG_PAX_KERNEXEC
14351+ pax_open_kernel(cr0);
14352+#endif
14353+
14354 set_pte(kmap_pte-idx, mk_pte(page, prot));
14355+
14356+#ifdef CONFIG_PAX_KERNEXEC
14357+ pax_close_kernel(cr0);
14358+#endif
14359+
14360 arch_flush_lazy_mmu_mode();
14361
14362 return (void *)vaddr;
017d2877 14363@@ -59,15 +73,29 @@ void kunmap_atomic(void *kvaddr, enum km
2380c486
JR
14364 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
14365 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
14366
14367+#ifdef CONFIG_PAX_KERNEXEC
14368+ unsigned long cr0;
14369+#endif
14370+
14371 /*
14372 * Force other mappings to Oops if they'll try to access this pte
14373 * without first remap it. Keeping stale mappings around is a bad idea
14374 * also, in case the page changes cacheability attributes or becomes
14375 * a protected page in a hypervisor.
14376 */
14377- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
14378+ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
14379+
14380+#ifdef CONFIG_PAX_KERNEXEC
14381+ pax_open_kernel(cr0);
14382+#endif
14383+
14384 kpte_clear_flush(kmap_pte-idx, vaddr);
14385- else {
14386+
14387+#ifdef CONFIG_PAX_KERNEXEC
14388+ pax_close_kernel(cr0);
14389+#endif
14390+
14391+ } else {
14392 #ifdef CONFIG_DEBUG_HIGHMEM
14393 BUG_ON(vaddr < PAGE_OFFSET);
14394 BUG_ON(vaddr >= (unsigned long)high_memory);
017d2877
AM
14395diff -urNp linux-2.6.30.4/arch/x86/mm/hugetlbpage.c linux-2.6.30.4/arch/x86/mm/hugetlbpage.c
14396--- linux-2.6.30.4/arch/x86/mm/hugetlbpage.c 2009-07-24 17:47:51.000000000 -0400
14397+++ linux-2.6.30.4/arch/x86/mm/hugetlbpage.c 2009-07-30 09:48:09.971412512 -0400
de855c5d 14398@@ -267,13 +267,18 @@ static unsigned long hugetlb_get_unmappe
2380c486
JR
14399 struct hstate *h = hstate_file(file);
14400 struct mm_struct *mm = current->mm;
14401 struct vm_area_struct *vma;
14402- unsigned long start_addr;
14403+ unsigned long start_addr, pax_task_size = TASK_SIZE;
14404+
14405+#ifdef CONFIG_PAX_SEGMEXEC
14406+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
14407+ pax_task_size = SEGMEXEC_TASK_SIZE;
14408+#endif
14409
14410 if (len > mm->cached_hole_size) {
14411- start_addr = mm->free_area_cache;
14412+ start_addr = mm->free_area_cache;
14413 } else {
14414- start_addr = TASK_UNMAPPED_BASE;
14415- mm->cached_hole_size = 0;
14416+ start_addr = mm->mmap_base;
14417+ mm->cached_hole_size = 0;
14418 }
14419
14420 full_search:
de855c5d 14421@@ -281,13 +286,13 @@ full_search:
2380c486
JR
14422
14423 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
14424 /* At this point: (!vma || addr < vma->vm_end). */
14425- if (TASK_SIZE - len < addr) {
14426+ if (pax_task_size - len < addr) {
14427 /*
14428 * Start a new search - just in case we missed
14429 * some holes.
14430 */
14431- if (start_addr != TASK_UNMAPPED_BASE) {
14432- start_addr = TASK_UNMAPPED_BASE;
14433+ if (start_addr != mm->mmap_base) {
14434+ start_addr = mm->mmap_base;
14435 mm->cached_hole_size = 0;
14436 goto full_search;
14437 }
de855c5d 14438@@ -310,9 +315,8 @@ static unsigned long hugetlb_get_unmappe
2380c486
JR
14439 struct hstate *h = hstate_file(file);
14440 struct mm_struct *mm = current->mm;
14441 struct vm_area_struct *vma, *prev_vma;
14442- unsigned long base = mm->mmap_base, addr = addr0;
14443+ unsigned long base = mm->mmap_base, addr;
14444 unsigned long largest_hole = mm->cached_hole_size;
14445- int first_time = 1;
14446
14447 /* don't allow allocations above current base */
14448 if (mm->free_area_cache > base)
de855c5d 14449@@ -322,7 +326,7 @@ static unsigned long hugetlb_get_unmappe
2380c486
JR
14450 largest_hole = 0;
14451 mm->free_area_cache = base;
14452 }
14453-try_again:
14454+
14455 /* make sure it can fit in the remaining address space */
14456 if (mm->free_area_cache < len)
14457 goto fail;
de855c5d 14458@@ -364,22 +368,26 @@ try_again:
2380c486
JR
14459
14460 fail:
14461 /*
14462- * if hint left us with no space for the requested
14463- * mapping then try again:
14464- */
14465- if (first_time) {
14466- mm->free_area_cache = base;
14467- largest_hole = 0;
14468- first_time = 0;
14469- goto try_again;
14470- }
14471- /*
14472 * A failed mmap() very likely causes application failure,
14473 * so fall back to the bottom-up function here. This scenario
14474 * can happen with large stack limits and large mmap()
14475 * allocations.
14476 */
14477- mm->free_area_cache = TASK_UNMAPPED_BASE;
14478+
14479+#ifdef CONFIG_PAX_SEGMEXEC
14480+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
14481+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
14482+ else
14483+#endif
14484+
14485+ mm->mmap_base = TASK_UNMAPPED_BASE;
14486+
14487+#ifdef CONFIG_PAX_RANDMMAP
14488+ if (mm->pax_flags & MF_PAX_RANDMMAP)
14489+ mm->mmap_base += mm->delta_mmap;
14490+#endif
14491+
14492+ mm->free_area_cache = mm->mmap_base;
14493 mm->cached_hole_size = ~0UL;
14494 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
14495 len, pgoff, flags);
de855c5d 14496@@ -387,6 +395,7 @@ fail:
2380c486
JR
14497 /*
14498 * Restore the topdown base:
14499 */
14500+ mm->mmap_base = base;
14501 mm->free_area_cache = base;
14502 mm->cached_hole_size = ~0UL;
14503
de855c5d 14504@@ -400,10 +409,17 @@ hugetlb_get_unmapped_area(struct file *f
2380c486
JR
14505 struct hstate *h = hstate_file(file);
14506 struct mm_struct *mm = current->mm;
14507 struct vm_area_struct *vma;
14508+ unsigned long pax_task_size = TASK_SIZE;
14509
14510 if (len & ~huge_page_mask(h))
14511 return -EINVAL;
14512- if (len > TASK_SIZE)
14513+
14514+#ifdef CONFIG_PAX_SEGMEXEC
14515+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
14516+ pax_task_size = SEGMEXEC_TASK_SIZE;
14517+#endif
14518+
14519+ if (len > pax_task_size)
14520 return -ENOMEM;
14521
14522 if (flags & MAP_FIXED) {
de855c5d 14523@@ -415,7 +431,7 @@ hugetlb_get_unmapped_area(struct file *f
2380c486
JR
14524 if (addr) {
14525 addr = ALIGN(addr, huge_page_size(h));
14526 vma = find_vma(mm, addr);
14527- if (TASK_SIZE - len >= addr &&
14528+ if (pax_task_size - len >= addr &&
14529 (!vma || addr + len <= vma->vm_start))
14530 return addr;
14531 }
017d2877
AM
14532diff -urNp linux-2.6.30.4/arch/x86/mm/init_32.c linux-2.6.30.4/arch/x86/mm/init_32.c
14533--- linux-2.6.30.4/arch/x86/mm/init_32.c 2009-07-24 17:47:51.000000000 -0400
14534+++ linux-2.6.30.4/arch/x86/mm/init_32.c 2009-07-30 09:48:09.972413251 -0400
2380c486
JR
14535@@ -50,6 +50,7 @@
14536 #include <asm/setup.h>
14537 #include <asm/cacheflush.h>
017d2877 14538 #include <asm/init.h>
2380c486
JR
14539+#include <asm/desc.h>
14540
017d2877
AM
14541 unsigned long max_low_pfn_mapped;
14542 unsigned long max_pfn_mapped;
14543@@ -75,36 +76,6 @@ static __init void *alloc_low_page(void)
2380c486
JR
14544 }
14545
14546 /*
14547- * Creates a middle page table and puts a pointer to it in the
14548- * given global directory entry. This only returns the gd entry
14549- * in non-PAE compilation mode, since the middle layer is folded.
14550- */
14551-static pmd_t * __init one_md_table_init(pgd_t *pgd)
14552-{
14553- pud_t *pud;
14554- pmd_t *pmd_table;
14555-
14556-#ifdef CONFIG_X86_PAE
14557- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
017d2877 14558- if (after_bootmem)
2380c486
JR
14559- pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
14560- else
14561- pmd_table = (pmd_t *)alloc_low_page();
14562- paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
14563- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
14564- pud = pud_offset(pgd, 0);
14565- BUG_ON(pmd_table != pmd_offset(pud, 0));
14566-
14567- return pmd_table;
14568- }
14569-#endif
14570- pud = pud_offset(pgd, 0);
14571- pmd_table = pmd_offset(pud, 0);
14572-
14573- return pmd_table;
14574-}
14575-
14576-/*
14577 * Create a page table and place a pointer to it in a middle page
14578 * directory entry:
14579 */
017d2877 14580@@ -124,13 +95,28 @@ static pte_t * __init one_page_table_ini
2380c486
JR
14581 page_table = (pte_t *)alloc_low_page();
14582
14583 paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
14584+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14585+ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
14586+#else
14587 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
14588+#endif
14589 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
14590 }
14591
017d2877
AM
14592 return pte_offset_kernel(pmd, 0);
14593 }
14594
14595+static pmd_t * __init one_md_table_init(pgd_t *pgd)
14596+{
14597+ pud_t *pud;
14598+ pmd_t *pmd_table;
14599+
14600+ pud = pud_offset(pgd, 0);
14601+ pmd_table = pmd_offset(pud, 0);
14602+
14603+ return pmd_table;
14604+}
14605+
14606 pmd_t * __init populate_extra_pmd(unsigned long vaddr)
14607 {
14608 int pgd_idx = pgd_index(vaddr);
14609@@ -204,6 +190,7 @@ page_table_range_init(unsigned long star
2380c486
JR
14610 int pgd_idx, pmd_idx;
14611 unsigned long vaddr;
14612 pgd_t *pgd;
14613+ pud_t *pud;
14614 pmd_t *pmd;
14615 pte_t *pte = NULL;
14616
017d2877 14617@@ -213,8 +200,13 @@ page_table_range_init(unsigned long star
2380c486
JR
14618 pgd = pgd_base + pgd_idx;
14619
14620 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
14621- pmd = one_md_table_init(pgd);
14622- pmd = pmd + pmd_index(vaddr);
14623+ pud = pud_offset(pgd, vaddr);
14624+ pmd = pmd_offset(pud, vaddr);
14625+
14626+#ifdef CONFIG_X86_PAE
14627+ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
14628+#endif
14629+
14630 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
14631 pmd++, pmd_idx++) {
14632 pte = page_table_kmap_check(one_page_table_init(pmd),
017d2877 14633@@ -226,11 +218,23 @@ page_table_range_init(unsigned long star
2380c486
JR
14634 }
14635 }
14636
14637-static inline int is_kernel_text(unsigned long addr)
14638+static inline int is_kernel_text(unsigned long start, unsigned long end)
14639 {
14640- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
14641- return 1;
14642- return 0;
14643+ unsigned long etext;
14644+
14645+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14646+ etext = ktva_ktla((unsigned long)&MODULES_END);
14647+#else
14648+ etext = (unsigned long)&_etext;
14649+#endif
14650+
14651+ if ((start > ktla_ktva(etext) ||
14652+ end <= ktla_ktva((unsigned long)_stext)) &&
14653+ (start > ktla_ktva((unsigned long)_einittext) ||
14654+ end <= ktla_ktva((unsigned long)_sinittext)) &&
14655+ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
14656+ return 0;
14657+ return 1;
14658 }
14659
14660 /*
017d2877
AM
14661@@ -246,9 +250,10 @@ kernel_physical_mapping_init(unsigned lo
14662 int use_pse = page_size_mask == (1<<PG_LEVEL_2M);
14663 unsigned long start_pfn, end_pfn;
14664 pgd_t *pgd_base = swapper_pg_dir;
2380c486
JR
14665- int pgd_idx, pmd_idx, pte_ofs;
14666+ unsigned int pgd_idx, pmd_idx, pte_ofs;
14667 unsigned long pfn;
14668 pgd_t *pgd;
14669+ pud_t *pud;
14670 pmd_t *pmd;
14671 pte_t *pte;
14672 unsigned pages_2m, pages_4k;
017d2877 14673@@ -281,8 +286,13 @@ repeat:
2380c486
JR
14674 pfn = start_pfn;
14675 pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
14676 pgd = pgd_base + pgd_idx;
14677- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
14678- pmd = one_md_table_init(pgd);
14679+ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
14680+ pud = pud_offset(pgd, 0);
14681+ pmd = pmd_offset(pud, 0);
14682+
14683+#ifdef CONFIG_X86_PAE
14684+ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
14685+#endif
14686
14687 if (pfn >= end_pfn)
14688 continue;
017d2877 14689@@ -294,14 +304,13 @@ repeat:
2380c486
JR
14690 #endif
14691 for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
14692 pmd++, pmd_idx++) {
14693- unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
14694+ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
14695
14696 /*
14697 * Map with big pages if possible, otherwise
14698 * create normal page tables:
14699 */
14700 if (use_pse) {
14701- unsigned int addr2;
14702 pgprot_t prot = PAGE_KERNEL_LARGE;
14703 /*
14704 * first pass will use the same initial
017d2877 14705@@ -311,11 +320,7 @@ repeat:
2380c486
JR
14706 __pgprot(PTE_IDENT_ATTR |
14707 _PAGE_PSE);
14708
14709- addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
14710- PAGE_OFFSET + PAGE_SIZE-1;
14711-
14712- if (is_kernel_text(addr) ||
14713- is_kernel_text(addr2))
14714+ if (is_kernel_text(address, address + PMD_SIZE))
14715 prot = PAGE_KERNEL_LARGE_EXEC;
14716
14717 pages_2m++;
017d2877 14718@@ -332,7 +337,7 @@ repeat:
2380c486
JR
14719 pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
14720 pte += pte_ofs;
14721 for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
14722- pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
14723+ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
14724 pgprot_t prot = PAGE_KERNEL;
14725 /*
14726 * first pass will use the same initial
017d2877 14727@@ -340,7 +345,7 @@ repeat:
2380c486
JR
14728 */
14729 pgprot_t init_prot = __pgprot(PTE_IDENT_ATTR);
14730
14731- if (is_kernel_text(addr))
14732+ if (is_kernel_text(address, address + PAGE_SIZE))
14733 prot = PAGE_KERNEL_EXEC;
14734
14735 pages_4k++;
017d2877 14736@@ -492,7 +497,7 @@ void __init native_pagetable_setup_start
2380c486
JR
14737
14738 pud = pud_offset(pgd, va);
14739 pmd = pmd_offset(pud, va);
14740- if (!pmd_present(*pmd))
14741+ if (!pmd_present(*pmd) || pmd_huge(*pmd))
14742 break;
14743
14744 pte = pte_offset_kernel(pmd, va);
017d2877 14745@@ -544,9 +549,7 @@ void __init early_ioremap_page_table_ran
2380c486
JR
14746
14747 static void __init pagetable_init(void)
14748 {
14749- pgd_t *pgd_base = swapper_pg_dir;
14750-
14751- permanent_kmaps_init(pgd_base);
14752+ permanent_kmaps_init(swapper_pg_dir);
14753 }
14754
14755 #ifdef CONFIG_ACPI_SLEEP
017d2877 14756@@ -554,12 +557,12 @@ static void __init pagetable_init(void)
2380c486
JR
14757 * ACPI suspend needs this for resume, because things like the intel-agp
14758 * driver might have split up a kernel 4MB mapping.
14759 */
14760-char swsusp_pg_dir[PAGE_SIZE]
14761+pgd_t swsusp_pg_dir[PTRS_PER_PGD]
14762 __attribute__ ((aligned(PAGE_SIZE)));
14763
14764 static inline void save_pg_dir(void)
14765 {
14766- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
14767+ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
14768 }
14769 #else /* !CONFIG_ACPI_SLEEP */
14770 static inline void save_pg_dir(void)
017d2877 14771@@ -589,13 +592,11 @@ void zap_low_mappings(void)
2380c486
JR
14772
14773 int nx_enabled;
14774
14775-pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
14776+pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
14777 EXPORT_SYMBOL_GPL(__supported_pte_mask);
14778
14779 #ifdef CONFIG_X86_PAE
14780
14781-static int disable_nx __initdata;
14782-
14783 /*
14784 * noexec = on|off
14785 *
017d2877 14786@@ -604,40 +605,33 @@ static int disable_nx __initdata;
2380c486
JR
14787 * on Enable
14788 * off Disable
14789 */
14790+#if !defined(CONFIG_PAX_PAGEEXEC)
14791 static int __init noexec_setup(char *str)
14792 {
14793 if (!str || !strcmp(str, "on")) {
14794- if (cpu_has_nx) {
14795- __supported_pte_mask |= _PAGE_NX;
14796- disable_nx = 0;
14797- }
14798+ if (cpu_has_nx)
14799+ nx_enabled = 1;
14800 } else {
14801- if (!strcmp(str, "off")) {
14802- disable_nx = 1;
14803- __supported_pte_mask &= ~_PAGE_NX;
14804- } else {
14805+ if (!strcmp(str, "off"))
14806+ nx_enabled = 0;
14807+ else
14808 return -EINVAL;
14809- }
14810 }
14811
14812 return 0;
14813 }
14814 early_param("noexec", noexec_setup);
14815+#endif
14816
017d2877 14817 void __init set_nx(void)
2380c486
JR
14818 {
14819- unsigned int v[4], l, h;
2380c486
JR
14820+ if (!nx_enabled && cpu_has_nx) {
14821+ unsigned l, h;
14822
de855c5d
AM
14823- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
14824- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
14825-
2380c486
JR
14826- if ((v[3] & (1 << 20)) && !disable_nx) {
14827- rdmsr(MSR_EFER, l, h);
14828- l |= EFER_NX;
14829- wrmsr(MSR_EFER, l, h);
14830- nx_enabled = 1;
14831- __supported_pte_mask |= _PAGE_NX;
14832- }
14833+ __supported_pte_mask &= ~_PAGE_NX;
14834+ rdmsr(MSR_EFER, l, h);
14835+ l &= ~EFER_NX;
14836+ wrmsr(MSR_EFER, l, h);
14837 }
14838 }
14839 #endif
017d2877 14840@@ -934,7 +928,7 @@ void __init mem_init(void)
2380c486
JR
14841 set_highmem_pages_init();
14842
14843 codesize = (unsigned long) &_etext - (unsigned long) &_text;
14844- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
14845+ datasize = (unsigned long) &_edata - (unsigned long) &_data;
14846 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
14847
14848 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
017d2877 14849@@ -980,10 +974,10 @@ void __init mem_init(void)
2380c486
JR
14850 ((unsigned long)&__init_end -
14851 (unsigned long)&__init_begin) >> 10,
14852
14853- (unsigned long)&_etext, (unsigned long)&_edata,
14854- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
14855+ (unsigned long)&_data, (unsigned long)&_edata,
14856+ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
14857
14858- (unsigned long)&_text, (unsigned long)&_etext,
14859+ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
14860 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
14861
14862 /*
017d2877
AM
14863diff -urNp linux-2.6.30.4/arch/x86/mm/init_64.c linux-2.6.30.4/arch/x86/mm/init_64.c
14864--- linux-2.6.30.4/arch/x86/mm/init_64.c 2009-07-24 17:47:51.000000000 -0400
14865+++ linux-2.6.30.4/arch/x86/mm/init_64.c 2009-07-30 09:48:09.972413251 -0400
14866@@ -202,12 +202,24 @@ void set_pte_vaddr_pud(pud_t *pud_page,
2380c486
JR
14867 pmd_t *pmd;
14868 pte_t *pte;
14869
14870+#ifdef CONFIG_PAX_KERNEXEC
14871+ unsigned long cr0;
14872+#endif
14873+
14874 pud = pud_page + pud_index(vaddr);
017d2877
AM
14875 pmd = fill_pmd(pud, vaddr);
14876 pte = fill_pte(pmd, vaddr);
2380c486 14877
2380c486
JR
14878+#ifdef CONFIG_PAX_KERNEXEC
14879+ pax_open_kernel(cr0);
14880+#endif
14881+
14882 set_pte(pte, new_pte);
14883
14884+#ifdef CONFIG_PAX_KERNEXEC
14885+ pax_close_kernel(cr0);
14886+#endif
14887+
14888 /*
14889 * It's enough to flush this one mapping.
14890 * (PGE mappings get flushed as well)
017d2877 14891@@ -265,14 +277,12 @@ static void __init __init_extra_mapping(
2380c486
JR
14892 pgd = pgd_offset_k((unsigned long)__va(phys));
14893 if (pgd_none(*pgd)) {
14894 pud = (pud_t *) spp_getpage();
14895- set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
14896- _PAGE_USER));
14897+ set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
14898 }
14899 pud = pud_offset(pgd, (unsigned long)__va(phys));
14900 if (pud_none(*pud)) {
14901 pmd = (pmd_t *) spp_getpage();
14902- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
14903- _PAGE_USER));
14904+ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
14905 }
14906 pmd = pmd_offset(pud, phys);
14907 BUG_ON(!pmd_none(*pmd));
017d2877
AM
14908@@ -882,8 +892,8 @@ int kern_addr_valid(unsigned long addr)
14909 static struct vm_area_struct gate_vma = {
14910 .vm_start = VSYSCALL_START,
14911 .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE),
14912- .vm_page_prot = PAGE_READONLY_EXEC,
14913- .vm_flags = VM_READ | VM_EXEC
14914+ .vm_page_prot = PAGE_READONLY,
14915+ .vm_flags = VM_READ
14916 };
14917
14918 struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
14919@@ -917,7 +927,7 @@ int in_gate_area_no_task(unsigned long a
14920
14921 const char *arch_vma_name(struct vm_area_struct *vma)
14922 {
14923- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
14924+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
14925 return "[vdso]";
14926 if (vma == &gate_vma)
14927 return "[vsyscall]";
14928diff -urNp linux-2.6.30.4/arch/x86/mm/init.c linux-2.6.30.4/arch/x86/mm/init.c
14929--- linux-2.6.30.4/arch/x86/mm/init.c 2009-07-24 17:47:51.000000000 -0400
14930+++ linux-2.6.30.4/arch/x86/mm/init.c 2009-07-30 09:48:09.971412512 -0400
14931@@ -348,7 +348,13 @@ unsigned long __init_refok init_memory_m
2380c486
JR
14932 */
14933 int devmem_is_allowed(unsigned long pagenr)
14934 {
14935- if (pagenr <= 256)
14936+ if (!pagenr)
14937+ return 1;
017d2877
AM
14938+#ifdef CONFIG_VM86
14939+ if (pagenr < (ISA_START_ADDRESS >> PAGE_SHIFT))
14940+ return 1;
14941+#endif
2380c486
JR
14942+ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
14943 return 1;
14944 if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
14945 return 0;
017d2877 14946@@ -396,6 +402,75 @@ void free_init_pages(char *what, unsigne
2380c486
JR
14947
14948 void free_initmem(void)
14949 {
14950+
14951+#ifdef CONFIG_PAX_KERNEXEC
2380c486
JR
14952+ pgd_t *pgd;
14953+ pud_t *pud;
14954+ pmd_t *pmd;
14955+
017d2877
AM
14956+#ifdef CONFIG_X86_32
14957+ /* PaX: limit KERNEL_CS to actual size */
14958+ unsigned long addr, limit;
14959+ struct desc_struct d;
14960+ int cpu;
14961+
14962+#ifdef CONFIG_MODULES
14963+ limit = ktva_ktla((unsigned long)&MODULES_END);
14964+#else
14965+ limit = (unsigned long)&_etext;
14966+#endif
14967+ limit = (limit - 1UL) >> PAGE_SHIFT;
14968+
14969+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
14970+ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
14971+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
14972+ }
14973+
14974+ /* PaX: make KERNEL_CS read-only */
14975+ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
14976+ pgd = pgd_offset_k(addr);
14977+ pud = pud_offset(pgd, addr);
14978+ pmd = pmd_offset(pud, addr);
14979+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
14980+ }
14981+#ifdef CONFIG_X86_PAE
14982+ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
14983+ pgd = pgd_offset_k(addr);
14984+ pud = pud_offset(pgd, addr);
14985+ pmd = pmd_offset(pud, addr);
14986+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
14987+ }
14988+#endif
14989+#else
14990+ unsigned long addr, end;
14991+
2380c486
JR
14992+ /* PaX: make kernel code/rodata read-only, rest non-executable */
14993+ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
14994+ pgd = pgd_offset_k(addr);
14995+ pud = pud_offset(pgd, addr);
14996+ pmd = pmd_offset(pud, addr);
14997+ if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
14998+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
14999+ else
15000+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
15001+ }
15002+
15003+ addr = (unsigned long)__va(__pa(__START_KERNEL_map));
15004+ end = addr + KERNEL_IMAGE_SIZE;
15005+ for (; addr < end; addr += PMD_SIZE) {
15006+ pgd = pgd_offset_k(addr);
15007+ pud = pud_offset(pgd, addr);
15008+ pmd = pmd_offset(pud, addr);
15009+ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
15010+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
15011+ else
15012+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
15013+ }
017d2877 15014+#endif
2380c486
JR
15015+
15016+ flush_tlb_all();
15017+#endif
15018+
15019 free_init_pages("unused kernel memory",
15020 (unsigned long)(&__init_begin),
15021 (unsigned long)(&__init_end));
017d2877
AM
15022diff -urNp linux-2.6.30.4/arch/x86/mm/iomap_32.c linux-2.6.30.4/arch/x86/mm/iomap_32.c
15023--- linux-2.6.30.4/arch/x86/mm/iomap_32.c 2009-07-24 17:47:51.000000000 -0400
15024+++ linux-2.6.30.4/arch/x86/mm/iomap_32.c 2009-07-30 09:48:09.973477350 -0400
15025@@ -37,12 +37,26 @@ void *kmap_atomic_prot_pfn(unsigned long
15026 enum fixed_addresses idx;
15027 unsigned long vaddr;
de855c5d 15028
017d2877
AM
15029+#ifdef CONFIG_PAX_KERNEXEC
15030+ unsigned long cr0;
15031+#endif
15032+
15033 pagefault_disable();
2380c486 15034
017d2877
AM
15035 debug_kmap_atomic(type);
15036 idx = type + KM_TYPE_NR * smp_processor_id();
15037 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
15038+
15039+#ifdef CONFIG_PAX_KERNEXEC
15040+ pax_open_kernel(cr0);
15041+#endif
15042+
15043 set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
15044+
15045+#ifdef CONFIG_PAX_KERNEXEC
15046+ pax_close_kernel(cr0);
15047+#endif
15048+
15049 arch_flush_lazy_mmu_mode();
15050
15051 return (void *)vaddr;
15052diff -urNp linux-2.6.30.4/arch/x86/mm/ioremap.c linux-2.6.30.4/arch/x86/mm/ioremap.c
15053--- linux-2.6.30.4/arch/x86/mm/ioremap.c 2009-07-24 17:47:51.000000000 -0400
15054+++ linux-2.6.30.4/arch/x86/mm/ioremap.c 2009-07-30 19:56:23.514032300 -0400
15055@@ -111,8 +111,8 @@ int page_is_ram(unsigned long pagenr)
2380c486
JR
15056 * Second special case: Some BIOSen report the PC BIOS
15057 * area (640->1Mb) as ram even though it is not.
15058 */
15059- if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
15060- pagenr < (BIOS_END >> PAGE_SHIFT))
15061+ if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
15062+ pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
15063 return 0;
15064
15065 for (i = 0; i < e820.nr_map; i++) {
017d2877
AM
15066@@ -207,10 +207,7 @@ static void __iomem *__ioremap_caller(re
15067 /*
15068 * Don't allow anybody to remap normal RAM that we're using..
15069 */
15070- for (pfn = phys_addr >> PAGE_SHIFT;
15071- (pfn << PAGE_SHIFT) < (last_addr & PAGE_MASK);
15072- pfn++) {
15073-
15074+ for (pfn = phys_addr >> PAGE_SHIFT; ((resource_size_t)pfn << PAGE_SHIFT) < (last_addr & PAGE_MASK); pfn++) {
15075 int is_ram = page_is_ram(pfn);
15076
15077 if (is_ram && pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn)))
15078@@ -272,6 +269,8 @@ static void __iomem *__ioremap_caller(re
2380c486
JR
15079 break;
15080 }
15081
15082+ prot = canon_pgprot(prot);
15083+
15084 /*
15085 * Ok, go for it..
15086 */
017d2877 15087@@ -489,7 +488,6 @@ static int __init early_ioremap_debug_se
2380c486
JR
15088 early_param("early_ioremap_debug", early_ioremap_debug_setup);
15089
15090 static __initdata int after_paging_init;
15091-static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
2380c486
JR
15092
15093 static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
15094 {
017d2877
AM
15095@@ -502,11 +500,6 @@ static inline pmd_t * __init early_iorem
15096 return pmd;
2380c486
JR
15097 }
15098
017d2877
AM
15099-static inline pte_t * __init early_ioremap_pte(unsigned long addr)
15100-{
15101- return &bm_pte[pte_index(addr)];
15102-}
15103-
15104 static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata;
15105
2380c486 15106 void __init early_ioremap_init(void)
017d2877
AM
15107@@ -521,8 +514,6 @@ void __init early_ioremap_init(void)
15108 slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
2380c486
JR
15109
15110 pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
017d2877
AM
15111- memset(bm_pte, 0, sizeof(bm_pte));
15112- pmd_populate_kernel(&init_mm, pmd, bm_pte);
2380c486
JR
15113
15114 /*
15115 * The boot-ioremap range spans multiple pmds, for which
017d2877
AM
15116@@ -552,13 +543,15 @@ static void __init __early_set_fixmap(en
15117 phys_addr_t phys, pgprot_t flags)
15118 {
15119 unsigned long addr = __fix_to_virt(idx);
15120+ unsigned int level;
15121 pte_t *pte;
15122
15123 if (idx >= __end_of_fixed_addresses) {
15124 BUG();
15125 return;
15126 }
15127- pte = early_ioremap_pte(addr);
15128+ pte = lookup_address(addr, &level);
15129+ BUG_ON(!pte || level != PG_LEVEL_4K);
15130
15131 if (pgprot_val(flags))
15132 set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags));
15133diff -urNp linux-2.6.30.4/arch/x86/mm/mmap.c linux-2.6.30.4/arch/x86/mm/mmap.c
15134--- linux-2.6.30.4/arch/x86/mm/mmap.c 2009-07-24 17:47:51.000000000 -0400
15135+++ linux-2.6.30.4/arch/x86/mm/mmap.c 2009-07-30 09:48:09.973477350 -0400
2380c486
JR
15136@@ -36,7 +36,7 @@
15137 * Leave an at least ~128 MB hole.
15138 */
15139 #define MIN_GAP (128*1024*1024)
15140-#define MAX_GAP (TASK_SIZE/6*5)
15141+#define MAX_GAP (pax_task_size/6*5)
15142
15143 /*
15144 * True on X86_32 or when emulating IA32 on X86_64
15145@@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
15146 return rnd << PAGE_SHIFT;
15147 }
15148
15149-static unsigned long mmap_base(void)
15150+static unsigned long mmap_base(struct mm_struct *mm)
15151 {
15152 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
15153+ unsigned long pax_task_size = TASK_SIZE;
15154+
15155+#ifdef CONFIG_PAX_SEGMEXEC
15156+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
15157+ pax_task_size = SEGMEXEC_TASK_SIZE;
15158+#endif
15159
15160 if (gap < MIN_GAP)
15161 gap = MIN_GAP;
15162 else if (gap > MAX_GAP)
15163 gap = MAX_GAP;
15164
15165- return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
15166+ return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
15167 }
15168
15169 /*
15170 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
15171 * does, but not when emulating X86_32
15172 */
15173-static unsigned long mmap_legacy_base(void)
15174+static unsigned long mmap_legacy_base(struct mm_struct *mm)
15175 {
15176- if (mmap_is_ia32())
15177+ if (mmap_is_ia32()) {
15178+
15179+#ifdef CONFIG_PAX_SEGMEXEC
15180+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
15181+ return SEGMEXEC_TASK_UNMAPPED_BASE;
15182+ else
15183+#endif
15184+
15185 return TASK_UNMAPPED_BASE;
15186- else
15187+ } else
15188 return TASK_UNMAPPED_BASE + mmap_rnd();
15189 }
15190
15191@@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
15192 void arch_pick_mmap_layout(struct mm_struct *mm)
15193 {
15194 if (mmap_is_legacy()) {
15195- mm->mmap_base = mmap_legacy_base();
15196+ mm->mmap_base = mmap_legacy_base(mm);
15197+
15198+#ifdef CONFIG_PAX_RANDMMAP
15199+ if (mm->pax_flags & MF_PAX_RANDMMAP)
15200+ mm->mmap_base += mm->delta_mmap;
15201+#endif
15202+
15203 mm->get_unmapped_area = arch_get_unmapped_area;
15204 mm->unmap_area = arch_unmap_area;
15205 } else {
15206- mm->mmap_base = mmap_base();
15207+ mm->mmap_base = mmap_base(mm);
15208+
15209+#ifdef CONFIG_PAX_RANDMMAP
15210+ if (mm->pax_flags & MF_PAX_RANDMMAP)
15211+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
15212+#endif
15213+
15214 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
15215 mm->unmap_area = arch_unmap_area_topdown;
15216 }
017d2877
AM
15217diff -urNp linux-2.6.30.4/arch/x86/mm/numa_32.c linux-2.6.30.4/arch/x86/mm/numa_32.c
15218--- linux-2.6.30.4/arch/x86/mm/numa_32.c 2009-07-24 17:47:51.000000000 -0400
15219+++ linux-2.6.30.4/arch/x86/mm/numa_32.c 2009-07-30 09:48:09.974436034 -0400
2380c486
JR
15220@@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int
15221 }
15222 #endif
15223
15224-extern unsigned long find_max_low_pfn(void);
15225 extern unsigned long highend_pfn, highstart_pfn;
15226
15227 #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
017d2877
AM
15228diff -urNp linux-2.6.30.4/arch/x86/mm/pageattr.c linux-2.6.30.4/arch/x86/mm/pageattr.c
15229--- linux-2.6.30.4/arch/x86/mm/pageattr.c 2009-07-24 17:47:51.000000000 -0400
15230+++ linux-2.6.30.4/arch/x86/mm/pageattr.c 2009-07-30 09:48:09.974436034 -0400
15231@@ -21,6 +21,7 @@
2380c486
JR
15232 #include <asm/pgalloc.h>
15233 #include <asm/proto.h>
15234 #include <asm/pat.h>
15235+#include <asm/desc.h>
15236
15237 /*
15238 * The current flushing context - we pass it instead of 5 arguments:
017d2877 15239@@ -265,9 +266,10 @@ static inline pgprot_t static_protection
2380c486
JR
15240 * Does not cover __inittext since that is gone later on. On
15241 * 64bit we do not enforce !NX on the low mapping
15242 */
15243- if (within(address, (unsigned long)_text, (unsigned long)_etext))
15244+ if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
15245 pgprot_val(forbidden) |= _PAGE_NX;
15246
de855c5d 15247+#ifdef CONFIG_DEBUG_RODATA
2380c486 15248 /*
de855c5d
AM
15249 * The .rodata section needs to be read-only. Using the pfn
15250 * catches all aliases.
017d2877 15251@@ -275,6 +277,7 @@ static inline pgprot_t static_protection
de855c5d
AM
15252 if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT,
15253 __pa((unsigned long)__end_rodata) >> PAGE_SHIFT))
15254 pgprot_val(forbidden) |= _PAGE_RW;
15255+#endif
15256
15257 prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
15258
017d2877 15259@@ -327,8 +330,20 @@ EXPORT_SYMBOL_GPL(lookup_address);
2380c486
JR
15260 */
15261 static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
15262 {
15263+
15264+#ifdef CONFIG_PAX_KERNEXEC
15265+ unsigned long cr0;
15266+
15267+ pax_open_kernel(cr0);
15268+#endif
15269+
15270 /* change init_mm */
15271 set_pte_atomic(kpte, pte);
15272+
15273+#ifdef CONFIG_PAX_KERNEXEC
15274+ pax_close_kernel(cr0);
15275+#endif
15276+
15277 #ifdef CONFIG_X86_32
15278 if (!SHARED_KERNEL_PMD) {
15279 struct page *page;
017d2877
AM
15280diff -urNp linux-2.6.30.4/arch/x86/mm/pageattr-test.c linux-2.6.30.4/arch/x86/mm/pageattr-test.c
15281--- linux-2.6.30.4/arch/x86/mm/pageattr-test.c 2009-07-24 17:47:51.000000000 -0400
15282+++ linux-2.6.30.4/arch/x86/mm/pageattr-test.c 2009-07-30 09:48:09.974436034 -0400
2380c486
JR
15283@@ -36,7 +36,7 @@ enum {
15284
15285 static int pte_testbit(pte_t pte)
15286 {
15287- return pte_flags(pte) & _PAGE_UNUSED1;
15288+ return pte_flags(pte) & _PAGE_CPA_TEST;
15289 }
15290
15291 struct split_state {
017d2877
AM
15292diff -urNp linux-2.6.30.4/arch/x86/mm/pat.c linux-2.6.30.4/arch/x86/mm/pat.c
15293--- linux-2.6.30.4/arch/x86/mm/pat.c 2009-07-24 17:47:51.000000000 -0400
15294+++ linux-2.6.30.4/arch/x86/mm/pat.c 2009-07-30 09:48:09.975412278 -0400
15295@@ -213,7 +213,7 @@ chk_conflict(struct memtype *new, struct
de855c5d
AM
15296
15297 conflict:
15298 printk(KERN_INFO "%s:%d conflicting memory types "
15299- "%Lx-%Lx %s<->%s\n", current->comm, current->pid, new->start,
15300+ "%Lx-%Lx %s<->%s\n", current->comm, task_pid_nr(current), new->start,
15301 new->end, cattr_name(new->type), cattr_name(entry->type));
15302 return -EBUSY;
15303 }
017d2877 15304@@ -487,7 +487,7 @@ int free_memtype(u64 start, u64 end)
de855c5d
AM
15305
15306 if (err) {
15307 printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n",
15308- current->comm, current->pid, start, end);
15309+ current->comm, task_pid_nr(current), start, end);
15310 }
2380c486 15311
de855c5d 15312 dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end);
017d2877 15313@@ -588,7 +588,7 @@ int kernel_map_sync_memtype(u64 base, un
de855c5d 15314 printk(KERN_INFO
017d2877
AM
15315 "%s:%d ioremap_change_attr failed %s "
15316 "for %Lx-%Lx\n",
de855c5d
AM
15317- current->comm, current->pid,
15318+ current->comm, task_pid_nr(current),
15319 cattr_name(flags),
017d2877
AM
15320 base, (unsigned long long)(base + size));
15321 return -EINVAL;
15322@@ -627,7 +627,7 @@ static int reserve_pfn_range(u64 paddr,
de855c5d
AM
15323 free_memtype(paddr, paddr + size);
15324 printk(KERN_ERR "%s:%d map pfn expected mapping type %s"
15325 " for %Lx-%Lx, got %s\n",
15326- current->comm, current->pid,
15327+ current->comm, task_pid_nr(current),
15328 cattr_name(want_flags),
15329 (unsigned long long)paddr,
15330 (unsigned long long)(paddr + size),
017d2877
AM
15331@@ -826,7 +826,7 @@ static int memtype_seq_show(struct seq_f
15332 return 0;
15333 }
15334
15335-static struct seq_operations memtype_seq_ops = {
15336+static const struct seq_operations memtype_seq_ops = {
15337 .start = memtype_seq_start,
15338 .next = memtype_seq_next,
15339 .stop = memtype_seq_stop,
15340diff -urNp linux-2.6.30.4/arch/x86/mm/pgtable_32.c linux-2.6.30.4/arch/x86/mm/pgtable_32.c
15341--- linux-2.6.30.4/arch/x86/mm/pgtable_32.c 2009-07-24 17:47:51.000000000 -0400
15342+++ linux-2.6.30.4/arch/x86/mm/pgtable_32.c 2009-07-30 09:48:09.975412278 -0400
15343@@ -33,6 +33,10 @@ void set_pte_vaddr(unsigned long vaddr,
2380c486
JR
15344 pmd_t *pmd;
15345 pte_t *pte;
15346
15347+#ifdef CONFIG_PAX_KERNEXEC
15348+ unsigned long cr0;
15349+#endif
15350+
15351 pgd = swapper_pg_dir + pgd_index(vaddr);
15352 if (pgd_none(*pgd)) {
15353 BUG();
017d2877 15354@@ -49,11 +53,20 @@ void set_pte_vaddr(unsigned long vaddr,
2380c486
JR
15355 return;
15356 }
15357 pte = pte_offset_kernel(pmd, vaddr);
15358+
15359+#ifdef CONFIG_PAX_KERNEXEC
15360+ pax_open_kernel(cr0);
15361+#endif
15362+
15363 if (pte_val(pteval))
017d2877 15364 set_pte_at(&init_mm, vaddr, pte, pteval);
2380c486
JR
15365 else
15366 pte_clear(&init_mm, vaddr, pte);
15367
15368+#ifdef CONFIG_PAX_KERNEXEC
15369+ pax_close_kernel(cr0);
15370+#endif
15371+
15372 /*
15373 * It's enough to flush this one mapping.
15374 * (PGE mappings get flushed as well)
017d2877
AM
15375diff -urNp linux-2.6.30.4/arch/x86/mm/tlb.c linux-2.6.30.4/arch/x86/mm/tlb.c
15376--- linux-2.6.30.4/arch/x86/mm/tlb.c 2009-07-24 17:47:51.000000000 -0400
15377+++ linux-2.6.30.4/arch/x86/mm/tlb.c 2009-07-30 09:48:09.975412278 -0400
15378@@ -12,7 +12,7 @@
15379 #include <asm/uv/uv.h>
15380
15381 DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
15382- = { &init_mm, 0, };
15383+ = { &init_mm, 0 };
15384
15385 /*
15386 * Smarter SMP flushing macros.
15387diff -urNp linux-2.6.30.4/arch/x86/oprofile/backtrace.c linux-2.6.30.4/arch/x86/oprofile/backtrace.c
15388--- linux-2.6.30.4/arch/x86/oprofile/backtrace.c 2009-07-24 17:47:51.000000000 -0400
15389+++ linux-2.6.30.4/arch/x86/oprofile/backtrace.c 2009-07-30 09:48:09.975412278 -0400
2380c486
JR
15390@@ -37,7 +37,7 @@ static void backtrace_address(void *data
15391 unsigned int *depth = data;
15392
15393 if ((*depth)--)
15394- oprofile_add_trace(addr);
15395+ oprofile_add_trace(ktla_ktva(addr));
15396 }
15397
15398 static struct stacktrace_ops backtrace_ops = {
017d2877
AM
15399@@ -77,7 +77,7 @@ x86_backtrace(struct pt_regs * const reg
15400 {
2380c486 15401 struct frame_head *head = (struct frame_head *)frame_pointer(regs);
2380c486
JR
15402
15403- if (!user_mode_vm(regs)) {
15404+ if (!user_mode(regs)) {
017d2877 15405 unsigned long stack = kernel_stack_pointer(regs);
2380c486
JR
15406 if (depth)
15407 dump_trace(NULL, regs, (unsigned long *)stack, 0,
017d2877
AM
15408diff -urNp linux-2.6.30.4/arch/x86/oprofile/op_model_p4.c linux-2.6.30.4/arch/x86/oprofile/op_model_p4.c
15409--- linux-2.6.30.4/arch/x86/oprofile/op_model_p4.c 2009-07-24 17:47:51.000000000 -0400
15410+++ linux-2.6.30.4/arch/x86/oprofile/op_model_p4.c 2009-07-30 09:48:09.976413155 -0400
2380c486
JR
15411@@ -48,7 +48,7 @@ static inline void setup_num_counters(vo
15412 #endif
15413 }
15414
15415-static int inline addr_increment(void)
15416+static inline int addr_increment(void)
15417 {
15418 #ifdef CONFIG_SMP
15419 return smp_num_siblings == 2 ? 2 : 1;
017d2877
AM
15420diff -urNp linux-2.6.30.4/arch/x86/pci/common.c linux-2.6.30.4/arch/x86/pci/common.c
15421--- linux-2.6.30.4/arch/x86/pci/common.c 2009-07-24 17:47:51.000000000 -0400
15422+++ linux-2.6.30.4/arch/x86/pci/common.c 2009-07-30 09:48:09.976413155 -0400
15423@@ -370,7 +370,7 @@ static const struct dmi_system_id __devi
2380c486
JR
15424 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
15425 },
15426 },
15427- {}
15428+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
15429 };
15430
15431 void __init dmi_check_pciprobe(void)
017d2877
AM
15432diff -urNp linux-2.6.30.4/arch/x86/pci/fixup.c linux-2.6.30.4/arch/x86/pci/fixup.c
15433--- linux-2.6.30.4/arch/x86/pci/fixup.c 2009-07-24 17:47:51.000000000 -0400
15434+++ linux-2.6.30.4/arch/x86/pci/fixup.c 2009-07-30 09:48:09.976413155 -0400
15435@@ -364,7 +364,7 @@ static const struct dmi_system_id __devi
2380c486
JR
15436 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
15437 },
15438 },
15439- {}
15440+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15441 };
15442
15443 /*
017d2877 15444@@ -435,7 +435,7 @@ static const struct dmi_system_id __devi
2380c486
JR
15445 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
15446 },
15447 },
15448- { }
15449+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15450 };
15451
15452 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
017d2877
AM
15453diff -urNp linux-2.6.30.4/arch/x86/pci/i386.c linux-2.6.30.4/arch/x86/pci/i386.c
15454--- linux-2.6.30.4/arch/x86/pci/i386.c 2009-07-30 20:32:40.384629006 -0400
15455+++ linux-2.6.30.4/arch/x86/pci/i386.c 2009-07-30 20:32:47.941604516 -0400
15456@@ -269,7 +269,7 @@ void pcibios_set_master(struct pci_dev *
15457 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
15458 }
15459
15460-static struct vm_operations_struct pci_mmap_ops = {
15461+static const struct vm_operations_struct pci_mmap_ops = {
15462 .access = generic_access_phys,
15463 };
15464
15465diff -urNp linux-2.6.30.4/arch/x86/pci/irq.c linux-2.6.30.4/arch/x86/pci/irq.c
15466--- linux-2.6.30.4/arch/x86/pci/irq.c 2009-07-24 17:47:51.000000000 -0400
15467+++ linux-2.6.30.4/arch/x86/pci/irq.c 2009-07-30 09:48:09.976413155 -0400
2380c486
JR
15468@@ -543,7 +543,7 @@ static __init int intel_router_probe(str
15469 static struct pci_device_id __initdata pirq_440gx[] = {
15470 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
15471 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
15472- { },
15473+ { PCI_DEVICE(0, 0) }
15474 };
15475
15476 /* 440GX has a proprietary PIRQ router -- don't use it */
15477@@ -1145,7 +1145,7 @@ static struct dmi_system_id __initdata p
15478 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
15479 },
15480 },
15481- { }
15482+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
15483 };
15484
15485 int __init pcibios_irq_init(void)
017d2877
AM
15486diff -urNp linux-2.6.30.4/arch/x86/pci/pcbios.c linux-2.6.30.4/arch/x86/pci/pcbios.c
15487--- linux-2.6.30.4/arch/x86/pci/pcbios.c 2009-07-24 17:47:51.000000000 -0400
15488+++ linux-2.6.30.4/arch/x86/pci/pcbios.c 2009-07-30 09:48:09.976413155 -0400
2380c486
JR
15489@@ -56,50 +56,120 @@ union bios32 {
15490 static struct {
15491 unsigned long address;
15492 unsigned short segment;
15493-} bios32_indirect = { 0, __KERNEL_CS };
15494+} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
15495
15496 /*
15497 * Returns the entry point for the given service, NULL on error
15498 */
15499
15500-static unsigned long bios32_service(unsigned long service)
15501+static unsigned long __devinit bios32_service(unsigned long service)
15502 {
15503 unsigned char return_code; /* %al */
15504 unsigned long address; /* %ebx */
15505 unsigned long length; /* %ecx */
15506 unsigned long entry; /* %edx */
15507 unsigned long flags;
15508+ struct desc_struct d, *gdt;
15509+
15510+#ifdef CONFIG_PAX_KERNEXEC
15511+ unsigned long cr0;
15512+#endif
15513
15514 local_irq_save(flags);
15515- __asm__("lcall *(%%edi); cld"
15516+
15517+ gdt = get_cpu_gdt_table(smp_processor_id());
15518+
15519+#ifdef CONFIG_PAX_KERNEXEC
15520+ pax_open_kernel(cr0);
15521+#endif
15522+
15523+ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
15524+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
15525+ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
15526+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
15527+
15528+#ifdef CONFIG_PAX_KERNEXEC
15529+ pax_close_kernel(cr0);
15530+#endif
15531+
15532+ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
15533 : "=a" (return_code),
15534 "=b" (address),
15535 "=c" (length),
15536 "=d" (entry)
15537 : "0" (service),
15538 "1" (0),
15539- "D" (&bios32_indirect));
15540+ "D" (&bios32_indirect),
15541+ "r"(__PCIBIOS_DS)
15542+ : "memory");
15543+
15544+#ifdef CONFIG_PAX_KERNEXEC
15545+ pax_open_kernel(cr0);
15546+#endif
15547+
15548+ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
15549+ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
15550+ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
15551+ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
15552+
15553+#ifdef CONFIG_PAX_KERNEXEC
15554+ pax_close_kernel(cr0);
15555+#endif
15556+
15557 local_irq_restore(flags);
15558
15559 switch (return_code) {
15560- case 0:
15561- return address + entry;
15562- case 0x80: /* Not present */
15563- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
15564- return 0;
15565- default: /* Shouldn't happen */
15566- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
15567- service, return_code);
15568+ case 0: {
15569+ int cpu;
15570+ unsigned char flags;
15571+
15572+ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
15573+ if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
15574+ printk(KERN_WARNING "bios32_service: not valid\n");
15575 return 0;
15576+ }
15577+ address = address + PAGE_OFFSET;
15578+ length += 16UL; /* some BIOSs underreport this... */
15579+ flags = 4;
15580+ if (length >= 64*1024*1024) {
15581+ length >>= PAGE_SHIFT;
15582+ flags |= 8;
15583+ }
15584+
15585+#ifdef CONFIG_PAX_KERNEXEC
15586+ pax_open_kernel(cr0);
15587+#endif
15588+
15589+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
15590+ gdt = get_cpu_gdt_table(cpu);
15591+ pack_descriptor(&d, address, length, 0x9b, flags);
15592+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
15593+ pack_descriptor(&d, address, length, 0x93, flags);
15594+ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
15595+ }
15596+
15597+#ifdef CONFIG_PAX_KERNEXEC
15598+ pax_close_kernel(cr0);
15599+#endif
15600+
15601+ return entry;
15602+ }
15603+ case 0x80: /* Not present */
15604+ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
15605+ return 0;
15606+ default: /* Shouldn't happen */
15607+ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
15608+ service, return_code);
15609+ return 0;
15610 }
15611 }
15612
15613 static struct {
15614 unsigned long address;
15615 unsigned short segment;
15616-} pci_indirect = { 0, __KERNEL_CS };
15617+} pci_indirect __read_only = { 0, __PCIBIOS_CS };
15618
15619-static int pci_bios_present;
15620+static int pci_bios_present __read_only;
15621
15622 static int __devinit check_pcibios(void)
15623 {
15624@@ -108,11 +178,13 @@ static int __devinit check_pcibios(void)
15625 unsigned long flags, pcibios_entry;
15626
15627 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
15628- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
15629+ pci_indirect.address = pcibios_entry;
15630
15631 local_irq_save(flags);
15632- __asm__(
15633- "lcall *(%%edi); cld\n\t"
15634+ __asm__("movw %w6, %%ds\n\t"
15635+ "lcall *%%ss:(%%edi); cld\n\t"
15636+ "push %%ss\n\t"
15637+ "pop %%ds\n\t"
15638 "jc 1f\n\t"
15639 "xor %%ah, %%ah\n"
15640 "1:"
15641@@ -121,7 +193,8 @@ static int __devinit check_pcibios(void)
15642 "=b" (ebx),
15643 "=c" (ecx)
15644 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
15645- "D" (&pci_indirect)
15646+ "D" (&pci_indirect),
15647+ "r" (__PCIBIOS_DS)
15648 : "memory");
15649 local_irq_restore(flags);
15650
15651@@ -165,7 +238,10 @@ static int pci_bios_read(unsigned int se
15652
15653 switch (len) {
15654 case 1:
15655- __asm__("lcall *(%%esi); cld\n\t"
15656+ __asm__("movw %w6, %%ds\n\t"
15657+ "lcall *%%ss:(%%esi); cld\n\t"
15658+ "push %%ss\n\t"
15659+ "pop %%ds\n\t"
15660 "jc 1f\n\t"
15661 "xor %%ah, %%ah\n"
15662 "1:"
15663@@ -174,7 +250,8 @@ static int pci_bios_read(unsigned int se
15664 : "1" (PCIBIOS_READ_CONFIG_BYTE),
15665 "b" (bx),
15666 "D" ((long)reg),
15667- "S" (&pci_indirect));
15668+ "S" (&pci_indirect),
15669+ "r" (__PCIBIOS_DS));
15670 /*
15671 * Zero-extend the result beyond 8 bits, do not trust the
15672 * BIOS having done it:
15673@@ -182,7 +259,10 @@ static int pci_bios_read(unsigned int se
15674 *value &= 0xff;
15675 break;
15676 case 2:
15677- __asm__("lcall *(%%esi); cld\n\t"
15678+ __asm__("movw %w6, %%ds\n\t"
15679+ "lcall *%%ss:(%%esi); cld\n\t"
15680+ "push %%ss\n\t"
15681+ "pop %%ds\n\t"
15682 "jc 1f\n\t"
15683 "xor %%ah, %%ah\n"
15684 "1:"
15685@@ -191,7 +271,8 @@ static int pci_bios_read(unsigned int se
15686 : "1" (PCIBIOS_READ_CONFIG_WORD),
15687 "b" (bx),
15688 "D" ((long)reg),
15689- "S" (&pci_indirect));
15690+ "S" (&pci_indirect),
15691+ "r" (__PCIBIOS_DS));
15692 /*
15693 * Zero-extend the result beyond 16 bits, do not trust the
15694 * BIOS having done it:
15695@@ -199,7 +280,10 @@ static int pci_bios_read(unsigned int se
15696 *value &= 0xffff;
15697 break;
15698 case 4:
15699- __asm__("lcall *(%%esi); cld\n\t"
15700+ __asm__("movw %w6, %%ds\n\t"
15701+ "lcall *%%ss:(%%esi); cld\n\t"
15702+ "push %%ss\n\t"
15703+ "pop %%ds\n\t"
15704 "jc 1f\n\t"
15705 "xor %%ah, %%ah\n"
15706 "1:"
15707@@ -208,7 +292,8 @@ static int pci_bios_read(unsigned int se
15708 : "1" (PCIBIOS_READ_CONFIG_DWORD),
15709 "b" (bx),
15710 "D" ((long)reg),
15711- "S" (&pci_indirect));
15712+ "S" (&pci_indirect),
15713+ "r" (__PCIBIOS_DS));
15714 break;
15715 }
15716
15717@@ -231,7 +316,10 @@ static int pci_bios_write(unsigned int s
15718
15719 switch (len) {
15720 case 1:
15721- __asm__("lcall *(%%esi); cld\n\t"
15722+ __asm__("movw %w6, %%ds\n\t"
15723+ "lcall *%%ss:(%%esi); cld\n\t"
15724+ "push %%ss\n\t"
15725+ "pop %%ds\n\t"
15726 "jc 1f\n\t"
15727 "xor %%ah, %%ah\n"
15728 "1:"
15729@@ -240,10 +328,14 @@ static int pci_bios_write(unsigned int s
15730 "c" (value),
15731 "b" (bx),
15732 "D" ((long)reg),
15733- "S" (&pci_indirect));
15734+ "S" (&pci_indirect),
15735+ "r" (__PCIBIOS_DS));
15736 break;
15737 case 2:
15738- __asm__("lcall *(%%esi); cld\n\t"
15739+ __asm__("movw %w6, %%ds\n\t"
15740+ "lcall *%%ss:(%%esi); cld\n\t"
15741+ "push %%ss\n\t"
15742+ "pop %%ds\n\t"
15743 "jc 1f\n\t"
15744 "xor %%ah, %%ah\n"
15745 "1:"
15746@@ -252,10 +344,14 @@ static int pci_bios_write(unsigned int s
15747 "c" (value),
15748 "b" (bx),
15749 "D" ((long)reg),
15750- "S" (&pci_indirect));
15751+ "S" (&pci_indirect),
15752+ "r" (__PCIBIOS_DS));
15753 break;
15754 case 4:
15755- __asm__("lcall *(%%esi); cld\n\t"
15756+ __asm__("movw %w6, %%ds\n\t"
15757+ "lcall *%%ss:(%%esi); cld\n\t"
15758+ "push %%ss\n\t"
15759+ "pop %%ds\n\t"
15760 "jc 1f\n\t"
15761 "xor %%ah, %%ah\n"
15762 "1:"
15763@@ -264,7 +360,8 @@ static int pci_bios_write(unsigned int s
15764 "c" (value),
15765 "b" (bx),
15766 "D" ((long)reg),
15767- "S" (&pci_indirect));
15768+ "S" (&pci_indirect),
15769+ "r" (__PCIBIOS_DS));
15770 break;
15771 }
15772
15773@@ -368,10 +465,13 @@ struct irq_routing_table * pcibios_get_i
15774
15775 DBG("PCI: Fetching IRQ routing table... ");
15776 __asm__("push %%es\n\t"
15777+ "movw %w8, %%ds\n\t"
15778 "push %%ds\n\t"
15779 "pop %%es\n\t"
15780- "lcall *(%%esi); cld\n\t"
15781+ "lcall *%%ss:(%%esi); cld\n\t"
15782 "pop %%es\n\t"
15783+ "push %%ss\n\t"
15784+ "pop %%ds\n"
15785 "jc 1f\n\t"
15786 "xor %%ah, %%ah\n"
15787 "1:"
15788@@ -382,7 +482,8 @@ struct irq_routing_table * pcibios_get_i
15789 "1" (0),
15790 "D" ((long) &opt),
15791 "S" (&pci_indirect),
15792- "m" (opt)
15793+ "m" (opt),
15794+ "r" (__PCIBIOS_DS)
15795 : "memory");
15796 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
15797 if (ret & 0xff00)
15798@@ -406,7 +507,10 @@ int pcibios_set_irq_routing(struct pci_d
15799 {
15800 int ret;
15801
15802- __asm__("lcall *(%%esi); cld\n\t"
15803+ __asm__("movw %w5, %%ds\n\t"
15804+ "lcall *%%ss:(%%esi); cld\n\t"
15805+ "push %%ss\n\t"
15806+ "pop %%ds\n"
15807 "jc 1f\n\t"
15808 "xor %%ah, %%ah\n"
15809 "1:"
15810@@ -414,7 +518,8 @@ int pcibios_set_irq_routing(struct pci_d
15811 : "0" (PCIBIOS_SET_PCI_HW_INT),
15812 "b" ((dev->bus->number << 8) | dev->devfn),
15813 "c" ((irq << 8) | (pin + 10)),
15814- "S" (&pci_indirect));
15815+ "S" (&pci_indirect),
15816+ "r" (__PCIBIOS_DS));
15817 return !(ret & 0xff00);
15818 }
15819 EXPORT_SYMBOL(pcibios_set_irq_routing);
017d2877
AM
15820diff -urNp linux-2.6.30.4/arch/x86/power/cpu_32.c linux-2.6.30.4/arch/x86/power/cpu_32.c
15821--- linux-2.6.30.4/arch/x86/power/cpu_32.c 2009-07-24 17:47:51.000000000 -0400
15822+++ linux-2.6.30.4/arch/x86/power/cpu_32.c 2009-07-30 09:48:09.976413155 -0400
15823@@ -68,7 +68,7 @@ static void do_fpu_end(void)
2380c486
JR
15824 static void fix_processor_context(void)
15825 {
15826 int cpu = smp_processor_id();
15827- struct tss_struct *t = &per_cpu(init_tss, cpu);
15828+ struct tss_struct *t = init_tss + cpu;
15829
15830 set_tss_desc(cpu, t); /*
15831 * This just modifies memory; should not be
017d2877
AM
15832diff -urNp linux-2.6.30.4/arch/x86/power/cpu_64.c linux-2.6.30.4/arch/x86/power/cpu_64.c
15833--- linux-2.6.30.4/arch/x86/power/cpu_64.c 2009-07-24 17:47:51.000000000 -0400
15834+++ linux-2.6.30.4/arch/x86/power/cpu_64.c 2009-07-30 09:48:09.978339754 -0400
15835@@ -144,7 +144,11 @@ void restore_processor_state(void)
2380c486
JR
15836 static void fix_processor_context(void)
15837 {
15838 int cpu = smp_processor_id();
15839- struct tss_struct *t = &per_cpu(init_tss, cpu);
15840+ struct tss_struct *t = init_tss + cpu;
15841+
15842+#ifdef CONFIG_PAX_KERNEXEC
15843+ unsigned long cr0;
15844+#endif
15845
15846 /*
15847 * This just modifies memory; should not be necessary. But... This
017d2877 15848@@ -153,8 +157,16 @@ static void fix_processor_context(void)
2380c486
JR
15849 */
15850 set_tss_desc(cpu, t);
15851
15852+#ifdef CONFIG_PAX_KERNEXEC
15853+ pax_open_kernel(cr0);
15854+#endif
15855+
15856 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
15857
15858+#ifdef CONFIG_PAX_KERNEXEC
15859+ pax_close_kernel(cr0);
15860+#endif
15861+
15862 syscall_init(); /* This sets MSR_*STAR and related */
15863 load_TR_desc(); /* This does ltr */
15864 load_LDT(&current->active_mm->context); /* This does lldt */
017d2877
AM
15865diff -urNp linux-2.6.30.4/arch/x86/vdso/Makefile linux-2.6.30.4/arch/x86/vdso/Makefile
15866--- linux-2.6.30.4/arch/x86/vdso/Makefile 2009-07-24 17:47:51.000000000 -0400
15867+++ linux-2.6.30.4/arch/x86/vdso/Makefile 2009-07-30 09:48:09.978339754 -0400
de855c5d
AM
15868@@ -122,7 +122,7 @@ quiet_cmd_vdso = VDSO $@
15869 $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
15870 -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^)
15871
15872-VDSO_LDFLAGS = -fPIC -shared $(call ld-option, -Wl$(comma)--hash-style=sysv)
15873+VDSO_LDFLAGS = -fPIC -shared --no-undefined $(call ld-option, -Wl$(comma)--hash-style=sysv)
15874
15875 #
15876 # Install the unstripped copy of vdso*.so listed in $(vdso-install-y).
017d2877
AM
15877diff -urNp linux-2.6.30.4/arch/x86/vdso/vclock_gettime.c linux-2.6.30.4/arch/x86/vdso/vclock_gettime.c
15878--- linux-2.6.30.4/arch/x86/vdso/vclock_gettime.c 2009-07-24 17:47:51.000000000 -0400
15879+++ linux-2.6.30.4/arch/x86/vdso/vclock_gettime.c 2009-07-30 09:48:09.978662746 -0400
de855c5d
AM
15880@@ -26,20 +26,43 @@
15881
15882 #define gtod vdso_vsyscall_gtod_data
15883
15884+notrace noinline long __vdso_fallback_time(long *t)
15885+{
15886+ long secs;
15887+ asm volatile("syscall"
15888+ : "=a" (secs)
15889+ : "0" (__NR_time),"D" (t) : "r11", "cx", "memory");
15890+ return secs;
15891+}
15892+
15893 notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
15894 {
15895 long ret;
15896 asm("syscall" : "=a" (ret) :
15897- "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "memory");
15898+ "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "r11", "cx", "memory");
15899 return ret;
15900 }
15901
15902+notrace static inline cycle_t __vdso_vread_hpet(void)
15903+{
15904+ return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0);
15905+}
15906+
15907+notrace static inline cycle_t __vdso_vread_tsc(void)
15908+{
15909+ cycle_t ret = (cycle_t)vget_cycles();
15910+
15911+ return ret >= gtod->clock.cycle_last ? ret : gtod->clock.cycle_last;
15912+}
15913+
15914 notrace static inline long vgetns(void)
15915 {
15916 long v;
15917- cycles_t (*vread)(void);
15918- vread = gtod->clock.vread;
15919- v = (vread() - gtod->clock.cycle_last) & gtod->clock.mask;
15920+ if (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3])
15921+ v = __vdso_vread_tsc();
15922+ else
15923+ v = __vdso_vread_hpet();
15924+ v = (v - gtod->clock.cycle_last) & gtod->clock.mask;
15925 return (v * gtod->clock.mult) >> gtod->clock.shift;
15926 }
15927
15928@@ -88,7 +111,9 @@ notrace static noinline int do_monotonic
15929
15930 notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
15931 {
15932- if (likely(gtod->sysctl_enabled && gtod->clock.vread))
15933+ if (likely(gtod->sysctl_enabled &&
15934+ ((gtod->clock.name[0] == 'h' && gtod->clock.name[1] == 'p' && gtod->clock.name[2] == 'e' && gtod->clock.name[3] == 't' && !gtod->clock.name[4]) ||
15935+ (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3]))))
15936 switch (clock) {
15937 case CLOCK_REALTIME:
15938 return do_realtime(ts);
15939@@ -100,10 +125,20 @@ notrace int __vdso_clock_gettime(clockid
15940 int clock_gettime(clockid_t, struct timespec *)
15941 __attribute__((weak, alias("__vdso_clock_gettime")));
15942
15943-notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
15944+notrace noinline int __vdso_fallback_gettimeofday(struct timeval *tv, struct timezone *tz)
15945 {
15946 long ret;
15947- if (likely(gtod->sysctl_enabled && gtod->clock.vread)) {
15948+ asm("syscall" : "=a" (ret) :
15949+ "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "r11", "cx", "memory");
15950+ return ret;
15951+}
15952+
15953+notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
15954+{
15955+ if (likely(gtod->sysctl_enabled &&
15956+ ((gtod->clock.name[0] == 'h' && gtod->clock.name[1] == 'p' && gtod->clock.name[2] == 'e' && gtod->clock.name[3] == 't' && !gtod->clock.name[4]) ||
15957+ (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3]))))
15958+ {
017d2877
AM
15959 if (likely(tv != NULL)) {
15960 BUILD_BUG_ON(offsetof(struct timeval, tv_usec) !=
15961 offsetof(struct timespec, tv_nsec) ||
15962@@ -118,9 +153,7 @@ notrace int __vdso_gettimeofday(struct t
de855c5d
AM
15963 }
15964 return 0;
15965 }
15966- asm("syscall" : "=a" (ret) :
15967- "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory");
15968- return ret;
15969+ return __vdso_fallback_gettimeofday(tv, tz);
15970 }
15971 int gettimeofday(struct timeval *, struct timezone *)
15972 __attribute__((weak, alias("__vdso_gettimeofday")));
017d2877
AM
15973diff -urNp linux-2.6.30.4/arch/x86/vdso/vdso32-setup.c linux-2.6.30.4/arch/x86/vdso/vdso32-setup.c
15974--- linux-2.6.30.4/arch/x86/vdso/vdso32-setup.c 2009-07-24 17:47:51.000000000 -0400
15975+++ linux-2.6.30.4/arch/x86/vdso/vdso32-setup.c 2009-07-30 09:48:09.979439324 -0400
2380c486
JR
15976@@ -226,7 +226,7 @@ static inline void map_compat_vdso(int m
15977 void enable_sep_cpu(void)
15978 {
15979 int cpu = get_cpu();
15980- struct tss_struct *tss = &per_cpu(init_tss, cpu);
15981+ struct tss_struct *tss = init_tss + cpu;
15982
15983 if (!boot_cpu_has(X86_FEATURE_SEP)) {
15984 put_cpu();
15985@@ -249,7 +249,7 @@ static int __init gate_vma_init(void)
15986 gate_vma.vm_start = FIXADDR_USER_START;
15987 gate_vma.vm_end = FIXADDR_USER_END;
15988 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
15989- gate_vma.vm_page_prot = __P101;
15990+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
15991 /*
15992 * Make sure the vDSO gets into every core dump.
15993 * Dumping its contents makes post-mortem fully interpretable later
15994@@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct l
15995 if (compat)
15996 addr = VDSO_HIGH_BASE;
15997 else {
15998- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
15999+ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
16000 if (IS_ERR_VALUE(addr)) {
16001 ret = addr;
16002 goto up_fail;
16003@@ -358,7 +358,7 @@ int arch_setup_additional_pages(struct l
16004 goto up_fail;
16005 }
16006
16007- current->mm->context.vdso = (void *)addr;
16008+ current->mm->context.vdso = addr;
16009 current_thread_info()->sysenter_return =
16010 VDSO32_SYMBOL(addr, SYSENTER_RETURN);
16011
16012@@ -384,7 +384,7 @@ static ctl_table abi_table2[] = {
16013 .mode = 0644,
16014 .proc_handler = proc_dointvec
16015 },
16016- {}
16017+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
16018 };
16019
16020 static ctl_table abi_root_table2[] = {
16021@@ -394,7 +394,7 @@ static ctl_table abi_root_table2[] = {
16022 .mode = 0555,
16023 .child = abi_table2
16024 },
16025- {}
16026+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
16027 };
16028
16029 static __init int ia32_binfmt_init(void)
16030@@ -409,8 +409,14 @@ __initcall(ia32_binfmt_init);
16031
16032 const char *arch_vma_name(struct vm_area_struct *vma)
16033 {
16034- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
16035+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
16036 return "[vdso]";
16037+
16038+#ifdef CONFIG_PAX_SEGMEXEC
16039+ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
16040+ return "[vdso]";
16041+#endif
16042+
16043 return NULL;
16044 }
16045
16046@@ -419,7 +425,7 @@ struct vm_area_struct *get_gate_vma(stru
16047 struct mm_struct *mm = tsk->mm;
16048
16049 /* Check to see if this task was created in compat vdso mode */
16050- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
16051+ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
16052 return &gate_vma;
16053 return NULL;
16054 }
017d2877
AM
16055diff -urNp linux-2.6.30.4/arch/x86/vdso/vdso.lds.S linux-2.6.30.4/arch/x86/vdso/vdso.lds.S
16056--- linux-2.6.30.4/arch/x86/vdso/vdso.lds.S 2009-07-24 17:47:51.000000000 -0400
16057+++ linux-2.6.30.4/arch/x86/vdso/vdso.lds.S 2009-07-30 09:48:09.978662746 -0400
de855c5d
AM
16058@@ -35,3 +35,9 @@ VDSO64_PRELINK = VDSO_PRELINK;
16059 #define VEXTERN(x) VDSO64_ ## x = vdso_ ## x;
16060 #include "vextern.h"
16061 #undef VEXTERN
16062+
16063+#define VEXTERN(x) VDSO64_ ## x = __vdso_ ## x;
16064+VEXTERN(fallback_gettimeofday)
16065+VEXTERN(fallback_time)
16066+VEXTERN(getcpu)
16067+#undef VEXTERN
017d2877
AM
16068diff -urNp linux-2.6.30.4/arch/x86/vdso/vextern.h linux-2.6.30.4/arch/x86/vdso/vextern.h
16069--- linux-2.6.30.4/arch/x86/vdso/vextern.h 2009-07-24 17:47:51.000000000 -0400
16070+++ linux-2.6.30.4/arch/x86/vdso/vextern.h 2009-07-30 09:48:09.979439324 -0400
de855c5d
AM
16071@@ -11,6 +11,5 @@
16072 put into vextern.h and be referenced as a pointer with vdso prefix.
16073 The main kernel later fills in the values. */
16074
16075-VEXTERN(jiffies)
16076 VEXTERN(vgetcpu_mode)
16077 VEXTERN(vsyscall_gtod_data)
017d2877
AM
16078diff -urNp linux-2.6.30.4/arch/x86/vdso/vma.c linux-2.6.30.4/arch/x86/vdso/vma.c
16079--- linux-2.6.30.4/arch/x86/vdso/vma.c 2009-07-24 17:47:51.000000000 -0400
16080+++ linux-2.6.30.4/arch/x86/vdso/vma.c 2009-07-30 09:48:09.979439324 -0400
de855c5d
AM
16081@@ -8,6 +8,7 @@
16082 #include <linux/sched.h>
16083 #include <linux/init.h>
16084 #include <linux/random.h>
16085+#include <linux/elf.h>
16086 #include <asm/vsyscall.h>
16087 #include <asm/vgtod.h>
16088 #include <asm/proto.h>
16089@@ -56,7 +57,7 @@ static int __init init_vdso_vars(void)
16090 if (!vbase)
16091 goto oom;
16092
16093- if (memcmp(vbase, "\177ELF", 4)) {
16094+ if (memcmp(vbase, ELFMAG, SELFMAG)) {
16095 printk("VDSO: I'm broken; not ELF\n");
16096 vdso_enabled = 0;
16097 }
16098@@ -65,6 +66,7 @@ static int __init init_vdso_vars(void)
16099 *(typeof(__ ## x) **) var_ref(VDSO64_SYMBOL(vbase, x), #x) = &__ ## x;
16100 #include "vextern.h"
16101 #undef VEXTERN
16102+ vunmap(vbase);
16103 return 0;
16104
16105 oom:
017d2877 16106@@ -123,15 +125,8 @@ int arch_setup_additional_pages(struct l
2380c486
JR
16107 if (ret)
16108 goto up_fail;
16109
16110- current->mm->context.vdso = (void *)addr;
16111+ current->mm->context.vdso = addr;
16112 up_fail:
16113 up_write(&mm->mmap_sem);
16114 return ret;
017d2877
AM
16115 }
16116-
16117-static __init int vdso_setup(char *s)
16118-{
16119- vdso_enabled = simple_strtoul(s, NULL, 0);
16120- return 0;
16121-}
16122-__setup("vdso=", vdso_setup);
16123diff -urNp linux-2.6.30.4/arch/x86/xen/debugfs.c linux-2.6.30.4/arch/x86/xen/debugfs.c
16124--- linux-2.6.30.4/arch/x86/xen/debugfs.c 2009-07-24 17:47:51.000000000 -0400
16125+++ linux-2.6.30.4/arch/x86/xen/debugfs.c 2009-07-30 09:48:09.979439324 -0400
16126@@ -100,7 +100,7 @@ static int xen_array_release(struct inod
16127 return 0;
16128 }
16129
16130-static struct file_operations u32_array_fops = {
16131+static const struct file_operations u32_array_fops = {
16132 .owner = THIS_MODULE,
16133 .open = u32_array_open,
16134 .release= xen_array_release,
16135diff -urNp linux-2.6.30.4/arch/x86/xen/enlighten.c linux-2.6.30.4/arch/x86/xen/enlighten.c
16136--- linux-2.6.30.4/arch/x86/xen/enlighten.c 2009-07-24 17:47:51.000000000 -0400
16137+++ linux-2.6.30.4/arch/x86/xen/enlighten.c 2009-07-30 09:48:09.980662517 -0400
16138@@ -454,7 +454,7 @@ static void xen_write_idt_entry(gate_des
2380c486
JR
16139
16140 preempt_disable();
16141
16142- start = __get_cpu_var(idt_desc).address;
16143+ start = (unsigned long)__get_cpu_var(idt_desc).address;
16144 end = start + __get_cpu_var(idt_desc).size + 1;
16145
16146 xen_mc_flush();
017d2877
AM
16147diff -urNp linux-2.6.30.4/arch/x86/xen/mmu.c linux-2.6.30.4/arch/x86/xen/mmu.c
16148--- linux-2.6.30.4/arch/x86/xen/mmu.c 2009-07-24 17:47:51.000000000 -0400
16149+++ linux-2.6.30.4/arch/x86/xen/mmu.c 2009-07-30 09:48:09.980662517 -0400
16150@@ -1716,6 +1716,8 @@ __init pgd_t *xen_setup_kernel_pagetable
2380c486
JR
16151 convert_pfn_mfn(init_level4_pgt);
16152 convert_pfn_mfn(level3_ident_pgt);
16153 convert_pfn_mfn(level3_kernel_pgt);
16154+ convert_pfn_mfn(level3_vmalloc_pgt);
16155+ convert_pfn_mfn(level3_vmemmap_pgt);
16156
16157 l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
16158 l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
017d2877 16159@@ -1734,9 +1736,12 @@ __init pgd_t *xen_setup_kernel_pagetable
2380c486
JR
16160 set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
16161 set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
16162 set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
16163+ set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
16164+ set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
16165 set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
16166 set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
16167 set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
16168+ set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
16169
16170 /* Pin down new L4 */
16171 pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
017d2877
AM
16172diff -urNp linux-2.6.30.4/arch/x86/xen/smp.c linux-2.6.30.4/arch/x86/xen/smp.c
16173--- linux-2.6.30.4/arch/x86/xen/smp.c 2009-07-24 17:47:51.000000000 -0400
16174+++ linux-2.6.30.4/arch/x86/xen/smp.c 2009-07-30 09:48:09.981489035 -0400
16175@@ -167,11 +167,6 @@ static void __init xen_smp_prepare_boot_
2380c486
JR
16176 {
16177 BUG_ON(smp_processor_id() != 0);
16178 native_smp_prepare_boot_cpu();
16179-
16180- /* We've switched to the "real" per-cpu gdt, so make sure the
16181- old memory can be recycled */
017d2877 16182- make_lowmem_page_readwrite(xen_initial_gdt);
2380c486
JR
16183-
16184 xen_setup_vcpu_info_placement();
16185 }
16186
017d2877 16187@@ -231,8 +226,8 @@ cpu_initialize_context(unsigned int cpu,
2380c486
JR
16188 gdt = get_cpu_gdt_table(cpu);
16189
16190 ctxt->flags = VGCF_IN_KERNEL;
16191- ctxt->user_regs.ds = __USER_DS;
16192- ctxt->user_regs.es = __USER_DS;
16193+ ctxt->user_regs.ds = __KERNEL_DS;
16194+ ctxt->user_regs.es = __KERNEL_DS;
16195 ctxt->user_regs.ss = __KERNEL_DS;
16196 #ifdef CONFIG_X86_32
16197 ctxt->user_regs.fs = __KERNEL_PERCPU;
017d2877
AM
16198diff -urNp linux-2.6.30.4/arch/xtensa/include/asm/atomic.h linux-2.6.30.4/arch/xtensa/include/asm/atomic.h
16199--- linux-2.6.30.4/arch/xtensa/include/asm/atomic.h 2009-07-24 17:47:51.000000000 -0400
16200+++ linux-2.6.30.4/arch/xtensa/include/asm/atomic.h 2009-07-30 09:48:09.981489035 -0400
de855c5d
AM
16201@@ -165,6 +165,9 @@ static inline int atomic_sub_return(int
16202 * Atomically increments @v by 1.
16203 */
16204 #define atomic_inc(v) atomic_add(1,(v))
16205+#define atomic_inc_unchecked(v) atomic_inc(v)
16206+#define atomic_add_unchecked(i, v) atomic_add((i), (v))
16207+#define atomic_sub_unchecked(i, v) atomic_sub((i), (v))
16208
16209 /**
16210 * atomic_inc - increment atomic variable
017d2877
AM
16211diff -urNp linux-2.6.30.4/arch/xtensa/include/asm/kmap_types.h linux-2.6.30.4/arch/xtensa/include/asm/kmap_types.h
16212--- linux-2.6.30.4/arch/xtensa/include/asm/kmap_types.h 2009-07-24 17:47:51.000000000 -0400
16213+++ linux-2.6.30.4/arch/xtensa/include/asm/kmap_types.h 2009-07-30 09:48:09.981489035 -0400
2380c486
JR
16214@@ -25,6 +25,7 @@ enum km_type {
16215 KM_IRQ1,
16216 KM_SOFTIRQ0,
16217 KM_SOFTIRQ1,
16218+ KM_CLEARPAGE,
16219 KM_TYPE_NR
16220 };
16221
017d2877
AM
16222diff -urNp linux-2.6.30.4/crypto/lrw.c linux-2.6.30.4/crypto/lrw.c
16223--- linux-2.6.30.4/crypto/lrw.c 2009-07-24 17:47:51.000000000 -0400
16224+++ linux-2.6.30.4/crypto/lrw.c 2009-07-30 09:48:09.982442014 -0400
2380c486
JR
16225@@ -60,7 +60,7 @@ static int setkey(struct crypto_tfm *par
16226 struct priv *ctx = crypto_tfm_ctx(parent);
16227 struct crypto_cipher *child = ctx->child;
16228 int err, i;
16229- be128 tmp = { 0 };
16230+ be128 tmp = { 0, 0 };
16231 int bsize = crypto_cipher_blocksize(child);
16232
16233 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
017d2877
AM
16234diff -urNp linux-2.6.30.4/Documentation/dontdiff linux-2.6.30.4/Documentation/dontdiff
16235--- linux-2.6.30.4/Documentation/dontdiff 2009-07-24 17:47:51.000000000 -0400
16236+++ linux-2.6.30.4/Documentation/dontdiff 2009-07-30 09:48:09.870977266 -0400
2380c486
JR
16237@@ -3,6 +3,7 @@
16238 *.bin
16239 *.cpio
16240 *.csp
16241+*.dbg
16242 *.dsp
16243 *.dvi
16244 *.elf
16245@@ -49,6 +50,10 @@
16246 53c700_d.h
16247 CVS
16248 ChangeSet
16249+GPATH
16250+GRTAGS
16251+GSYMS
16252+GTAGS
16253 Image
16254 Kerntypes
16255 Module.markers
017d2877 16256@@ -76,6 +81,7 @@ btfixupprep
2380c486
JR
16257 build
16258 bvmlinux
16259 bzImage*
16260+capflags.c
16261 classlist.h*
16262 comp*.log
16263 compile.h*
017d2877 16264@@ -103,6 +109,7 @@ gen_crc32table
de855c5d
AM
16265 gen_init_cpio
16266 genksyms
16267 *_gray256.c
16268+hash
16269 ihex2fw
16270 ikconfig.h*
16271 initramfs_data.cpio
017d2877 16272@@ -164,6 +171,7 @@ setup
de855c5d
AM
16273 setup.bin
16274 setup.elf
16275 sImage
16276+slabinfo
16277 sm_tbl*
16278 split-include
16279 syscalltab.h
017d2877 16280@@ -187,12 +195,15 @@ version.h*
2380c486
JR
16281 vmlinux
16282 vmlinux-*
16283 vmlinux.aout
16284+vmlinux.bin.all
16285 vmlinux.lds
16286+vmlinux.relocs
16287 vsyscall.lds
16288 vsyscall_32.lds
16289 wanxlfw.inc
16290 uImage
16291 unifdef
16292+utsrelease.h
16293 wakeup.bin
16294 wakeup.elf
16295 wakeup.lds
017d2877
AM
16296diff -urNp linux-2.6.30.4/drivers/acpi/blacklist.c linux-2.6.30.4/drivers/acpi/blacklist.c
16297--- linux-2.6.30.4/drivers/acpi/blacklist.c 2009-07-24 17:47:51.000000000 -0400
16298+++ linux-2.6.30.4/drivers/acpi/blacklist.c 2009-07-30 09:48:09.982442014 -0400
2380c486
JR
16299@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
16300 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
16301 "Incorrect _ADR", 1},
16302
16303- {""}
16304+ {"", "", 0, 0, 0, all_versions, 0}
16305 };
16306
16307 #if CONFIG_ACPI_BLACKLIST_YEAR
017d2877
AM
16308diff -urNp linux-2.6.30.4/drivers/acpi/osl.c linux-2.6.30.4/drivers/acpi/osl.c
16309--- linux-2.6.30.4/drivers/acpi/osl.c 2009-07-24 17:47:51.000000000 -0400
16310+++ linux-2.6.30.4/drivers/acpi/osl.c 2009-07-30 09:48:09.986535027 -0400
16311@@ -492,6 +492,8 @@ acpi_os_read_memory(acpi_physical_addres
2380c486
JR
16312 void __iomem *virt_addr;
16313
16314 virt_addr = ioremap(phys_addr, width);
16315+ if (!virt_addr)
16316+ return AE_NO_MEMORY;
16317 if (!value)
16318 value = &dummy;
16319
017d2877 16320@@ -520,6 +522,8 @@ acpi_os_write_memory(acpi_physical_addre
2380c486
JR
16321 void __iomem *virt_addr;
16322
16323 virt_addr = ioremap(phys_addr, width);
16324+ if (!virt_addr)
16325+ return AE_NO_MEMORY;
16326
16327 switch (width) {
16328 case 8:
017d2877
AM
16329diff -urNp linux-2.6.30.4/drivers/acpi/processor_core.c linux-2.6.30.4/drivers/acpi/processor_core.c
16330--- linux-2.6.30.4/drivers/acpi/processor_core.c 2009-07-24 17:47:51.000000000 -0400
16331+++ linux-2.6.30.4/drivers/acpi/processor_core.c 2009-07-30 09:48:09.986535027 -0400
16332@@ -703,7 +703,7 @@ static int __cpuinit acpi_processor_star
2380c486
JR
16333 return 0;
16334 }
16335
16336- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
16337+ BUG_ON(pr->id >= nr_cpu_ids);
16338
16339 /*
16340 * Buggy BIOS check
017d2877
AM
16341diff -urNp linux-2.6.30.4/drivers/acpi/processor_idle.c linux-2.6.30.4/drivers/acpi/processor_idle.c
16342--- linux-2.6.30.4/drivers/acpi/processor_idle.c 2009-07-24 17:47:51.000000000 -0400
16343+++ linux-2.6.30.4/drivers/acpi/processor_idle.c 2009-07-30 09:48:09.987663767 -0400
16344@@ -108,7 +108,7 @@ static struct dmi_system_id __cpuinitdat
2380c486
JR
16345 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
16346 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
16347 (void *)2},
16348- {},
16349+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL},
16350 };
16351
017d2877
AM
16352
16353diff -urNp linux-2.6.30.4/drivers/acpi/video.c linux-2.6.30.4/drivers/acpi/video.c
16354--- linux-2.6.30.4/drivers/acpi/video.c 2009-07-24 17:47:51.000000000 -0400
16355+++ linux-2.6.30.4/drivers/acpi/video.c 2009-07-30 12:06:52.099841502 -0400
16356@@ -282,7 +282,7 @@ static int acpi_video_device_brightness_
16357 struct file *file);
16358 static ssize_t acpi_video_device_write_brightness(struct file *file,
16359 const char __user *buffer, size_t count, loff_t *data);
16360-static struct file_operations acpi_video_device_brightness_fops = {
16361+static const struct file_operations acpi_video_device_brightness_fops = {
16362 .owner = THIS_MODULE,
16363 .open = acpi_video_device_brightness_open_fs,
16364 .read = seq_read,
16365diff -urNp linux-2.6.30.4/drivers/ata/ahci.c linux-2.6.30.4/drivers/ata/ahci.c
16366--- linux-2.6.30.4/drivers/ata/ahci.c 2009-07-24 17:47:51.000000000 -0400
16367+++ linux-2.6.30.4/drivers/ata/ahci.c 2009-07-30 09:48:09.987663767 -0400
16368@@ -622,7 +622,7 @@ static const struct pci_device_id ahci_p
2380c486
JR
16369 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
16370 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
16371
16372- { } /* terminate list */
16373+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
16374 };
16375
16376
017d2877
AM
16377diff -urNp linux-2.6.30.4/drivers/ata/ata_piix.c linux-2.6.30.4/drivers/ata/ata_piix.c
16378--- linux-2.6.30.4/drivers/ata/ata_piix.c 2009-07-24 17:47:51.000000000 -0400
16379+++ linux-2.6.30.4/drivers/ata/ata_piix.c 2009-07-30 09:48:09.988577262 -0400
16380@@ -293,7 +293,7 @@ static const struct pci_device_id piix_p
2380c486
JR
16381 { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
16382 /* SATA Controller IDE (PCH) */
16383 { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
16384- { } /* terminate list */
16385+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
16386 };
16387
16388 static struct pci_driver piix_pci_driver = {
017d2877 16389@@ -607,7 +607,7 @@ static const struct ich_laptop ich_lapto
2380c486 16390 { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
017d2877 16391 { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */
2380c486
JR
16392 /* end marker */
16393- { 0, }
16394+ { 0, 0, 0 }
16395 };
16396
16397 /**
017d2877 16398@@ -1073,7 +1073,7 @@ static int piix_broken_suspend(void)
2380c486
JR
16399 },
16400 },
16401
16402- { } /* terminate list */
16403+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } /* terminate list */
16404 };
16405 static const char *oemstrs[] = {
16406 "Tecra M3,",
017d2877
AM
16407diff -urNp linux-2.6.30.4/drivers/ata/libata-core.c linux-2.6.30.4/drivers/ata/libata-core.c
16408--- linux-2.6.30.4/drivers/ata/libata-core.c 2009-07-24 17:47:51.000000000 -0400
16409+++ linux-2.6.30.4/drivers/ata/libata-core.c 2009-07-30 09:48:09.989999430 -0400
16410@@ -890,7 +890,7 @@ static const struct ata_xfer_ent {
2380c486
JR
16411 { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
16412 { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
16413 { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
16414- { -1, },
16415+ { -1, 0, 0 }
16416 };
16417
16418 /**
017d2877 16419@@ -3129,7 +3129,7 @@ static const struct ata_timing ata_timin
2380c486
JR
16420 { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 },
16421 { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 },
16422
16423- { 0xFF }
16424+ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
16425 };
16426
16427 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
017d2877 16428@@ -4293,7 +4293,7 @@ static const struct ata_blacklist_entry
2380c486
JR
16429 { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, },
16430
16431 /* End Marker */
16432- { }
16433+ { NULL, NULL, 0 }
16434 };
16435
16436 static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
017d2877
AM
16437diff -urNp linux-2.6.30.4/drivers/atm/adummy.c linux-2.6.30.4/drivers/atm/adummy.c
16438--- linux-2.6.30.4/drivers/atm/adummy.c 2009-07-24 17:47:51.000000000 -0400
16439+++ linux-2.6.30.4/drivers/atm/adummy.c 2009-07-30 09:48:09.989999430 -0400
de855c5d
AM
16440@@ -77,7 +77,7 @@ adummy_send(struct atm_vcc *vcc, struct
16441 vcc->pop(vcc, skb);
16442 else
16443 dev_kfree_skb_any(skb);
16444- atomic_inc(&vcc->stats->tx);
16445+ atomic_inc_unchecked(&vcc->stats->tx);
16446
16447 return 0;
16448 }
017d2877
AM
16449diff -urNp linux-2.6.30.4/drivers/atm/ambassador.c linux-2.6.30.4/drivers/atm/ambassador.c
16450--- linux-2.6.30.4/drivers/atm/ambassador.c 2009-07-24 17:47:51.000000000 -0400
16451+++ linux-2.6.30.4/drivers/atm/ambassador.c 2009-07-30 09:48:09.990535817 -0400
de855c5d
AM
16452@@ -453,7 +453,7 @@ static void tx_complete (amb_dev * dev,
16453 PRINTD (DBG_FLOW|DBG_TX, "tx_complete %p %p", dev, tx);
16454
16455 // VC layer stats
16456- atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
16457+ atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
16458
16459 // free the descriptor
16460 kfree (tx_descr);
16461@@ -494,7 +494,7 @@ static void rx_complete (amb_dev * dev,
16462 dump_skb ("<<<", vc, skb);
16463
16464 // VC layer stats
16465- atomic_inc(&atm_vcc->stats->rx);
16466+ atomic_inc_unchecked(&atm_vcc->stats->rx);
16467 __net_timestamp(skb);
16468 // end of our responsability
16469 atm_vcc->push (atm_vcc, skb);
16470@@ -509,7 +509,7 @@ static void rx_complete (amb_dev * dev,
16471 } else {
16472 PRINTK (KERN_INFO, "dropped over-size frame");
16473 // should we count this?
16474- atomic_inc(&atm_vcc->stats->rx_drop);
16475+ atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
16476 }
16477
16478 } else {
16479@@ -1349,7 +1349,7 @@ static int amb_send (struct atm_vcc * at
16480 }
16481
16482 if (check_area (skb->data, skb->len)) {
16483- atomic_inc(&atm_vcc->stats->tx_err);
16484+ atomic_inc_unchecked(&atm_vcc->stats->tx_err);
16485 return -ENOMEM; // ?
16486 }
16487
017d2877
AM
16488diff -urNp linux-2.6.30.4/drivers/atm/atmtcp.c linux-2.6.30.4/drivers/atm/atmtcp.c
16489--- linux-2.6.30.4/drivers/atm/atmtcp.c 2009-07-24 17:47:51.000000000 -0400
16490+++ linux-2.6.30.4/drivers/atm/atmtcp.c 2009-07-30 09:48:09.991629377 -0400
de855c5d
AM
16491@@ -206,7 +206,7 @@ static int atmtcp_v_send(struct atm_vcc
16492 if (vcc->pop) vcc->pop(vcc,skb);
16493 else dev_kfree_skb(skb);
16494 if (dev_data) return 0;
16495- atomic_inc(&vcc->stats->tx_err);
16496+ atomic_inc_unchecked(&vcc->stats->tx_err);
16497 return -ENOLINK;
16498 }
16499 size = skb->len+sizeof(struct atmtcp_hdr);
16500@@ -214,7 +214,7 @@ static int atmtcp_v_send(struct atm_vcc
16501 if (!new_skb) {
16502 if (vcc->pop) vcc->pop(vcc,skb);
16503 else dev_kfree_skb(skb);
16504- atomic_inc(&vcc->stats->tx_err);
16505+ atomic_inc_unchecked(&vcc->stats->tx_err);
16506 return -ENOBUFS;
16507 }
16508 hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr));
16509@@ -225,8 +225,8 @@ static int atmtcp_v_send(struct atm_vcc
16510 if (vcc->pop) vcc->pop(vcc,skb);
16511 else dev_kfree_skb(skb);
16512 out_vcc->push(out_vcc,new_skb);
16513- atomic_inc(&vcc->stats->tx);
16514- atomic_inc(&out_vcc->stats->rx);
16515+ atomic_inc_unchecked(&vcc->stats->tx);
16516+ atomic_inc_unchecked(&out_vcc->stats->rx);
16517 return 0;
16518 }
16519
16520@@ -300,7 +300,7 @@ static int atmtcp_c_send(struct atm_vcc
16521 out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci));
16522 read_unlock(&vcc_sklist_lock);
16523 if (!out_vcc) {
16524- atomic_inc(&vcc->stats->tx_err);
16525+ atomic_inc_unchecked(&vcc->stats->tx_err);
16526 goto done;
16527 }
16528 skb_pull(skb,sizeof(struct atmtcp_hdr));
16529@@ -312,8 +312,8 @@ static int atmtcp_c_send(struct atm_vcc
16530 __net_timestamp(new_skb);
16531 skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
16532 out_vcc->push(out_vcc,new_skb);
16533- atomic_inc(&vcc->stats->tx);
16534- atomic_inc(&out_vcc->stats->rx);
16535+ atomic_inc_unchecked(&vcc->stats->tx);
16536+ atomic_inc_unchecked(&out_vcc->stats->rx);
16537 done:
16538 if (vcc->pop) vcc->pop(vcc,skb);
16539 else dev_kfree_skb(skb);
017d2877
AM
16540diff -urNp linux-2.6.30.4/drivers/atm/eni.c linux-2.6.30.4/drivers/atm/eni.c
16541--- linux-2.6.30.4/drivers/atm/eni.c 2009-07-24 17:47:51.000000000 -0400
16542+++ linux-2.6.30.4/drivers/atm/eni.c 2009-07-30 09:48:09.991629377 -0400
de855c5d
AM
16543@@ -525,7 +525,7 @@ static int rx_aal0(struct atm_vcc *vcc)
16544 DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
16545 vcc->dev->number);
16546 length = 0;
16547- atomic_inc(&vcc->stats->rx_err);
16548+ atomic_inc_unchecked(&vcc->stats->rx_err);
16549 }
16550 else {
16551 length = ATM_CELL_SIZE-1; /* no HEC */
16552@@ -580,7 +580,7 @@ static int rx_aal5(struct atm_vcc *vcc)
16553 size);
16554 }
16555 eff = length = 0;
16556- atomic_inc(&vcc->stats->rx_err);
16557+ atomic_inc_unchecked(&vcc->stats->rx_err);
16558 }
16559 else {
16560 size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
16561@@ -597,7 +597,7 @@ static int rx_aal5(struct atm_vcc *vcc)
16562 "(VCI=%d,length=%ld,size=%ld (descr 0x%lx))\n",
16563 vcc->dev->number,vcc->vci,length,size << 2,descr);
16564 length = eff = 0;
16565- atomic_inc(&vcc->stats->rx_err);
16566+ atomic_inc_unchecked(&vcc->stats->rx_err);
16567 }
16568 }
16569 skb = eff ? atm_alloc_charge(vcc,eff << 2,GFP_ATOMIC) : NULL;
16570@@ -770,7 +770,7 @@ rx_dequeued++;
16571 vcc->push(vcc,skb);
16572 pushed++;
16573 }
16574- atomic_inc(&vcc->stats->rx);
16575+ atomic_inc_unchecked(&vcc->stats->rx);
16576 }
16577 wake_up(&eni_dev->rx_wait);
16578 }
16579@@ -1227,7 +1227,7 @@ static void dequeue_tx(struct atm_dev *d
16580 PCI_DMA_TODEVICE);
16581 if (vcc->pop) vcc->pop(vcc,skb);
16582 else dev_kfree_skb_irq(skb);
16583- atomic_inc(&vcc->stats->tx);
16584+ atomic_inc_unchecked(&vcc->stats->tx);
16585 wake_up(&eni_dev->tx_wait);
16586 dma_complete++;
16587 }
017d2877
AM
16588diff -urNp linux-2.6.30.4/drivers/atm/firestream.c linux-2.6.30.4/drivers/atm/firestream.c
16589--- linux-2.6.30.4/drivers/atm/firestream.c 2009-07-24 17:47:51.000000000 -0400
16590+++ linux-2.6.30.4/drivers/atm/firestream.c 2009-07-30 09:48:09.992530374 -0400
de855c5d
AM
16591@@ -748,7 +748,7 @@ static void process_txdone_queue (struct
16592 }
16593 }
16594
16595- atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
16596+ atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
16597
16598 fs_dprintk (FS_DEBUG_TXMEM, "i");
16599 fs_dprintk (FS_DEBUG_ALLOC, "Free t-skb: %p\n", skb);
16600@@ -815,7 +815,7 @@ static void process_incoming (struct fs_
16601 #endif
16602 skb_put (skb, qe->p1 & 0xffff);
16603 ATM_SKB(skb)->vcc = atm_vcc;
16604- atomic_inc(&atm_vcc->stats->rx);
16605+ atomic_inc_unchecked(&atm_vcc->stats->rx);
16606 __net_timestamp(skb);
16607 fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb);
16608 atm_vcc->push (atm_vcc, skb);
16609@@ -836,12 +836,12 @@ static void process_incoming (struct fs_
16610 kfree (pe);
16611 }
16612 if (atm_vcc)
16613- atomic_inc(&atm_vcc->stats->rx_drop);
16614+ atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
16615 break;
16616 case 0x1f: /* Reassembly abort: no buffers. */
16617 /* Silently increment error counter. */
16618 if (atm_vcc)
16619- atomic_inc(&atm_vcc->stats->rx_drop);
16620+ atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
16621 break;
16622 default: /* Hmm. Haven't written the code to handle the others yet... -- REW */
16623 printk (KERN_WARNING "Don't know what to do with RX status %x: %s.\n",
017d2877
AM
16624diff -urNp linux-2.6.30.4/drivers/atm/fore200e.c linux-2.6.30.4/drivers/atm/fore200e.c
16625--- linux-2.6.30.4/drivers/atm/fore200e.c 2009-07-24 17:47:51.000000000 -0400
16626+++ linux-2.6.30.4/drivers/atm/fore200e.c 2009-07-30 09:48:09.993922247 -0400
de855c5d
AM
16627@@ -931,9 +931,9 @@ fore200e_tx_irq(struct fore200e* fore200
16628 #endif
16629 /* check error condition */
16630 if (*entry->status & STATUS_ERROR)
16631- atomic_inc(&vcc->stats->tx_err);
16632+ atomic_inc_unchecked(&vcc->stats->tx_err);
16633 else
16634- atomic_inc(&vcc->stats->tx);
16635+ atomic_inc_unchecked(&vcc->stats->tx);
16636 }
16637 }
16638
16639@@ -1082,7 +1082,7 @@ fore200e_push_rpd(struct fore200e* fore2
16640 if (skb == NULL) {
16641 DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
16642
16643- atomic_inc(&vcc->stats->rx_drop);
16644+ atomic_inc_unchecked(&vcc->stats->rx_drop);
16645 return -ENOMEM;
16646 }
16647
16648@@ -1125,14 +1125,14 @@ fore200e_push_rpd(struct fore200e* fore2
16649
16650 dev_kfree_skb_any(skb);
16651
16652- atomic_inc(&vcc->stats->rx_drop);
16653+ atomic_inc_unchecked(&vcc->stats->rx_drop);
16654 return -ENOMEM;
16655 }
16656
16657 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
16658
16659 vcc->push(vcc, skb);
16660- atomic_inc(&vcc->stats->rx);
16661+ atomic_inc_unchecked(&vcc->stats->rx);
16662
16663 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
16664
16665@@ -1210,7 +1210,7 @@ fore200e_rx_irq(struct fore200e* fore200
16666 DPRINTK(2, "damaged PDU on %d.%d.%d\n",
16667 fore200e->atm_dev->number,
16668 entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
16669- atomic_inc(&vcc->stats->rx_err);
16670+ atomic_inc_unchecked(&vcc->stats->rx_err);
16671 }
16672 }
16673
16674@@ -1655,7 +1655,7 @@ fore200e_send(struct atm_vcc *vcc, struc
16675 goto retry_here;
16676 }
16677
16678- atomic_inc(&vcc->stats->tx_err);
16679+ atomic_inc_unchecked(&vcc->stats->tx_err);
16680
16681 fore200e->tx_sat++;
16682 DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
017d2877
AM
16683diff -urNp linux-2.6.30.4/drivers/atm/he.c linux-2.6.30.4/drivers/atm/he.c
16684--- linux-2.6.30.4/drivers/atm/he.c 2009-07-24 17:47:51.000000000 -0400
16685+++ linux-2.6.30.4/drivers/atm/he.c 2009-07-30 09:48:09.994421569 -0400
de855c5d
AM
16686@@ -1728,7 +1728,7 @@ he_service_rbrq(struct he_dev *he_dev, i
16687
16688 if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
16689 hprintk("HBUF_ERR! (cid 0x%x)\n", cid);
16690- atomic_inc(&vcc->stats->rx_drop);
16691+ atomic_inc_unchecked(&vcc->stats->rx_drop);
16692 goto return_host_buffers;
16693 }
16694
16695@@ -1761,7 +1761,7 @@ he_service_rbrq(struct he_dev *he_dev, i
16696 RBRQ_LEN_ERR(he_dev->rbrq_head)
16697 ? "LEN_ERR" : "",
16698 vcc->vpi, vcc->vci);
16699- atomic_inc(&vcc->stats->rx_err);
16700+ atomic_inc_unchecked(&vcc->stats->rx_err);
16701 goto return_host_buffers;
16702 }
16703
16704@@ -1820,7 +1820,7 @@ he_service_rbrq(struct he_dev *he_dev, i
16705 vcc->push(vcc, skb);
16706 spin_lock(&he_dev->global_lock);
16707
16708- atomic_inc(&vcc->stats->rx);
16709+ atomic_inc_unchecked(&vcc->stats->rx);
16710
16711 return_host_buffers:
16712 ++pdus_assembled;
017d2877
AM
16713@@ -2165,7 +2165,7 @@ __enqueue_tpd(struct he_dev *he_dev, str
16714 tpd->vcc->pop(tpd->vcc, tpd->skb);
16715 else
16716 dev_kfree_skb_any(tpd->skb);
16717- atomic_inc(&tpd->vcc->stats->tx_err);
16718+ atomic_inc_unchecked(&tpd->vcc->stats->tx_err);
16719 }
16720 pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
16721 return;
16722@@ -2577,7 +2577,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
16723 vcc->pop(vcc, skb);
16724 else
16725 dev_kfree_skb_any(skb);
16726- atomic_inc(&vcc->stats->tx_err);
16727+ atomic_inc_unchecked(&vcc->stats->tx_err);
16728 return -EINVAL;
16729 }
16730
16731@@ -2588,7 +2588,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
16732 vcc->pop(vcc, skb);
16733 else
16734 dev_kfree_skb_any(skb);
16735- atomic_inc(&vcc->stats->tx_err);
16736+ atomic_inc_unchecked(&vcc->stats->tx_err);
16737 return -EINVAL;
16738 }
16739 #endif
16740@@ -2600,7 +2600,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
16741 vcc->pop(vcc, skb);
16742 else
16743 dev_kfree_skb_any(skb);
16744- atomic_inc(&vcc->stats->tx_err);
16745+ atomic_inc_unchecked(&vcc->stats->tx_err);
16746 spin_unlock_irqrestore(&he_dev->global_lock, flags);
16747 return -ENOMEM;
16748 }
16749@@ -2642,7 +2642,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
16750 vcc->pop(vcc, skb);
16751 else
16752 dev_kfree_skb_any(skb);
16753- atomic_inc(&vcc->stats->tx_err);
16754+ atomic_inc_unchecked(&vcc->stats->tx_err);
16755 spin_unlock_irqrestore(&he_dev->global_lock, flags);
16756 return -ENOMEM;
16757 }
de855c5d
AM
16758@@ -2673,7 +2673,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
16759 __enqueue_tpd(he_dev, tpd, cid);
16760 spin_unlock_irqrestore(&he_dev->global_lock, flags);
16761
16762- atomic_inc(&vcc->stats->tx);
16763+ atomic_inc_unchecked(&vcc->stats->tx);
16764
16765 return 0;
16766 }
017d2877
AM
16767diff -urNp linux-2.6.30.4/drivers/atm/horizon.c linux-2.6.30.4/drivers/atm/horizon.c
16768--- linux-2.6.30.4/drivers/atm/horizon.c 2009-07-24 17:47:51.000000000 -0400
16769+++ linux-2.6.30.4/drivers/atm/horizon.c 2009-07-30 09:48:09.994421569 -0400
de855c5d
AM
16770@@ -1033,7 +1033,7 @@ static void rx_schedule (hrz_dev * dev,
16771 {
16772 struct atm_vcc * vcc = ATM_SKB(skb)->vcc;
16773 // VC layer stats
16774- atomic_inc(&vcc->stats->rx);
16775+ atomic_inc_unchecked(&vcc->stats->rx);
16776 __net_timestamp(skb);
16777 // end of our responsability
16778 vcc->push (vcc, skb);
16779@@ -1185,7 +1185,7 @@ static void tx_schedule (hrz_dev * const
16780 dev->tx_iovec = NULL;
16781
16782 // VC layer stats
16783- atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
16784+ atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
16785
16786 // free the skb
16787 hrz_kfree_skb (skb);
017d2877
AM
16788diff -urNp linux-2.6.30.4/drivers/atm/idt77252.c linux-2.6.30.4/drivers/atm/idt77252.c
16789--- linux-2.6.30.4/drivers/atm/idt77252.c 2009-07-24 17:47:51.000000000 -0400
16790+++ linux-2.6.30.4/drivers/atm/idt77252.c 2009-07-30 09:48:09.995868107 -0400
de855c5d
AM
16791@@ -810,7 +810,7 @@ drain_scq(struct idt77252_dev *card, str
16792 else
16793 dev_kfree_skb(skb);
16794
16795- atomic_inc(&vcc->stats->tx);
16796+ atomic_inc_unchecked(&vcc->stats->tx);
16797 }
16798
16799 atomic_dec(&scq->used);
16800@@ -1073,13 +1073,13 @@ dequeue_rx(struct idt77252_dev *card, st
16801 if ((sb = dev_alloc_skb(64)) == NULL) {
16802 printk("%s: Can't allocate buffers for aal0.\n",
16803 card->name);
16804- atomic_add(i, &vcc->stats->rx_drop);
16805+ atomic_add_unchecked(i, &vcc->stats->rx_drop);
16806 break;
16807 }
16808 if (!atm_charge(vcc, sb->truesize)) {
16809 RXPRINTK("%s: atm_charge() dropped aal0 packets.\n",
16810 card->name);
16811- atomic_add(i - 1, &vcc->stats->rx_drop);
16812+ atomic_add_unchecked(i - 1, &vcc->stats->rx_drop);
16813 dev_kfree_skb(sb);
16814 break;
16815 }
16816@@ -1096,7 +1096,7 @@ dequeue_rx(struct idt77252_dev *card, st
16817 ATM_SKB(sb)->vcc = vcc;
16818 __net_timestamp(sb);
16819 vcc->push(vcc, sb);
16820- atomic_inc(&vcc->stats->rx);
16821+ atomic_inc_unchecked(&vcc->stats->rx);
16822
16823 cell += ATM_CELL_PAYLOAD;
16824 }
16825@@ -1133,13 +1133,13 @@ dequeue_rx(struct idt77252_dev *card, st
16826 "(CDC: %08x)\n",
16827 card->name, len, rpp->len, readl(SAR_REG_CDC));
16828 recycle_rx_pool_skb(card, rpp);
16829- atomic_inc(&vcc->stats->rx_err);
16830+ atomic_inc_unchecked(&vcc->stats->rx_err);
16831 return;
16832 }
16833 if (stat & SAR_RSQE_CRC) {
16834 RXPRINTK("%s: AAL5 CRC error.\n", card->name);
16835 recycle_rx_pool_skb(card, rpp);
16836- atomic_inc(&vcc->stats->rx_err);
16837+ atomic_inc_unchecked(&vcc->stats->rx_err);
16838 return;
16839 }
16840 if (skb_queue_len(&rpp->queue) > 1) {
16841@@ -1150,7 +1150,7 @@ dequeue_rx(struct idt77252_dev *card, st
16842 RXPRINTK("%s: Can't alloc RX skb.\n",
16843 card->name);
16844 recycle_rx_pool_skb(card, rpp);
16845- atomic_inc(&vcc->stats->rx_err);
16846+ atomic_inc_unchecked(&vcc->stats->rx_err);
16847 return;
16848 }
16849 if (!atm_charge(vcc, skb->truesize)) {
16850@@ -1169,7 +1169,7 @@ dequeue_rx(struct idt77252_dev *card, st
16851 __net_timestamp(skb);
16852
16853 vcc->push(vcc, skb);
16854- atomic_inc(&vcc->stats->rx);
16855+ atomic_inc_unchecked(&vcc->stats->rx);
16856
16857 return;
16858 }
16859@@ -1191,7 +1191,7 @@ dequeue_rx(struct idt77252_dev *card, st
16860 __net_timestamp(skb);
16861
16862 vcc->push(vcc, skb);
16863- atomic_inc(&vcc->stats->rx);
16864+ atomic_inc_unchecked(&vcc->stats->rx);
16865
16866 if (skb->truesize > SAR_FB_SIZE_3)
16867 add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);
16868@@ -1303,14 +1303,14 @@ idt77252_rx_raw(struct idt77252_dev *car
16869 if (vcc->qos.aal != ATM_AAL0) {
16870 RPRINTK("%s: raw cell for non AAL0 vc %u.%u\n",
16871 card->name, vpi, vci);
16872- atomic_inc(&vcc->stats->rx_drop);
16873+ atomic_inc_unchecked(&vcc->stats->rx_drop);
16874 goto drop;
16875 }
16876
16877 if ((sb = dev_alloc_skb(64)) == NULL) {
16878 printk("%s: Can't allocate buffers for AAL0.\n",
16879 card->name);
16880- atomic_inc(&vcc->stats->rx_err);
16881+ atomic_inc_unchecked(&vcc->stats->rx_err);
16882 goto drop;
16883 }
16884
16885@@ -1329,7 +1329,7 @@ idt77252_rx_raw(struct idt77252_dev *car
16886 ATM_SKB(sb)->vcc = vcc;
16887 __net_timestamp(sb);
16888 vcc->push(vcc, sb);
16889- atomic_inc(&vcc->stats->rx);
16890+ atomic_inc_unchecked(&vcc->stats->rx);
16891
16892 drop:
16893 skb_pull(queue, 64);
16894@@ -1954,13 +1954,13 @@ idt77252_send_skb(struct atm_vcc *vcc, s
16895
16896 if (vc == NULL) {
16897 printk("%s: NULL connection in send().\n", card->name);
16898- atomic_inc(&vcc->stats->tx_err);
16899+ atomic_inc_unchecked(&vcc->stats->tx_err);
16900 dev_kfree_skb(skb);
16901 return -EINVAL;
16902 }
16903 if (!test_bit(VCF_TX, &vc->flags)) {
16904 printk("%s: Trying to transmit on a non-tx VC.\n", card->name);
16905- atomic_inc(&vcc->stats->tx_err);
16906+ atomic_inc_unchecked(&vcc->stats->tx_err);
16907 dev_kfree_skb(skb);
16908 return -EINVAL;
16909 }
16910@@ -1972,14 +1972,14 @@ idt77252_send_skb(struct atm_vcc *vcc, s
16911 break;
16912 default:
16913 printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
16914- atomic_inc(&vcc->stats->tx_err);
16915+ atomic_inc_unchecked(&vcc->stats->tx_err);
16916 dev_kfree_skb(skb);
16917 return -EINVAL;
16918 }
16919
16920 if (skb_shinfo(skb)->nr_frags != 0) {
16921 printk("%s: No scatter-gather yet.\n", card->name);
16922- atomic_inc(&vcc->stats->tx_err);
16923+ atomic_inc_unchecked(&vcc->stats->tx_err);
16924 dev_kfree_skb(skb);
16925 return -EINVAL;
16926 }
16927@@ -1987,7 +1987,7 @@ idt77252_send_skb(struct atm_vcc *vcc, s
16928
16929 err = queue_skb(card, vc, skb, oam);
16930 if (err) {
16931- atomic_inc(&vcc->stats->tx_err);
16932+ atomic_inc_unchecked(&vcc->stats->tx_err);
16933 dev_kfree_skb(skb);
16934 return err;
16935 }
16936@@ -2010,7 +2010,7 @@ idt77252_send_oam(struct atm_vcc *vcc, v
16937 skb = dev_alloc_skb(64);
16938 if (!skb) {
16939 printk("%s: Out of memory in send_oam().\n", card->name);
16940- atomic_inc(&vcc->stats->tx_err);
16941+ atomic_inc_unchecked(&vcc->stats->tx_err);
16942 return -ENOMEM;
16943 }
16944 atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
017d2877
AM
16945diff -urNp linux-2.6.30.4/drivers/atm/iphase.c linux-2.6.30.4/drivers/atm/iphase.c
16946--- linux-2.6.30.4/drivers/atm/iphase.c 2009-07-24 17:47:51.000000000 -0400
16947+++ linux-2.6.30.4/drivers/atm/iphase.c 2009-07-30 09:48:09.996522301 -0400
16948@@ -1123,7 +1123,7 @@ static int rx_pkt(struct atm_dev *dev)
de855c5d
AM
16949 status = (u_short) (buf_desc_ptr->desc_mode);
16950 if (status & (RX_CER | RX_PTE | RX_OFL))
16951 {
16952- atomic_inc(&vcc->stats->rx_err);
16953+ atomic_inc_unchecked(&vcc->stats->rx_err);
16954 IF_ERR(printk("IA: bad packet, dropping it");)
16955 if (status & RX_CER) {
16956 IF_ERR(printk(" cause: packet CRC error\n");)
017d2877 16957@@ -1146,7 +1146,7 @@ static int rx_pkt(struct atm_dev *dev)
de855c5d
AM
16958 len = dma_addr - buf_addr;
16959 if (len > iadev->rx_buf_sz) {
16960 printk("Over %d bytes sdu received, dropped!!!\n", iadev->rx_buf_sz);
16961- atomic_inc(&vcc->stats->rx_err);
16962+ atomic_inc_unchecked(&vcc->stats->rx_err);
16963 goto out_free_desc;
16964 }
16965
017d2877 16966@@ -1296,7 +1296,7 @@ static void rx_dle_intr(struct atm_dev *
de855c5d
AM
16967 ia_vcc = INPH_IA_VCC(vcc);
16968 if (ia_vcc == NULL)
16969 {
16970- atomic_inc(&vcc->stats->rx_err);
16971+ atomic_inc_unchecked(&vcc->stats->rx_err);
16972 dev_kfree_skb_any(skb);
16973 atm_return(vcc, atm_guess_pdu2truesize(len));
16974 goto INCR_DLE;
017d2877 16975@@ -1308,7 +1308,7 @@ static void rx_dle_intr(struct atm_dev *
de855c5d
AM
16976 if ((length > iadev->rx_buf_sz) || (length >
16977 (skb->len - sizeof(struct cpcs_trailer))))
16978 {
16979- atomic_inc(&vcc->stats->rx_err);
16980+ atomic_inc_unchecked(&vcc->stats->rx_err);
16981 IF_ERR(printk("rx_dle_intr: Bad AAL5 trailer %d (skb len %d)",
16982 length, skb->len);)
16983 dev_kfree_skb_any(skb);
017d2877 16984@@ -1324,7 +1324,7 @@ static void rx_dle_intr(struct atm_dev *
de855c5d
AM
16985
16986 IF_RX(printk("rx_dle_intr: skb push");)
16987 vcc->push(vcc,skb);
16988- atomic_inc(&vcc->stats->rx);
16989+ atomic_inc_unchecked(&vcc->stats->rx);
16990 iadev->rx_pkt_cnt++;
16991 }
16992 INCR_DLE:
017d2877 16993@@ -2919,7 +2919,7 @@ static int ia_pkt_tx (struct atm_vcc *vc
de855c5d
AM
16994 if ((desc == 0) || (desc > iadev->num_tx_desc))
16995 {
16996 IF_ERR(printk(DEV_LABEL "invalid desc for send: %d\n", desc);)
16997- atomic_inc(&vcc->stats->tx);
16998+ atomic_inc_unchecked(&vcc->stats->tx);
16999 if (vcc->pop)
17000 vcc->pop(vcc, skb);
17001 else
017d2877 17002@@ -3024,7 +3024,7 @@ static int ia_pkt_tx (struct atm_vcc *vc
de855c5d
AM
17003 ATM_DESC(skb) = vcc->vci;
17004 skb_queue_tail(&iadev->tx_dma_q, skb);
17005
17006- atomic_inc(&vcc->stats->tx);
17007+ atomic_inc_unchecked(&vcc->stats->tx);
17008 iadev->tx_pkt_cnt++;
17009 /* Increment transaction counter */
17010 writel(2, iadev->dma+IPHASE5575_TX_COUNTER);
017d2877
AM
17011diff -urNp linux-2.6.30.4/drivers/atm/lanai.c linux-2.6.30.4/drivers/atm/lanai.c
17012--- linux-2.6.30.4/drivers/atm/lanai.c 2009-07-24 17:47:51.000000000 -0400
17013+++ linux-2.6.30.4/drivers/atm/lanai.c 2009-07-30 09:48:09.997872955 -0400
de855c5d
AM
17014@@ -1305,7 +1305,7 @@ static void lanai_send_one_aal5(struct l
17015 vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);
17016 lanai_endtx(lanai, lvcc);
17017 lanai_free_skb(lvcc->tx.atmvcc, skb);
17018- atomic_inc(&lvcc->tx.atmvcc->stats->tx);
17019+ atomic_inc_unchecked(&lvcc->tx.atmvcc->stats->tx);
17020 }
17021
17022 /* Try to fill the buffer - don't call unless there is backlog */
17023@@ -1428,7 +1428,7 @@ static void vcc_rx_aal5(struct lanai_vcc
17024 ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
17025 __net_timestamp(skb);
17026 lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
17027- atomic_inc(&lvcc->rx.atmvcc->stats->rx);
17028+ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx);
17029 out:
17030 lvcc->rx.buf.ptr = end;
17031 cardvcc_write(lvcc, endptr, vcc_rxreadptr);
17032@@ -1670,7 +1670,7 @@ static int handle_service(struct lanai_d
17033 DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 "
17034 "vcc %d\n", lanai->number, (unsigned int) s, vci);
17035 lanai->stats.service_rxnotaal5++;
17036- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
17037+ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
17038 return 0;
17039 }
17040 if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) {
17041@@ -1682,7 +1682,7 @@ static int handle_service(struct lanai_d
17042 int bytes;
17043 read_unlock(&vcc_sklist_lock);
17044 DPRINTK("got trashed rx pdu on vci %d\n", vci);
17045- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
17046+ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
17047 lvcc->stats.x.aal5.service_trash++;
17048 bytes = (SERVICE_GET_END(s) * 16) -
17049 (((unsigned long) lvcc->rx.buf.ptr) -
17050@@ -1694,7 +1694,7 @@ static int handle_service(struct lanai_d
17051 }
17052 if (s & SERVICE_STREAM) {
17053 read_unlock(&vcc_sklist_lock);
17054- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
17055+ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
17056 lvcc->stats.x.aal5.service_stream++;
17057 printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream "
17058 "PDU on VCI %d!\n", lanai->number, vci);
17059@@ -1702,7 +1702,7 @@ static int handle_service(struct lanai_d
17060 return 0;
17061 }
17062 DPRINTK("got rx crc error on vci %d\n", vci);
17063- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
17064+ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
17065 lvcc->stats.x.aal5.service_rxcrc++;
17066 lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
17067 cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
017d2877
AM
17068diff -urNp linux-2.6.30.4/drivers/atm/nicstar.c linux-2.6.30.4/drivers/atm/nicstar.c
17069--- linux-2.6.30.4/drivers/atm/nicstar.c 2009-07-24 17:47:51.000000000 -0400
17070+++ linux-2.6.30.4/drivers/atm/nicstar.c 2009-07-30 09:48:09.998576713 -0400
de855c5d
AM
17071@@ -1723,7 +1723,7 @@ static int ns_send(struct atm_vcc *vcc,
17072 if ((vc = (vc_map *) vcc->dev_data) == NULL)
17073 {
17074 printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n", card->index);
17075- atomic_inc(&vcc->stats->tx_err);
17076+ atomic_inc_unchecked(&vcc->stats->tx_err);
17077 dev_kfree_skb_any(skb);
17078 return -EINVAL;
17079 }
17080@@ -1731,7 +1731,7 @@ static int ns_send(struct atm_vcc *vcc,
17081 if (!vc->tx)
17082 {
17083 printk("nicstar%d: Trying to transmit on a non-tx VC.\n", card->index);
17084- atomic_inc(&vcc->stats->tx_err);
17085+ atomic_inc_unchecked(&vcc->stats->tx_err);
17086 dev_kfree_skb_any(skb);
17087 return -EINVAL;
17088 }
17089@@ -1739,7 +1739,7 @@ static int ns_send(struct atm_vcc *vcc,
17090 if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0)
17091 {
17092 printk("nicstar%d: Only AAL0 and AAL5 are supported.\n", card->index);
17093- atomic_inc(&vcc->stats->tx_err);
17094+ atomic_inc_unchecked(&vcc->stats->tx_err);
17095 dev_kfree_skb_any(skb);
17096 return -EINVAL;
17097 }
17098@@ -1747,7 +1747,7 @@ static int ns_send(struct atm_vcc *vcc,
17099 if (skb_shinfo(skb)->nr_frags != 0)
17100 {
17101 printk("nicstar%d: No scatter-gather yet.\n", card->index);
17102- atomic_inc(&vcc->stats->tx_err);
17103+ atomic_inc_unchecked(&vcc->stats->tx_err);
17104 dev_kfree_skb_any(skb);
17105 return -EINVAL;
17106 }
17107@@ -1792,11 +1792,11 @@ static int ns_send(struct atm_vcc *vcc,
17108
17109 if (push_scqe(card, vc, scq, &scqe, skb) != 0)
17110 {
17111- atomic_inc(&vcc->stats->tx_err);
17112+ atomic_inc_unchecked(&vcc->stats->tx_err);
17113 dev_kfree_skb_any(skb);
17114 return -EIO;
17115 }
17116- atomic_inc(&vcc->stats->tx);
17117+ atomic_inc_unchecked(&vcc->stats->tx);
17118
17119 return 0;
17120 }
17121@@ -2111,14 +2111,14 @@ static void dequeue_rx(ns_dev *card, ns_
17122 {
17123 printk("nicstar%d: Can't allocate buffers for aal0.\n",
17124 card->index);
17125- atomic_add(i,&vcc->stats->rx_drop);
17126+ atomic_add_unchecked(i,&vcc->stats->rx_drop);
17127 break;
17128 }
17129 if (!atm_charge(vcc, sb->truesize))
17130 {
17131 RXPRINTK("nicstar%d: atm_charge() dropped aal0 packets.\n",
17132 card->index);
17133- atomic_add(i-1,&vcc->stats->rx_drop); /* already increased by 1 */
17134+ atomic_add_unchecked(i-1,&vcc->stats->rx_drop); /* already increased by 1 */
17135 dev_kfree_skb_any(sb);
17136 break;
17137 }
17138@@ -2133,7 +2133,7 @@ static void dequeue_rx(ns_dev *card, ns_
17139 ATM_SKB(sb)->vcc = vcc;
17140 __net_timestamp(sb);
17141 vcc->push(vcc, sb);
17142- atomic_inc(&vcc->stats->rx);
17143+ atomic_inc_unchecked(&vcc->stats->rx);
17144 cell += ATM_CELL_PAYLOAD;
17145 }
17146
17147@@ -2152,7 +2152,7 @@ static void dequeue_rx(ns_dev *card, ns_
17148 if (iovb == NULL)
17149 {
17150 printk("nicstar%d: Out of iovec buffers.\n", card->index);
17151- atomic_inc(&vcc->stats->rx_drop);
17152+ atomic_inc_unchecked(&vcc->stats->rx_drop);
17153 recycle_rx_buf(card, skb);
17154 return;
17155 }
17156@@ -2182,7 +2182,7 @@ static void dequeue_rx(ns_dev *card, ns_
17157 else if (NS_SKB(iovb)->iovcnt >= NS_MAX_IOVECS)
17158 {
17159 printk("nicstar%d: received too big AAL5 SDU.\n", card->index);
17160- atomic_inc(&vcc->stats->rx_err);
17161+ atomic_inc_unchecked(&vcc->stats->rx_err);
17162 recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, NS_MAX_IOVECS);
17163 NS_SKB(iovb)->iovcnt = 0;
17164 iovb->len = 0;
17165@@ -2202,7 +2202,7 @@ static void dequeue_rx(ns_dev *card, ns_
17166 printk("nicstar%d: Expected a small buffer, and this is not one.\n",
17167 card->index);
17168 which_list(card, skb);
17169- atomic_inc(&vcc->stats->rx_err);
17170+ atomic_inc_unchecked(&vcc->stats->rx_err);
17171 recycle_rx_buf(card, skb);
17172 vc->rx_iov = NULL;
17173 recycle_iov_buf(card, iovb);
17174@@ -2216,7 +2216,7 @@ static void dequeue_rx(ns_dev *card, ns_
17175 printk("nicstar%d: Expected a large buffer, and this is not one.\n",
17176 card->index);
17177 which_list(card, skb);
17178- atomic_inc(&vcc->stats->rx_err);
17179+ atomic_inc_unchecked(&vcc->stats->rx_err);
17180 recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data,
17181 NS_SKB(iovb)->iovcnt);
17182 vc->rx_iov = NULL;
17183@@ -2240,7 +2240,7 @@ static void dequeue_rx(ns_dev *card, ns_
17184 printk(" - PDU size mismatch.\n");
17185 else
17186 printk(".\n");
17187- atomic_inc(&vcc->stats->rx_err);
17188+ atomic_inc_unchecked(&vcc->stats->rx_err);
17189 recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data,
17190 NS_SKB(iovb)->iovcnt);
17191 vc->rx_iov = NULL;
17192@@ -2256,7 +2256,7 @@ static void dequeue_rx(ns_dev *card, ns_
17193 if (!atm_charge(vcc, skb->truesize))
17194 {
17195 push_rxbufs(card, skb);
17196- atomic_inc(&vcc->stats->rx_drop);
17197+ atomic_inc_unchecked(&vcc->stats->rx_drop);
17198 }
17199 else
17200 {
17201@@ -2268,7 +2268,7 @@ static void dequeue_rx(ns_dev *card, ns_
17202 ATM_SKB(skb)->vcc = vcc;
17203 __net_timestamp(skb);
17204 vcc->push(vcc, skb);
17205- atomic_inc(&vcc->stats->rx);
17206+ atomic_inc_unchecked(&vcc->stats->rx);
17207 }
17208 }
17209 else if (NS_SKB(iovb)->iovcnt == 2) /* One small plus one large buffer */
17210@@ -2283,7 +2283,7 @@ static void dequeue_rx(ns_dev *card, ns_
17211 if (!atm_charge(vcc, sb->truesize))
17212 {
17213 push_rxbufs(card, sb);
17214- atomic_inc(&vcc->stats->rx_drop);
17215+ atomic_inc_unchecked(&vcc->stats->rx_drop);
17216 }
17217 else
17218 {
17219@@ -2295,7 +2295,7 @@ static void dequeue_rx(ns_dev *card, ns_
17220 ATM_SKB(sb)->vcc = vcc;
17221 __net_timestamp(sb);
17222 vcc->push(vcc, sb);
17223- atomic_inc(&vcc->stats->rx);
17224+ atomic_inc_unchecked(&vcc->stats->rx);
17225 }
17226
17227 push_rxbufs(card, skb);
17228@@ -2306,7 +2306,7 @@ static void dequeue_rx(ns_dev *card, ns_
17229 if (!atm_charge(vcc, skb->truesize))
17230 {
17231 push_rxbufs(card, skb);
17232- atomic_inc(&vcc->stats->rx_drop);
17233+ atomic_inc_unchecked(&vcc->stats->rx_drop);
17234 }
17235 else
17236 {
17237@@ -2320,7 +2320,7 @@ static void dequeue_rx(ns_dev *card, ns_
17238 ATM_SKB(skb)->vcc = vcc;
17239 __net_timestamp(skb);
17240 vcc->push(vcc, skb);
17241- atomic_inc(&vcc->stats->rx);
17242+ atomic_inc_unchecked(&vcc->stats->rx);
17243 }
17244
17245 push_rxbufs(card, sb);
17246@@ -2342,7 +2342,7 @@ static void dequeue_rx(ns_dev *card, ns_
17247 if (hb == NULL)
17248 {
17249 printk("nicstar%d: Out of huge buffers.\n", card->index);
17250- atomic_inc(&vcc->stats->rx_drop);
17251+ atomic_inc_unchecked(&vcc->stats->rx_drop);
17252 recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data,
17253 NS_SKB(iovb)->iovcnt);
17254 vc->rx_iov = NULL;
17255@@ -2393,7 +2393,7 @@ static void dequeue_rx(ns_dev *card, ns_
17256 }
17257 else
17258 dev_kfree_skb_any(hb);
17259- atomic_inc(&vcc->stats->rx_drop);
17260+ atomic_inc_unchecked(&vcc->stats->rx_drop);
17261 }
17262 else
17263 {
17264@@ -2427,7 +2427,7 @@ static void dequeue_rx(ns_dev *card, ns_
17265 #endif /* NS_USE_DESTRUCTORS */
17266 __net_timestamp(hb);
17267 vcc->push(vcc, hb);
17268- atomic_inc(&vcc->stats->rx);
17269+ atomic_inc_unchecked(&vcc->stats->rx);
17270 }
17271 }
17272
017d2877
AM
17273diff -urNp linux-2.6.30.4/drivers/atm/solos-pci.c linux-2.6.30.4/drivers/atm/solos-pci.c
17274--- linux-2.6.30.4/drivers/atm/solos-pci.c 2009-07-24 17:47:51.000000000 -0400
17275+++ linux-2.6.30.4/drivers/atm/solos-pci.c 2009-07-30 09:48:09.998576713 -0400
17276@@ -663,7 +663,7 @@ void solos_bh(unsigned long card_arg)
de855c5d
AM
17277 }
17278 atm_charge(vcc, skb->truesize);
17279 vcc->push(vcc, skb);
17280- atomic_inc(&vcc->stats->rx);
17281+ atomic_inc_unchecked(&vcc->stats->rx);
17282 break;
17283
017d2877
AM
17284 case PKT_STATUS:
17285@@ -966,7 +966,7 @@ static uint32_t fpga_tx(struct solos_car
17286 vcc = SKB_CB(oldskb)->vcc;
de855c5d
AM
17287
17288 if (vcc) {
17289- atomic_inc(&vcc->stats->tx);
17290+ atomic_inc_unchecked(&vcc->stats->tx);
017d2877 17291 solos_pop(vcc, oldskb);
de855c5d 17292 } else
017d2877
AM
17293 dev_kfree_skb_irq(oldskb);
17294diff -urNp linux-2.6.30.4/drivers/atm/suni.c linux-2.6.30.4/drivers/atm/suni.c
17295--- linux-2.6.30.4/drivers/atm/suni.c 2009-07-24 17:47:51.000000000 -0400
17296+++ linux-2.6.30.4/drivers/atm/suni.c 2009-07-30 09:48:09.998576713 -0400
de855c5d
AM
17297@@ -49,7 +49,7 @@ static DEFINE_SPINLOCK(sunis_lock);
17298
17299
17300 #define ADD_LIMITED(s,v) \
17301- atomic_add((v),&stats->s); \
17302+ atomic_add_unchecked((v),&stats->s); \
17303 if (atomic_read(&stats->s) < 0) atomic_set(&stats->s,INT_MAX);
17304
17305
017d2877
AM
17306diff -urNp linux-2.6.30.4/drivers/atm/uPD98402.c linux-2.6.30.4/drivers/atm/uPD98402.c
17307--- linux-2.6.30.4/drivers/atm/uPD98402.c 2009-07-24 17:47:51.000000000 -0400
17308+++ linux-2.6.30.4/drivers/atm/uPD98402.c 2009-07-30 09:48:09.999830275 -0400
de855c5d
AM
17309@@ -41,7 +41,7 @@ static int fetch_stats(struct atm_dev *d
17310 struct sonet_stats tmp;
17311 int error = 0;
17312
17313- atomic_add(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
17314+ atomic_add_unchecked(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
17315 sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp);
17316 if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
17317 if (zero && !error) {
17318@@ -160,7 +160,7 @@ static int uPD98402_ioctl(struct atm_dev
17319
17320
17321 #define ADD_LIMITED(s,v) \
17322- { atomic_add(GET(v),&PRIV(dev)->sonet_stats.s); \
17323+ { atomic_add_unchecked(GET(v),&PRIV(dev)->sonet_stats.s); \
17324 if (atomic_read(&PRIV(dev)->sonet_stats.s) < 0) \
17325 atomic_set(&PRIV(dev)->sonet_stats.s,INT_MAX); }
17326
17327@@ -193,7 +193,7 @@ static void uPD98402_int(struct atm_dev
17328 if (reason & uPD98402_INT_PFM) stat_event(dev);
17329 if (reason & uPD98402_INT_PCO) {
17330 (void) GET(PCOCR); /* clear interrupt cause */
17331- atomic_add(GET(HECCT),
17332+ atomic_add_unchecked(GET(HECCT),
17333 &PRIV(dev)->sonet_stats.uncorr_hcs);
17334 }
17335 if ((reason & uPD98402_INT_RFO) &&
017d2877
AM
17336diff -urNp linux-2.6.30.4/drivers/atm/zatm.c linux-2.6.30.4/drivers/atm/zatm.c
17337--- linux-2.6.30.4/drivers/atm/zatm.c 2009-07-24 17:47:51.000000000 -0400
17338+++ linux-2.6.30.4/drivers/atm/zatm.c 2009-07-30 09:48:09.999830275 -0400
de855c5d
AM
17339@@ -458,7 +458,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
17340 }
17341 if (!size) {
17342 dev_kfree_skb_irq(skb);
17343- if (vcc) atomic_inc(&vcc->stats->rx_err);
17344+ if (vcc) atomic_inc_unchecked(&vcc->stats->rx_err);
17345 continue;
17346 }
17347 if (!atm_charge(vcc,skb->truesize)) {
17348@@ -468,7 +468,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
17349 skb->len = size;
17350 ATM_SKB(skb)->vcc = vcc;
17351 vcc->push(vcc,skb);
17352- atomic_inc(&vcc->stats->rx);
17353+ atomic_inc_unchecked(&vcc->stats->rx);
17354 }
17355 zout(pos & 0xffff,MTA(mbx));
17356 #if 0 /* probably a stupid idea */
17357@@ -732,7 +732,7 @@ if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD
17358 skb_queue_head(&zatm_vcc->backlog,skb);
17359 break;
17360 }
17361- atomic_inc(&vcc->stats->tx);
17362+ atomic_inc_unchecked(&vcc->stats->tx);
17363 wake_up(&zatm_vcc->tx_wait);
17364 }
17365
017d2877
AM
17366diff -urNp linux-2.6.30.4/drivers/block/cciss.c linux-2.6.30.4/drivers/block/cciss.c
17367--- linux-2.6.30.4/drivers/block/cciss.c 2009-07-24 17:47:51.000000000 -0400
17368+++ linux-2.6.30.4/drivers/block/cciss.c 2009-07-30 09:48:10.000592968 -0400
17369@@ -351,7 +351,7 @@ static void cciss_seq_stop(struct seq_fi
17370 h->busy_configuring = 0;
17371 }
17372
17373-static struct seq_operations cciss_seq_ops = {
17374+static const struct seq_operations cciss_seq_ops = {
17375 .start = cciss_seq_start,
17376 .show = cciss_seq_show,
17377 .next = cciss_seq_next,
17378@@ -414,7 +414,7 @@ out:
17379 return err;
17380 }
17381
17382-static struct file_operations cciss_proc_fops = {
17383+static const struct file_operations cciss_proc_fops = {
17384 .owner = THIS_MODULE,
17385 .open = cciss_seq_open,
17386 .read = seq_read,
17387diff -urNp linux-2.6.30.4/drivers/char/agp/alpha-agp.c linux-2.6.30.4/drivers/char/agp/alpha-agp.c
17388--- linux-2.6.30.4/drivers/char/agp/alpha-agp.c 2009-07-24 17:47:51.000000000 -0400
17389+++ linux-2.6.30.4/drivers/char/agp/alpha-agp.c 2009-07-30 09:48:10.000592968 -0400
17390@@ -40,7 +40,7 @@ static struct aper_size_info_fixed alpha
17391 { 0, 0, 0 }, /* filled in by alpha_core_agp_setup */
17392 };
17393
17394-struct vm_operations_struct alpha_core_agp_vm_ops = {
17395+const struct vm_operations_struct alpha_core_agp_vm_ops = {
17396 .fault = alpha_core_agp_vm_fault,
17397 };
17398
17399diff -urNp linux-2.6.30.4/drivers/char/agp/frontend.c linux-2.6.30.4/drivers/char/agp/frontend.c
17400--- linux-2.6.30.4/drivers/char/agp/frontend.c 2009-07-24 17:47:51.000000000 -0400
17401+++ linux-2.6.30.4/drivers/char/agp/frontend.c 2009-07-30 09:48:10.001783459 -0400
2380c486
JR
17402@@ -824,7 +824,7 @@ static int agpioc_reserve_wrap(struct ag
17403 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
17404 return -EFAULT;
17405
17406- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
17407+ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
17408 return -EFAULT;
17409
17410 client = agp_find_client_by_pid(reserve.pid);
017d2877
AM
17411diff -urNp linux-2.6.30.4/drivers/char/agp/intel-agp.c linux-2.6.30.4/drivers/char/agp/intel-agp.c
17412--- linux-2.6.30.4/drivers/char/agp/intel-agp.c 2009-07-24 17:47:51.000000000 -0400
17413+++ linux-2.6.30.4/drivers/char/agp/intel-agp.c 2009-07-30 09:48:10.002661044 -0400
17414@@ -2387,7 +2387,7 @@ static struct pci_device_id agp_intel_pc
2380c486
JR
17415 ID(PCI_DEVICE_ID_INTEL_Q45_HB),
17416 ID(PCI_DEVICE_ID_INTEL_G45_HB),
17417 ID(PCI_DEVICE_ID_INTEL_G41_HB),
17418- { }
17419+ { 0, 0, 0, 0, 0, 0, 0 }
17420 };
17421
17422 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
017d2877
AM
17423diff -urNp linux-2.6.30.4/drivers/char/apm-emulation.c linux-2.6.30.4/drivers/char/apm-emulation.c
17424--- linux-2.6.30.4/drivers/char/apm-emulation.c 2009-07-24 17:47:51.000000000 -0400
17425+++ linux-2.6.30.4/drivers/char/apm-emulation.c 2009-07-30 09:48:10.002661044 -0400
17426@@ -393,7 +393,7 @@ static int apm_open(struct inode * inode
17427 return as ? 0 : -ENOMEM;
17428 }
17429
17430-static struct file_operations apm_bios_fops = {
17431+static const struct file_operations apm_bios_fops = {
17432 .owner = THIS_MODULE,
17433 .read = apm_read,
17434 .poll = apm_poll,
17435diff -urNp linux-2.6.30.4/drivers/char/bfin-otp.c linux-2.6.30.4/drivers/char/bfin-otp.c
17436--- linux-2.6.30.4/drivers/char/bfin-otp.c 2009-07-24 17:47:51.000000000 -0400
17437+++ linux-2.6.30.4/drivers/char/bfin-otp.c 2009-07-30 09:48:10.003480690 -0400
17438@@ -133,7 +133,7 @@ static ssize_t bfin_otp_write(struct fil
17439 # define bfin_otp_write NULL
17440 #endif
17441
17442-static struct file_operations bfin_otp_fops = {
17443+static const struct file_operations bfin_otp_fops = {
17444 .owner = THIS_MODULE,
17445 .read = bfin_otp_read,
17446 .write = bfin_otp_write,
17447diff -urNp linux-2.6.30.4/drivers/char/hpet.c linux-2.6.30.4/drivers/char/hpet.c
17448--- linux-2.6.30.4/drivers/char/hpet.c 2009-07-24 17:47:51.000000000 -0400
17449+++ linux-2.6.30.4/drivers/char/hpet.c 2009-07-30 09:48:10.003480690 -0400
17450@@ -995,7 +995,7 @@ static struct acpi_driver hpet_acpi_driv
2380c486
JR
17451 },
17452 };
17453
17454-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
17455+static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
17456
17457 static int __init hpet_init(void)
17458 {
017d2877
AM
17459diff -urNp linux-2.6.30.4/drivers/char/ipmi/ipmi_msghandler.c linux-2.6.30.4/drivers/char/ipmi/ipmi_msghandler.c
17460--- linux-2.6.30.4/drivers/char/ipmi/ipmi_msghandler.c 2009-07-24 17:47:51.000000000 -0400
17461+++ linux-2.6.30.4/drivers/char/ipmi/ipmi_msghandler.c 2009-07-30 09:48:10.004509700 -0400
17462@@ -413,7 +413,7 @@ struct ipmi_smi {
de855c5d
AM
17463 struct proc_dir_entry *proc_dir;
17464 char proc_dir_name[10];
17465
17466- atomic_t stats[IPMI_NUM_STATS];
17467+ atomic_unchecked_t stats[IPMI_NUM_STATS];
17468
17469 /*
17470 * run_to_completion duplicate of smb_info, smi_info
017d2877 17471@@ -446,7 +446,7 @@ static DEFINE_MUTEX(smi_watchers_mutex);
de855c5d
AM
17472
17473
17474 #define ipmi_inc_stat(intf, stat) \
17475- atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
17476+ atomic_inc_unchecked(&(intf)->stats[IPMI_STAT_ ## stat])
17477 #define ipmi_get_stat(intf, stat) \
17478 ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
17479
017d2877
AM
17480diff -urNp linux-2.6.30.4/drivers/char/ipmi/ipmi_si_intf.c linux-2.6.30.4/drivers/char/ipmi/ipmi_si_intf.c
17481--- linux-2.6.30.4/drivers/char/ipmi/ipmi_si_intf.c 2009-07-24 17:47:51.000000000 -0400
17482+++ linux-2.6.30.4/drivers/char/ipmi/ipmi_si_intf.c 2009-07-30 09:48:10.005414644 -0400
17483@@ -277,7 +277,7 @@ struct smi_info {
17484 unsigned char slave_addr;
17485
17486 /* Counters and things for the proc filesystem. */
17487- atomic_t stats[SI_NUM_STATS];
17488+ atomic_unchecked_t stats[SI_NUM_STATS];
17489
17490 struct task_struct *thread;
17491
17492@@ -285,7 +285,7 @@ struct smi_info {
de855c5d
AM
17493 };
17494
17495 #define smi_inc_stat(smi, stat) \
17496- atomic_inc(&(smi)->stats[SI_STAT_ ## stat])
17497+ atomic_inc_unchecked(&(smi)->stats[SI_STAT_ ## stat])
17498 #define smi_get_stat(smi, stat) \
17499 ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_ ## stat]))
17500
017d2877
AM
17501diff -urNp linux-2.6.30.4/drivers/char/keyboard.c linux-2.6.30.4/drivers/char/keyboard.c
17502--- linux-2.6.30.4/drivers/char/keyboard.c 2009-07-24 17:47:51.000000000 -0400
17503+++ linux-2.6.30.4/drivers/char/keyboard.c 2009-07-30 11:10:48.982870250 -0400
2380c486
JR
17504@@ -635,6 +635,16 @@ static void k_spec(struct vc_data *vc, u
17505 kbd->kbdmode == VC_MEDIUMRAW) &&
17506 value != KVAL(K_SAK))
17507 return; /* SAK is allowed even in raw mode */
17508+
17509+#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
17510+ {
17511+ void *func = fn_handler[value];
17512+ if (func == fn_show_state || func == fn_show_ptregs ||
17513+ func == fn_show_mem)
17514+ return;
17515+ }
17516+#endif
17517+
17518 fn_handler[value](vc);
17519 }
17520
17521@@ -1388,7 +1398,7 @@ static const struct input_device_id kbd_
17522 .evbit = { BIT_MASK(EV_SND) },
17523 },
17524
17525- { }, /* Terminating entry */
17526+ { 0 }, /* Terminating entry */
17527 };
17528
17529 MODULE_DEVICE_TABLE(input, kbd_ids);
017d2877
AM
17530diff -urNp linux-2.6.30.4/drivers/char/mem.c linux-2.6.30.4/drivers/char/mem.c
17531--- linux-2.6.30.4/drivers/char/mem.c 2009-07-24 17:47:51.000000000 -0400
17532+++ linux-2.6.30.4/drivers/char/mem.c 2009-07-30 12:07:09.578070399 -0400
2380c486
JR
17533@@ -18,6 +18,7 @@
17534 #include <linux/raw.h>
17535 #include <linux/tty.h>
17536 #include <linux/capability.h>
17537+#include <linux/security.h>
17538 #include <linux/ptrace.h>
17539 #include <linux/device.h>
17540 #include <linux/highmem.h>
17541@@ -35,6 +36,10 @@
17542 # include <linux/efi.h>
17543 #endif
17544
de855c5d 17545+#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
2380c486
JR
17546+extern struct file_operations grsec_fops;
17547+#endif
17548+
17549 /*
17550 * Architectures vary in how they handle caching for addresses
17551 * outside of main memory.
17552@@ -192,6 +197,11 @@ static ssize_t write_mem(struct file * f
17553 if (!valid_phys_addr_range(p, count))
17554 return -EFAULT;
17555
17556+#ifdef CONFIG_GRKERNSEC_KMEM
17557+ gr_handle_mem_write();
17558+ return -EPERM;
17559+#endif
17560+
17561 written = 0;
17562
17563 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
017d2877
AM
17564@@ -301,7 +311,7 @@ static inline int private_mapping_ok(str
17565 }
17566 #endif
17567
17568-static struct vm_operations_struct mmap_mem_ops = {
17569+static const struct vm_operations_struct mmap_mem_ops = {
17570 #ifdef CONFIG_HAVE_IOREMAP_PROT
17571 .access = generic_access_phys
17572 #endif
17573@@ -324,6 +334,11 @@ static int mmap_mem(struct file * file,
2380c486
JR
17574 &vma->vm_page_prot))
17575 return -EINVAL;
17576
17577+#ifdef CONFIG_GRKERNSEC_KMEM
17578+ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
17579+ return -EPERM;
17580+#endif
17581+
17582 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
17583 size,
17584 vma->vm_page_prot);
017d2877 17585@@ -558,6 +573,11 @@ static ssize_t write_kmem(struct file *
2380c486
JR
17586 ssize_t written;
17587 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
17588
17589+#ifdef CONFIG_GRKERNSEC_KMEM
17590+ gr_handle_kmem_write();
17591+ return -EPERM;
17592+#endif
17593+
17594 if (p < (unsigned long) high_memory) {
17595
17596 wrote = count;
017d2877 17597@@ -764,6 +784,16 @@ static loff_t memory_lseek(struct file *
2380c486
JR
17598
17599 static int open_port(struct inode * inode, struct file * filp)
17600 {
17601+#ifdef CONFIG_GRKERNSEC_KMEM
17602+ gr_handle_open_port();
17603+ return -EPERM;
17604+#endif
17605+
17606+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
17607+}
17608+
17609+static int open_mem(struct inode * inode, struct file * filp)
17610+{
17611 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
17612 }
17613
017d2877 17614@@ -771,7 +801,6 @@ static int open_port(struct inode * inod
2380c486
JR
17615 #define full_lseek null_lseek
17616 #define write_zero write_null
17617 #define read_full read_zero
17618-#define open_mem open_port
17619 #define open_kmem open_mem
17620 #define open_oldmem open_mem
17621
017d2877 17622@@ -911,6 +940,11 @@ static int memory_open(struct inode * in
2380c486
JR
17623 filp->f_op = &oldmem_fops;
17624 break;
17625 #endif
de855c5d 17626+#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
2380c486
JR
17627+ case 13:
17628+ filp->f_op = &grsec_fops;
17629+ break;
17630+#endif
17631 default:
17632 unlock_kernel();
17633 return -ENXIO;
017d2877 17634@@ -947,6 +981,9 @@ static const struct {
2380c486
JR
17635 #ifdef CONFIG_CRASH_DUMP
17636 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
17637 #endif
de855c5d 17638+#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC)
2380c486
JR
17639+ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
17640+#endif
17641 };
17642
17643 static struct class *mem_class;
017d2877
AM
17644diff -urNp linux-2.6.30.4/drivers/char/misc.c linux-2.6.30.4/drivers/char/misc.c
17645--- linux-2.6.30.4/drivers/char/misc.c 2009-07-24 17:47:51.000000000 -0400
17646+++ linux-2.6.30.4/drivers/char/misc.c 2009-07-30 09:48:10.006662764 -0400
17647@@ -91,7 +91,7 @@ static int misc_seq_show(struct seq_file
17648 }
17649
17650
17651-static struct seq_operations misc_seq_ops = {
17652+static const struct seq_operations misc_seq_ops = {
17653 .start = misc_seq_start,
17654 .next = misc_seq_next,
17655 .stop = misc_seq_stop,
17656diff -urNp linux-2.6.30.4/drivers/char/mspec.c linux-2.6.30.4/drivers/char/mspec.c
17657--- linux-2.6.30.4/drivers/char/mspec.c 2009-07-24 17:47:51.000000000 -0400
17658+++ linux-2.6.30.4/drivers/char/mspec.c 2009-07-30 09:48:10.006662764 -0400
17659@@ -239,7 +239,7 @@ mspec_fault(struct vm_area_struct *vma,
17660 return VM_FAULT_NOPAGE;
17661 }
17662
17663-static struct vm_operations_struct mspec_vm_ops = {
17664+static const struct vm_operations_struct mspec_vm_ops = {
17665 .open = mspec_open,
17666 .close = mspec_close,
17667 .fault = mspec_fault,
17668diff -urNp linux-2.6.30.4/drivers/char/nvram.c linux-2.6.30.4/drivers/char/nvram.c
17669--- linux-2.6.30.4/drivers/char/nvram.c 2009-07-24 17:47:51.000000000 -0400
17670+++ linux-2.6.30.4/drivers/char/nvram.c 2009-07-30 09:48:10.006662764 -0400
2380c486
JR
17671@@ -429,7 +429,10 @@ static const struct file_operations nvra
17672 static struct miscdevice nvram_dev = {
17673 NVRAM_MINOR,
17674 "nvram",
17675- &nvram_fops
17676+ &nvram_fops,
17677+ {NULL, NULL},
17678+ NULL,
17679+ NULL
17680 };
17681
17682 static int __init nvram_init(void)
017d2877
AM
17683diff -urNp linux-2.6.30.4/drivers/char/random.c linux-2.6.30.4/drivers/char/random.c
17684--- linux-2.6.30.4/drivers/char/random.c 2009-07-24 17:47:51.000000000 -0400
17685+++ linux-2.6.30.4/drivers/char/random.c 2009-07-30 11:10:48.992521357 -0400
17686@@ -253,8 +253,13 @@
2380c486
JR
17687 /*
17688 * Configuration information
17689 */
17690+#ifdef CONFIG_GRKERNSEC_RANDNET
17691+#define INPUT_POOL_WORDS 512
17692+#define OUTPUT_POOL_WORDS 128
17693+#else
17694 #define INPUT_POOL_WORDS 128
17695 #define OUTPUT_POOL_WORDS 32
17696+#endif
17697 #define SEC_XFER_SIZE 512
17698
17699 /*
017d2877 17700@@ -291,10 +296,17 @@ static struct poolinfo {
2380c486
JR
17701 int poolwords;
17702 int tap1, tap2, tap3, tap4, tap5;
17703 } poolinfo_table[] = {
17704+#ifdef CONFIG_GRKERNSEC_RANDNET
17705+ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
17706+ { 512, 411, 308, 208, 104, 1 },
17707+ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
17708+ { 128, 103, 76, 51, 25, 1 },
17709+#else
17710 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
17711 { 128, 103, 76, 51, 25, 1 },
17712 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
17713 { 32, 26, 20, 14, 7, 1 },
17714+#endif
17715 #if 0
17716 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
17717 { 2048, 1638, 1231, 819, 411, 1 },
017d2877 17718@@ -1204,7 +1216,7 @@ EXPORT_SYMBOL(generate_random_uuid);
2380c486
JR
17719 #include <linux/sysctl.h>
17720
17721 static int min_read_thresh = 8, min_write_thresh;
17722-static int max_read_thresh = INPUT_POOL_WORDS * 32;
17723+static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
17724 static int max_write_thresh = INPUT_POOL_WORDS * 32;
17725 static char sysctl_bootid[16];
17726
017d2877
AM
17727diff -urNp linux-2.6.30.4/drivers/char/tpm/tpm_bios.c linux-2.6.30.4/drivers/char/tpm/tpm_bios.c
17728--- linux-2.6.30.4/drivers/char/tpm/tpm_bios.c 2009-07-24 17:47:51.000000000 -0400
17729+++ linux-2.6.30.4/drivers/char/tpm/tpm_bios.c 2009-07-30 09:48:10.007651841 -0400
17730@@ -343,14 +343,14 @@ static int tpm_ascii_bios_measurements_s
17731 return 0;
17732 }
17733
17734-static struct seq_operations tpm_ascii_b_measurments_seqops = {
17735+static const struct seq_operations tpm_ascii_b_measurments_seqops = {
17736 .start = tpm_bios_measurements_start,
17737 .next = tpm_bios_measurements_next,
17738 .stop = tpm_bios_measurements_stop,
17739 .show = tpm_ascii_bios_measurements_show,
17740 };
17741
17742-static struct seq_operations tpm_binary_b_measurments_seqops = {
17743+static const struct seq_operations tpm_binary_b_measurments_seqops = {
17744 .start = tpm_bios_measurements_start,
17745 .next = tpm_bios_measurements_next,
17746 .stop = tpm_bios_measurements_stop,
17747diff -urNp linux-2.6.30.4/drivers/char/tty_ldisc.c linux-2.6.30.4/drivers/char/tty_ldisc.c
17748--- linux-2.6.30.4/drivers/char/tty_ldisc.c 2009-07-24 17:47:51.000000000 -0400
17749+++ linux-2.6.30.4/drivers/char/tty_ldisc.c 2009-07-30 09:48:10.008436205 -0400
17750@@ -73,7 +73,7 @@ int tty_register_ldisc(int disc, struct
2380c486
JR
17751 spin_lock_irqsave(&tty_ldisc_lock, flags);
17752 tty_ldiscs[disc] = new_ldisc;
17753 new_ldisc->num = disc;
17754- new_ldisc->refcount = 0;
17755+ atomic_set(&new_ldisc->refcount, 0);
17756 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
17757
17758 return ret;
017d2877 17759@@ -101,7 +101,7 @@ int tty_unregister_ldisc(int disc)
2380c486
JR
17760 return -EINVAL;
17761
17762 spin_lock_irqsave(&tty_ldisc_lock, flags);
17763- if (tty_ldiscs[disc]->refcount)
17764+ if (atomic_read(&tty_ldiscs[disc]->refcount))
17765 ret = -EBUSY;
17766 else
17767 tty_ldiscs[disc] = NULL;
017d2877 17768@@ -138,7 +138,7 @@ static int tty_ldisc_try_get(int disc, s
2380c486
JR
17769 err = -EAGAIN;
17770 else {
17771 /* lock it */
17772- ldops->refcount++;
17773+ atomic_inc(&ldops->refcount);
17774 ld->ops = ldops;
17775 err = 0;
17776 }
017d2877 17777@@ -195,8 +195,8 @@ static void tty_ldisc_put(struct tty_ldi
2380c486
JR
17778
17779 spin_lock_irqsave(&tty_ldisc_lock, flags);
17780 ld = tty_ldiscs[disc];
17781- BUG_ON(ld->refcount == 0);
17782- ld->refcount--;
17783+ BUG_ON(atomic_read(&ld->refcount) == 0);
17784+ atomic_dec(&ld->refcount);
17785 module_put(ld->owner);
17786 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
17787 }
017d2877 17788@@ -263,7 +263,7 @@ const struct file_operations tty_ldiscs_
2380c486
JR
17789
17790 static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
17791 {
17792- ld->refcount = 0;
17793+ atomic_set(&ld->refcount, 0);
17794 tty->ldisc = *ld;
17795 }
17796
017d2877 17797@@ -288,7 +288,7 @@ static int tty_ldisc_try(struct tty_stru
2380c486
JR
17798 spin_lock_irqsave(&tty_ldisc_lock, flags);
17799 ld = &tty->ldisc;
17800 if (test_bit(TTY_LDISC, &tty->flags)) {
17801- ld->refcount++;
17802+ atomic_inc(&ld->refcount);
17803 ret = 1;
17804 }
17805 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
017d2877 17806@@ -315,7 +315,7 @@ struct tty_ldisc *tty_ldisc_ref_wait(str
2380c486
JR
17807 {
17808 /* wait_event is a macro */
17809 wait_event(tty_ldisc_wait, tty_ldisc_try(tty));
17810- WARN_ON(tty->ldisc.refcount == 0);
17811+ WARN_ON(atomic_read(&tty->ldisc.refcount) == 0);
17812 return &tty->ldisc;
17813 }
17814
017d2877 17815@@ -358,11 +358,9 @@ void tty_ldisc_deref(struct tty_ldisc *l
2380c486
JR
17816 BUG_ON(ld == NULL);
17817
17818 spin_lock_irqsave(&tty_ldisc_lock, flags);
17819- if (ld->refcount == 0)
17820+ if (!atomic_add_unless(&ld->refcount, -1, 0))
17821 printk(KERN_ERR "tty_ldisc_deref: no references.\n");
17822- else
17823- ld->refcount--;
17824- if (ld->refcount == 0)
17825+ if (atomic_read(&ld->refcount) == 0)
17826 wake_up(&tty_ldisc_wait);
17827 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
17828 }
017d2877 17829@@ -506,8 +504,8 @@ restart:
2380c486
JR
17830 clear_bit(TTY_LDISC, &o_tty->flags);
17831
17832 spin_lock_irqsave(&tty_ldisc_lock, flags);
17833- if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) {
17834- if (tty->ldisc.refcount) {
17835+ if (atomic_read(&tty->ldisc.refcount) || (o_tty && atomic_read(&o_tty->ldisc.refcount))) {
17836+ if (atomic_read(&tty->ldisc.refcount)) {
17837 /* Free the new ldisc we grabbed. Must drop the lock
17838 first. */
17839 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
017d2877 17840@@ -519,14 +517,14 @@ restart:
2380c486
JR
17841 * and retries if we made tty_ldisc_wait() smarter.
17842 * That is up for discussion.
17843 */
17844- if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
17845+ if (wait_event_interruptible(tty_ldisc_wait, atomic_read(&tty->ldisc.refcount) == 0) < 0)
17846 return -ERESTARTSYS;
17847 goto restart;
17848 }
17849- if (o_tty && o_tty->ldisc.refcount) {
17850+ if (o_tty && atomic_read(&o_tty->ldisc.refcount)) {
17851 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
17852 tty_ldisc_put(o_tty->ldisc.ops);
17853- if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
17854+ if (wait_event_interruptible(tty_ldisc_wait, atomic_read(&o_tty->ldisc.refcount) == 0) < 0)
17855 return -ERESTARTSYS;
17856 goto restart;
17857 }
017d2877 17858@@ -669,9 +667,9 @@ void tty_ldisc_release(struct tty_struct
2380c486
JR
17859 * side is zero.
17860 */
17861 spin_lock_irqsave(&tty_ldisc_lock, flags);
17862- while (tty->ldisc.refcount) {
17863+ while (atomic_read(&tty->ldisc.refcount)) {
17864 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
17865- wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0);
17866+ wait_event(tty_ldisc_wait, atomic_read(&tty->ldisc.refcount) == 0);
17867 spin_lock_irqsave(&tty_ldisc_lock, flags);
17868 }
17869 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
017d2877
AM
17870diff -urNp linux-2.6.30.4/drivers/char/vt_ioctl.c linux-2.6.30.4/drivers/char/vt_ioctl.c
17871--- linux-2.6.30.4/drivers/char/vt_ioctl.c 2009-07-24 17:47:51.000000000 -0400
17872+++ linux-2.6.30.4/drivers/char/vt_ioctl.c 2009-07-30 11:10:49.002716445 -0400
2380c486
JR
17873@@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
17874 case KDSKBENT:
17875 if (!perm)
17876 return -EPERM;
17877+
17878+#ifdef CONFIG_GRKERNSEC
17879+ if (!capable(CAP_SYS_TTY_CONFIG))
17880+ return -EPERM;
17881+#endif
17882+
17883 if (!i && v == K_NOSUCHMAP) {
17884 /* deallocate map */
17885 key_map = key_maps[s];
17886@@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
17887 goto reterr;
17888 }
17889
17890+#ifdef CONFIG_GRKERNSEC
17891+ if (!capable(CAP_SYS_TTY_CONFIG)) {
17892+ ret = -EPERM;
17893+ goto reterr;
17894+ }
17895+#endif
17896+
17897 q = func_table[i];
17898 first_free = funcbufptr + (funcbufsize - funcbufleft);
17899 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
017d2877
AM
17900diff -urNp linux-2.6.30.4/drivers/char/xilinx_hwicap/xilinx_hwicap.c linux-2.6.30.4/drivers/char/xilinx_hwicap/xilinx_hwicap.c
17901--- linux-2.6.30.4/drivers/char/xilinx_hwicap/xilinx_hwicap.c 2009-07-24 17:47:51.000000000 -0400
17902+++ linux-2.6.30.4/drivers/char/xilinx_hwicap/xilinx_hwicap.c 2009-07-30 09:48:10.008436205 -0400
17903@@ -559,7 +559,7 @@ static int hwicap_release(struct inode *
17904 return status;
17905 }
17906
17907-static struct file_operations hwicap_fops = {
17908+static const struct file_operations hwicap_fops = {
17909 .owner = THIS_MODULE,
17910 .write = hwicap_write,
17911 .read = hwicap_read,
17912diff -urNp linux-2.6.30.4/drivers/edac/edac_core.h linux-2.6.30.4/drivers/edac/edac_core.h
17913--- linux-2.6.30.4/drivers/edac/edac_core.h 2009-07-24 17:47:51.000000000 -0400
17914+++ linux-2.6.30.4/drivers/edac/edac_core.h 2009-07-30 09:48:10.008436205 -0400
17915@@ -98,11 +98,11 @@ extern int edac_debug_level;
2380c486
JR
17916
17917 #else /* !CONFIG_EDAC_DEBUG */
17918
17919-#define debugf0( ... )
17920-#define debugf1( ... )
17921-#define debugf2( ... )
17922-#define debugf3( ... )
17923-#define debugf4( ... )
17924+#define debugf0( ... ) do {} while (0)
17925+#define debugf1( ... ) do {} while (0)
17926+#define debugf2( ... ) do {} while (0)
17927+#define debugf3( ... ) do {} while (0)
17928+#define debugf4( ... ) do {} while (0)
17929
17930 #endif /* !CONFIG_EDAC_DEBUG */
17931
017d2877
AM
17932diff -urNp linux-2.6.30.4/drivers/firmware/dmi_scan.c linux-2.6.30.4/drivers/firmware/dmi_scan.c
17933--- linux-2.6.30.4/drivers/firmware/dmi_scan.c 2009-07-24 17:47:51.000000000 -0400
17934+++ linux-2.6.30.4/drivers/firmware/dmi_scan.c 2009-07-30 09:48:10.009412825 -0400
17935@@ -391,11 +391,6 @@ void __init dmi_scan_machine(void)
2380c486
JR
17936 }
17937 }
17938 else {
17939- /*
17940- * no iounmap() for that ioremap(); it would be a no-op, but
17941- * it's so early in setup that sucker gets confused into doing
17942- * what it shouldn't if we actually call it.
17943- */
17944 p = dmi_ioremap(0xF0000, 0x10000);
17945 if (p == NULL)
17946 goto error;
017d2877
AM
17947diff -urNp linux-2.6.30.4/drivers/gpio/gpiolib.c linux-2.6.30.4/drivers/gpio/gpiolib.c
17948--- linux-2.6.30.4/drivers/gpio/gpiolib.c 2009-07-24 17:47:51.000000000 -0400
17949+++ linux-2.6.30.4/drivers/gpio/gpiolib.c 2009-07-30 09:48:10.009412825 -0400
17950@@ -1244,7 +1244,7 @@ static int gpiolib_open(struct inode *in
17951 return single_open(file, gpiolib_show, NULL);
17952 }
17953
17954-static struct file_operations gpiolib_operations = {
17955+static const struct file_operations gpiolib_operations = {
17956 .open = gpiolib_open,
17957 .read = seq_read,
17958 .llseek = seq_lseek,
17959diff -urNp linux-2.6.30.4/drivers/gpu/drm/drm_drv.c linux-2.6.30.4/drivers/gpu/drm/drm_drv.c
17960--- linux-2.6.30.4/drivers/gpu/drm/drm_drv.c 2009-07-24 17:47:51.000000000 -0400
17961+++ linux-2.6.30.4/drivers/gpu/drm/drm_drv.c 2009-07-30 09:48:10.010417819 -0400
17962@@ -425,7 +425,7 @@ int drm_ioctl(struct inode *inode, struc
de855c5d
AM
17963 char *kdata = NULL;
17964
17965 atomic_inc(&dev->ioctl_count);
17966- atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
17967+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_IOCTLS]);
17968 ++file_priv->ioctl_count;
17969
17970 DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
017d2877
AM
17971diff -urNp linux-2.6.30.4/drivers/gpu/drm/drm_fops.c linux-2.6.30.4/drivers/gpu/drm/drm_fops.c
17972--- linux-2.6.30.4/drivers/gpu/drm/drm_fops.c 2009-07-24 17:47:51.000000000 -0400
17973+++ linux-2.6.30.4/drivers/gpu/drm/drm_fops.c 2009-07-30 09:48:10.010417819 -0400
de855c5d
AM
17974@@ -130,9 +130,9 @@ int drm_open(struct inode *inode, struct
17975
17976 retcode = drm_open_helper(inode, filp, dev);
17977 if (!retcode) {
17978- atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
17979+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]);
17980 spin_lock(&dev->count_lock);
17981- if (!dev->open_count++) {
17982+ if (atomic_inc_return(&dev->open_count) == 1) {
17983 spin_unlock(&dev->count_lock);
17984 retcode = drm_setup(dev);
17985 goto out;
017d2877 17986@@ -433,7 +433,7 @@ int drm_release(struct inode *inode, str
de855c5d
AM
17987
17988 lock_kernel();
17989
17990- DRM_DEBUG("open_count = %d\n", dev->open_count);
17991+ DRM_DEBUG("open_count = %d\n", atomic_read(&dev->open_count));
17992
17993 if (dev->driver->preclose)
17994 dev->driver->preclose(dev, file_priv);
017d2877 17995@@ -445,7 +445,7 @@ int drm_release(struct inode *inode, str
de855c5d
AM
17996 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
17997 task_pid_nr(current),
17998 (long)old_encode_dev(file_priv->minor->device),
17999- dev->open_count);
18000+ atomic_read(&dev->open_count));
18001
18002 /* if the master has gone away we can't do anything with the lock */
18003 if (file_priv->minor->master)
017d2877 18004@@ -522,9 +522,9 @@ int drm_release(struct inode *inode, str
de855c5d
AM
18005 * End inline drm_release
18006 */
18007
18008- atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
18009+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_CLOSES]);
18010 spin_lock(&dev->count_lock);
18011- if (!--dev->open_count) {
18012+ if (atomic_dec_and_test(&dev->open_count)) {
18013 if (atomic_read(&dev->ioctl_count)) {
18014 DRM_ERROR("Device busy: %d\n",
18015 atomic_read(&dev->ioctl_count));
017d2877
AM
18016diff -urNp linux-2.6.30.4/drivers/gpu/drm/drm_lock.c linux-2.6.30.4/drivers/gpu/drm/drm_lock.c
18017--- linux-2.6.30.4/drivers/gpu/drm/drm_lock.c 2009-07-24 17:47:51.000000000 -0400
18018+++ linux-2.6.30.4/drivers/gpu/drm/drm_lock.c 2009-07-30 09:48:10.010417819 -0400
de855c5d
AM
18019@@ -87,7 +87,7 @@ int drm_lock(struct drm_device *dev, voi
18020 if (drm_lock_take(&master->lock, lock->context)) {
18021 master->lock.file_priv = file_priv;
18022 master->lock.lock_time = jiffies;
18023- atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
18024+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_LOCKS]);
18025 break; /* Got lock */
18026 }
18027
18028@@ -165,7 +165,7 @@ int drm_unlock(struct drm_device *dev, v
18029 return -EINVAL;
18030 }
18031
18032- atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
18033+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_UNLOCKS]);
18034
18035 /* kernel_context_switch isn't used by any of the x86 drm
18036 * modules but is required by the Sparc driver.
017d2877
AM
18037diff -urNp linux-2.6.30.4/drivers/gpu/drm/drm_vm.c linux-2.6.30.4/drivers/gpu/drm/drm_vm.c
18038--- linux-2.6.30.4/drivers/gpu/drm/drm_vm.c 2009-07-24 17:47:51.000000000 -0400
18039+++ linux-2.6.30.4/drivers/gpu/drm/drm_vm.c 2009-07-30 09:48:10.011410038 -0400
18040@@ -369,28 +369,28 @@ static int drm_vm_sg_fault(struct vm_are
18041 }
18042
18043 /** AGP virtual memory operations */
18044-static struct vm_operations_struct drm_vm_ops = {
18045+static const struct vm_operations_struct drm_vm_ops = {
18046 .fault = drm_vm_fault,
18047 .open = drm_vm_open,
18048 .close = drm_vm_close,
18049 };
18050
18051 /** Shared virtual memory operations */
18052-static struct vm_operations_struct drm_vm_shm_ops = {
18053+static const struct vm_operations_struct drm_vm_shm_ops = {
18054 .fault = drm_vm_shm_fault,
18055 .open = drm_vm_open,
18056 .close = drm_vm_shm_close,
18057 };
18058
18059 /** DMA virtual memory operations */
18060-static struct vm_operations_struct drm_vm_dma_ops = {
18061+static const struct vm_operations_struct drm_vm_dma_ops = {
18062 .fault = drm_vm_dma_fault,
18063 .open = drm_vm_open,
18064 .close = drm_vm_close,
18065 };
18066
18067 /** Scatter-gather virtual memory operations */
18068-static struct vm_operations_struct drm_vm_sg_ops = {
18069+static const struct vm_operations_struct drm_vm_sg_ops = {
18070 .fault = drm_vm_sg_fault,
18071 .open = drm_vm_open,
18072 .close = drm_vm_close,
18073diff -urNp linux-2.6.30.4/drivers/gpu/drm/i810/i810_dma.c linux-2.6.30.4/drivers/gpu/drm/i810/i810_dma.c
18074--- linux-2.6.30.4/drivers/gpu/drm/i810/i810_dma.c 2009-07-24 17:47:51.000000000 -0400
18075+++ linux-2.6.30.4/drivers/gpu/drm/i810/i810_dma.c 2009-07-30 09:48:10.011410038 -0400
de855c5d
AM
18076@@ -954,8 +954,8 @@ static int i810_dma_vertex(struct drm_de
18077 dma->buflist[vertex->idx],
18078 vertex->discard, vertex->used);
18079
18080- atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
18081- atomic_inc(&dev->counts[_DRM_STAT_DMA]);
18082+ atomic_add_unchecked(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
18083+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]);
18084 sarea_priv->last_enqueue = dev_priv->counter - 1;
18085 sarea_priv->last_dispatch = (int)hw_status[5];
18086
18087@@ -1117,8 +1117,8 @@ static int i810_dma_mc(struct drm_device
18088 i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used,
18089 mc->last_render);
18090
18091- atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
18092- atomic_inc(&dev->counts[_DRM_STAT_DMA]);
18093+ atomic_add_unchecked(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
18094+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]);
18095 sarea_priv->last_enqueue = dev_priv->counter - 1;
18096 sarea_priv->last_dispatch = (int)hw_status[5];
18097
017d2877
AM
18098diff -urNp linux-2.6.30.4/drivers/gpu/drm/i915/i915_drv.c linux-2.6.30.4/drivers/gpu/drm/i915/i915_drv.c
18099--- linux-2.6.30.4/drivers/gpu/drm/i915/i915_drv.c 2009-07-24 17:47:51.000000000 -0400
18100+++ linux-2.6.30.4/drivers/gpu/drm/i915/i915_drv.c 2009-07-30 12:07:09.579971370 -0400
18101@@ -149,7 +149,7 @@ i915_pci_resume(struct pci_dev *pdev)
18102 return i915_resume(dev);
18103 }
18104
18105-static struct vm_operations_struct i915_gem_vm_ops = {
18106+static const struct vm_operations_struct i915_gem_vm_ops = {
18107 .fault = i915_gem_fault,
18108 .open = drm_gem_vm_open,
18109 .close = drm_gem_vm_close,
18110diff -urNp linux-2.6.30.4/drivers/hwmon/fschmd.c linux-2.6.30.4/drivers/hwmon/fschmd.c
18111--- linux-2.6.30.4/drivers/hwmon/fschmd.c 2009-07-24 17:47:51.000000000 -0400
18112+++ linux-2.6.30.4/drivers/hwmon/fschmd.c 2009-07-30 09:48:10.011410038 -0400
18113@@ -915,7 +915,7 @@ static int watchdog_ioctl(struct inode *
18114 return ret;
18115 }
18116
18117-static struct file_operations watchdog_fops = {
18118+static const struct file_operations watchdog_fops = {
18119 .owner = THIS_MODULE,
18120 .llseek = no_llseek,
18121 .open = watchdog_open,
18122diff -urNp linux-2.6.30.4/drivers/hwmon/fscpos.c linux-2.6.30.4/drivers/hwmon/fscpos.c
18123--- linux-2.6.30.4/drivers/hwmon/fscpos.c 2009-07-24 17:47:51.000000000 -0400
18124+++ linux-2.6.30.4/drivers/hwmon/fscpos.c 2009-07-30 09:48:10.015465337 -0400
2380c486
JR
18125@@ -240,7 +240,6 @@ static ssize_t set_pwm(struct i2c_client
18126 unsigned long v = simple_strtoul(buf, NULL, 10);
18127
18128 /* Range: 0..255 */
18129- if (v < 0) v = 0;
18130 if (v > 255) v = 255;
18131
18132 mutex_lock(&data->update_lock);
017d2877
AM
18133diff -urNp linux-2.6.30.4/drivers/hwmon/k8temp.c linux-2.6.30.4/drivers/hwmon/k8temp.c
18134--- linux-2.6.30.4/drivers/hwmon/k8temp.c 2009-07-24 17:47:51.000000000 -0400
18135+++ linux-2.6.30.4/drivers/hwmon/k8temp.c 2009-07-30 09:48:10.016410845 -0400
2380c486
JR
18136@@ -138,7 +138,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
18137
18138 static struct pci_device_id k8temp_ids[] = {
18139 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
18140- { 0 },
18141+ { 0, 0, 0, 0, 0, 0, 0 },
18142 };
18143
18144 MODULE_DEVICE_TABLE(pci, k8temp_ids);
017d2877
AM
18145diff -urNp linux-2.6.30.4/drivers/hwmon/sis5595.c linux-2.6.30.4/drivers/hwmon/sis5595.c
18146--- linux-2.6.30.4/drivers/hwmon/sis5595.c 2009-07-24 17:47:51.000000000 -0400
18147+++ linux-2.6.30.4/drivers/hwmon/sis5595.c 2009-07-30 09:48:10.016410845 -0400
2380c486
JR
18148@@ -699,7 +699,7 @@ static struct sis5595_data *sis5595_upda
18149
18150 static struct pci_device_id sis5595_pci_ids[] = {
18151 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
18152- { 0, }
18153+ { 0, 0, 0, 0, 0, 0, 0 }
18154 };
18155
18156 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
017d2877
AM
18157diff -urNp linux-2.6.30.4/drivers/hwmon/via686a.c linux-2.6.30.4/drivers/hwmon/via686a.c
18158--- linux-2.6.30.4/drivers/hwmon/via686a.c 2009-07-24 17:47:51.000000000 -0400
18159+++ linux-2.6.30.4/drivers/hwmon/via686a.c 2009-07-30 09:48:10.016410845 -0400
2380c486
JR
18160@@ -769,7 +769,7 @@ static struct via686a_data *via686a_upda
18161
18162 static struct pci_device_id via686a_pci_ids[] = {
18163 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
18164- { 0, }
18165+ { 0, 0, 0, 0, 0, 0, 0 }
18166 };
18167
18168 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
017d2877
AM
18169diff -urNp linux-2.6.30.4/drivers/hwmon/vt8231.c linux-2.6.30.4/drivers/hwmon/vt8231.c
18170--- linux-2.6.30.4/drivers/hwmon/vt8231.c 2009-07-24 17:47:51.000000000 -0400
18171+++ linux-2.6.30.4/drivers/hwmon/vt8231.c 2009-07-30 09:48:10.017409539 -0400
2380c486
JR
18172@@ -699,7 +699,7 @@ static struct platform_driver vt8231_dri
18173
18174 static struct pci_device_id vt8231_pci_ids[] = {
18175 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
18176- { 0, }
18177+ { 0, 0, 0, 0, 0, 0, 0 }
18178 };
18179
18180 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
017d2877
AM
18181diff -urNp linux-2.6.30.4/drivers/hwmon/w83791d.c linux-2.6.30.4/drivers/hwmon/w83791d.c
18182--- linux-2.6.30.4/drivers/hwmon/w83791d.c 2009-07-24 17:47:51.000000000 -0400
18183+++ linux-2.6.30.4/drivers/hwmon/w83791d.c 2009-07-30 09:48:10.017409539 -0400
2380c486
JR
18184@@ -330,8 +330,8 @@ static int w83791d_detect(struct i2c_cli
18185 struct i2c_board_info *info);
18186 static int w83791d_remove(struct i2c_client *client);
18187
18188-static int w83791d_read(struct i2c_client *client, u8 register);
18189-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
18190+static int w83791d_read(struct i2c_client *client, u8 reg);
18191+static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
18192 static struct w83791d_data *w83791d_update_device(struct device *dev);
18193
18194 #ifdef DEBUG
017d2877
AM
18195diff -urNp linux-2.6.30.4/drivers/i2c/busses/i2c-i801.c linux-2.6.30.4/drivers/i2c/busses/i2c-i801.c
18196--- linux-2.6.30.4/drivers/i2c/busses/i2c-i801.c 2009-07-24 17:47:51.000000000 -0400
18197+++ linux-2.6.30.4/drivers/i2c/busses/i2c-i801.c 2009-07-30 09:48:10.018424106 -0400
18198@@ -578,7 +578,7 @@ static struct pci_device_id i801_ids[] =
2380c486
JR
18199 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
18200 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
18201 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH_SMBUS) },
18202- { 0, }
18203+ { 0, 0, 0, 0, 0, 0, 0 }
18204 };
18205
18206 MODULE_DEVICE_TABLE (pci, i801_ids);
017d2877
AM
18207diff -urNp linux-2.6.30.4/drivers/i2c/busses/i2c-piix4.c linux-2.6.30.4/drivers/i2c/busses/i2c-piix4.c
18208--- linux-2.6.30.4/drivers/i2c/busses/i2c-piix4.c 2009-07-24 17:47:51.000000000 -0400
18209+++ linux-2.6.30.4/drivers/i2c/busses/i2c-piix4.c 2009-07-30 09:48:10.018424106 -0400
2380c486
JR
18210@@ -123,7 +123,7 @@ static struct dmi_system_id __devinitdat
18211 .ident = "IBM",
18212 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
18213 },
18214- { },
18215+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
18216 };
18217
18218 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
017d2877 18219@@ -489,7 +489,7 @@ static struct pci_device_id piix4_ids[]
2380c486 18220 PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
017d2877
AM
18221 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
18222 PCI_DEVICE_ID_SERVERWORKS_HT1100LD) },
2380c486
JR
18223- { 0, }
18224+ { 0, 0, 0, 0, 0, 0, 0 }
18225 };
18226
18227 MODULE_DEVICE_TABLE (pci, piix4_ids);
017d2877
AM
18228diff -urNp linux-2.6.30.4/drivers/i2c/busses/i2c-sis630.c linux-2.6.30.4/drivers/i2c/busses/i2c-sis630.c
18229--- linux-2.6.30.4/drivers/i2c/busses/i2c-sis630.c 2009-07-24 17:47:51.000000000 -0400
18230+++ linux-2.6.30.4/drivers/i2c/busses/i2c-sis630.c 2009-07-30 09:48:10.018424106 -0400
2380c486
JR
18231@@ -471,7 +471,7 @@ static struct i2c_adapter sis630_adapter
18232 static struct pci_device_id sis630_ids[] __devinitdata = {
18233 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
18234 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
18235- { 0, }
18236+ { 0, 0, 0, 0, 0, 0, 0 }
18237 };
18238
18239 MODULE_DEVICE_TABLE (pci, sis630_ids);
017d2877
AM
18240diff -urNp linux-2.6.30.4/drivers/i2c/busses/i2c-sis96x.c linux-2.6.30.4/drivers/i2c/busses/i2c-sis96x.c
18241--- linux-2.6.30.4/drivers/i2c/busses/i2c-sis96x.c 2009-07-24 17:47:51.000000000 -0400
18242+++ linux-2.6.30.4/drivers/i2c/busses/i2c-sis96x.c 2009-07-30 09:48:10.018424106 -0400
2380c486
JR
18243@@ -247,7 +247,7 @@ static struct i2c_adapter sis96x_adapter
18244
18245 static struct pci_device_id sis96x_ids[] = {
18246 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
18247- { 0, }
18248+ { 0, 0, 0, 0, 0, 0, 0 }
18249 };
18250
18251 MODULE_DEVICE_TABLE (pci, sis96x_ids);
017d2877
AM
18252diff -urNp linux-2.6.30.4/drivers/ieee1394/dma.c linux-2.6.30.4/drivers/ieee1394/dma.c
18253--- linux-2.6.30.4/drivers/ieee1394/dma.c 2009-07-24 17:47:51.000000000 -0400
18254+++ linux-2.6.30.4/drivers/ieee1394/dma.c 2009-07-30 09:48:10.018424106 -0400
18255@@ -247,7 +247,7 @@ static int dma_region_pagefault(struct v
18256 return 0;
18257 }
18258
18259-static struct vm_operations_struct dma_region_vm_ops = {
18260+static const struct vm_operations_struct dma_region_vm_ops = {
18261 .fault = dma_region_pagefault,
18262 };
18263
18264diff -urNp linux-2.6.30.4/drivers/ieee1394/dv1394.c linux-2.6.30.4/drivers/ieee1394/dv1394.c
18265--- linux-2.6.30.4/drivers/ieee1394/dv1394.c 2009-07-24 17:47:51.000000000 -0400
18266+++ linux-2.6.30.4/drivers/ieee1394/dv1394.c 2009-07-30 09:48:10.020336753 -0400
2380c486
JR
18267@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
18268 based upon DIF section and sequence
18269 */
18270
18271-static void inline
18272+static inline void
18273 frame_put_packet (struct frame *f, struct packet *p)
18274 {
18275 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
017d2877 18276@@ -2177,7 +2177,7 @@ static const struct ieee1394_device_id d
2380c486
JR
18277 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
18278 .version = AVC_SW_VERSION_ENTRY & 0xffffff
18279 },
18280- { }
18281+ { 0, 0, 0, 0, 0, 0 }
18282 };
18283
18284 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
017d2877
AM
18285diff -urNp linux-2.6.30.4/drivers/ieee1394/eth1394.c linux-2.6.30.4/drivers/ieee1394/eth1394.c
18286--- linux-2.6.30.4/drivers/ieee1394/eth1394.c 2009-07-24 17:47:51.000000000 -0400
18287+++ linux-2.6.30.4/drivers/ieee1394/eth1394.c 2009-07-30 09:48:10.020336753 -0400
18288@@ -445,7 +445,7 @@ static const struct ieee1394_device_id e
2380c486
JR
18289 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
18290 .version = ETHER1394_GASP_VERSION,
18291 },
18292- {}
18293+ { 0, 0, 0, 0, 0, 0 }
18294 };
18295
18296 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
017d2877
AM
18297diff -urNp linux-2.6.30.4/drivers/ieee1394/hosts.c linux-2.6.30.4/drivers/ieee1394/hosts.c
18298--- linux-2.6.30.4/drivers/ieee1394/hosts.c 2009-07-24 17:47:51.000000000 -0400
18299+++ linux-2.6.30.4/drivers/ieee1394/hosts.c 2009-07-30 09:48:10.020336753 -0400
2380c486
JR
18300@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
18301 }
18302
18303 static struct hpsb_host_driver dummy_driver = {
18304+ .name = "dummy",
18305 .transmit_packet = dummy_transmit_packet,
18306 .devctl = dummy_devctl,
18307 .isoctl = dummy_isoctl
017d2877
AM
18308diff -urNp linux-2.6.30.4/drivers/ieee1394/ohci1394.c linux-2.6.30.4/drivers/ieee1394/ohci1394.c
18309--- linux-2.6.30.4/drivers/ieee1394/ohci1394.c 2009-07-24 17:47:51.000000000 -0400
18310+++ linux-2.6.30.4/drivers/ieee1394/ohci1394.c 2009-07-30 09:48:10.020862787 -0400
2380c486
JR
18311@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
18312 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
18313
18314 /* Module Parameters */
18315-static int phys_dma = 1;
18316+static int phys_dma;
18317 module_param(phys_dma, int, 0444);
18318-MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
18319+MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
18320
18321 static void dma_trm_tasklet(unsigned long data);
18322 static void dma_trm_reset(struct dma_trm_ctx *d);
18323@@ -3449,7 +3449,7 @@ static struct pci_device_id ohci1394_pci
18324 .subvendor = PCI_ANY_ID,
18325 .subdevice = PCI_ANY_ID,
18326 },
18327- { 0, },
18328+ { 0, 0, 0, 0, 0, 0, 0 },
18329 };
18330
18331 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
017d2877
AM
18332diff -urNp linux-2.6.30.4/drivers/ieee1394/raw1394.c linux-2.6.30.4/drivers/ieee1394/raw1394.c
18333--- linux-2.6.30.4/drivers/ieee1394/raw1394.c 2009-07-24 17:47:51.000000000 -0400
18334+++ linux-2.6.30.4/drivers/ieee1394/raw1394.c 2009-07-30 09:48:10.022270946 -0400
18335@@ -2999,7 +2999,7 @@ static const struct ieee1394_device_id r
2380c486
JR
18336 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
18337 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
18338 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
18339- {}
18340+ { 0, 0, 0, 0, 0, 0 }
18341 };
18342
18343 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
017d2877
AM
18344diff -urNp linux-2.6.30.4/drivers/ieee1394/sbp2.c linux-2.6.30.4/drivers/ieee1394/sbp2.c
18345--- linux-2.6.30.4/drivers/ieee1394/sbp2.c 2009-07-24 17:47:51.000000000 -0400
18346+++ linux-2.6.30.4/drivers/ieee1394/sbp2.c 2009-07-30 09:48:10.022270946 -0400
18347@@ -290,7 +290,7 @@ static const struct ieee1394_device_id s
2380c486
JR
18348 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
18349 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
18350 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
18351- {}
18352+ { 0, 0, 0, 0, 0, 0 }
18353 };
18354 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
18355
017d2877 18356@@ -2111,7 +2111,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
2380c486
JR
18357 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
18358 MODULE_LICENSE("GPL");
18359
18360-static int sbp2_module_init(void)
18361+static int __init sbp2_module_init(void)
18362 {
18363 int ret;
18364
017d2877
AM
18365diff -urNp linux-2.6.30.4/drivers/ieee1394/video1394.c linux-2.6.30.4/drivers/ieee1394/video1394.c
18366--- linux-2.6.30.4/drivers/ieee1394/video1394.c 2009-07-24 17:47:51.000000000 -0400
18367+++ linux-2.6.30.4/drivers/ieee1394/video1394.c 2009-07-30 09:48:10.022535006 -0400
18368@@ -1310,7 +1310,7 @@ static const struct ieee1394_device_id v
2380c486
JR
18369 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
18370 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
18371 },
18372- { }
18373+ { 0, 0, 0, 0, 0, 0 }
18374 };
18375
18376 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
017d2877
AM
18377diff -urNp linux-2.6.30.4/drivers/infiniband/hw/ehca/ehca_uverbs.c linux-2.6.30.4/drivers/infiniband/hw/ehca/ehca_uverbs.c
18378--- linux-2.6.30.4/drivers/infiniband/hw/ehca/ehca_uverbs.c 2009-07-24 17:47:51.000000000 -0400
18379+++ linux-2.6.30.4/drivers/infiniband/hw/ehca/ehca_uverbs.c 2009-07-30 09:48:10.023536535 -0400
18380@@ -95,7 +95,7 @@ static void ehca_mm_close(struct vm_area
18381 vma->vm_start, vma->vm_end, *count);
18382 }
18383
18384-static struct vm_operations_struct vm_ops = {
18385+static const struct vm_operations_struct vm_ops = {
18386 .open = ehca_mm_open,
18387 .close = ehca_mm_close,
18388 };
18389diff -urNp linux-2.6.30.4/drivers/infiniband/hw/ipath/ipath_file_ops.c linux-2.6.30.4/drivers/infiniband/hw/ipath/ipath_file_ops.c
18390--- linux-2.6.30.4/drivers/infiniband/hw/ipath/ipath_file_ops.c 2009-07-24 17:47:51.000000000 -0400
18391+++ linux-2.6.30.4/drivers/infiniband/hw/ipath/ipath_file_ops.c 2009-07-30 09:48:10.023536535 -0400
18392@@ -1151,7 +1151,7 @@ static int ipath_file_vma_fault(struct v
18393 return 0;
18394 }
18395
18396-static struct vm_operations_struct ipath_file_vm_ops = {
18397+static const struct vm_operations_struct ipath_file_vm_ops = {
18398 .fault = ipath_file_vma_fault,
18399 };
18400
18401diff -urNp linux-2.6.30.4/drivers/infiniband/hw/ipath/ipath_mmap.c linux-2.6.30.4/drivers/infiniband/hw/ipath/ipath_mmap.c
18402--- linux-2.6.30.4/drivers/infiniband/hw/ipath/ipath_mmap.c 2009-07-24 17:47:51.000000000 -0400
18403+++ linux-2.6.30.4/drivers/infiniband/hw/ipath/ipath_mmap.c 2009-07-30 09:48:10.024683962 -0400
18404@@ -74,7 +74,7 @@ static void ipath_vma_close(struct vm_ar
18405 kref_put(&ip->ref, ipath_release_mmap_info);
18406 }
18407
18408-static struct vm_operations_struct ipath_vm_ops = {
18409+static const struct vm_operations_struct ipath_vm_ops = {
18410 .open = ipath_vma_open,
18411 .close = ipath_vma_close,
18412 };
18413diff -urNp linux-2.6.30.4/drivers/input/keyboard/atkbd.c linux-2.6.30.4/drivers/input/keyboard/atkbd.c
18414--- linux-2.6.30.4/drivers/input/keyboard/atkbd.c 2009-07-24 17:47:51.000000000 -0400
18415+++ linux-2.6.30.4/drivers/input/keyboard/atkbd.c 2009-07-30 09:48:10.024683962 -0400
de855c5d 18416@@ -1166,7 +1166,7 @@ static struct serio_device_id atkbd_seri
2380c486
JR
18417 .id = SERIO_ANY,
18418 .extra = SERIO_ANY,
18419 },
18420- { 0 }
18421+ { 0, 0, 0, 0 }
18422 };
18423
18424 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
017d2877
AM
18425diff -urNp linux-2.6.30.4/drivers/input/mouse/lifebook.c linux-2.6.30.4/drivers/input/mouse/lifebook.c
18426--- linux-2.6.30.4/drivers/input/mouse/lifebook.c 2009-07-24 17:47:51.000000000 -0400
18427+++ linux-2.6.30.4/drivers/input/mouse/lifebook.c 2009-07-30 09:48:10.025535593 -0400
18428@@ -116,7 +116,7 @@ static const struct dmi_system_id lifebo
2380c486
JR
18429 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
18430 },
18431 },
18432- { }
18433+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}
18434 };
18435
18436 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
017d2877
AM
18437diff -urNp linux-2.6.30.4/drivers/input/mouse/psmouse-base.c linux-2.6.30.4/drivers/input/mouse/psmouse-base.c
18438--- linux-2.6.30.4/drivers/input/mouse/psmouse-base.c 2009-07-24 17:47:51.000000000 -0400
18439+++ linux-2.6.30.4/drivers/input/mouse/psmouse-base.c 2009-07-30 09:48:10.025535593 -0400
2380c486
JR
18440@@ -1378,7 +1378,7 @@ static struct serio_device_id psmouse_se
18441 .id = SERIO_ANY,
18442 .extra = SERIO_ANY,
18443 },
18444- { 0 }
18445+ { 0, 0, 0, 0 }
18446 };
18447
18448 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
017d2877
AM
18449diff -urNp linux-2.6.30.4/drivers/input/mouse/synaptics.c linux-2.6.30.4/drivers/input/mouse/synaptics.c
18450--- linux-2.6.30.4/drivers/input/mouse/synaptics.c 2009-07-24 17:47:51.000000000 -0400
18451+++ linux-2.6.30.4/drivers/input/mouse/synaptics.c 2009-07-30 09:48:10.026633372 -0400
2380c486
JR
18452@@ -412,7 +412,7 @@ static void synaptics_process_packet(str
18453 break;
18454 case 2:
18455 if (SYN_MODEL_PEN(priv->model_id))
18456- ; /* Nothing, treat a pen as a single finger */
18457+ break; /* Nothing, treat a pen as a single finger */
18458 break;
18459 case 4 ... 15:
18460 if (SYN_CAP_PALMDETECT(priv->capabilities))
18461@@ -625,7 +625,7 @@ static const struct dmi_system_id toshib
18462 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
18463 },
18464 },
18465- { }
18466+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
18467 };
18468 #endif
18469
017d2877
AM
18470diff -urNp linux-2.6.30.4/drivers/input/mousedev.c linux-2.6.30.4/drivers/input/mousedev.c
18471--- linux-2.6.30.4/drivers/input/mousedev.c 2009-07-24 17:47:51.000000000 -0400
18472+++ linux-2.6.30.4/drivers/input/mousedev.c 2009-07-30 09:48:10.026633372 -0400
18473@@ -1059,7 +1059,7 @@ static struct input_handler mousedev_han
2380c486
JR
18474
18475 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
18476 static struct miscdevice psaux_mouse = {
18477- PSMOUSE_MINOR, "psaux", &mousedev_fops
18478+ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
18479 };
18480 static int psaux_registered;
18481 #endif
017d2877
AM
18482diff -urNp linux-2.6.30.4/drivers/input/serio/i8042-x86ia64io.h linux-2.6.30.4/drivers/input/serio/i8042-x86ia64io.h
18483--- linux-2.6.30.4/drivers/input/serio/i8042-x86ia64io.h 2009-07-24 17:47:51.000000000 -0400
18484+++ linux-2.6.30.4/drivers/input/serio/i8042-x86ia64io.h 2009-07-30 09:48:10.027427071 -0400
18485@@ -159,7 +159,7 @@ static struct dmi_system_id __initdata i
18486 DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
2380c486
JR
18487 },
18488 },
18489- { }
18490+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
18491 };
18492
18493 /*
017d2877 18494@@ -374,7 +374,7 @@ static struct dmi_system_id __initdata i
2380c486
JR
18495 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
18496 },
18497 },
18498- { }
18499+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
18500 };
18501
017d2877
AM
18502 static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
18503@@ -392,7 +392,7 @@ static struct dmi_system_id __initdata i
18504 DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
18505 },
18506 },
18507- { }
18508+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
18509 };
18510
2380c486 18511 #ifdef CONFIG_PNP
017d2877
AM
18512@@ -411,7 +411,7 @@ static struct dmi_system_id __initdata i
18513 DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
2380c486
JR
18514 },
18515 },
18516- { }
18517+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
18518 };
18519 #endif
18520
017d2877 18521@@ -478,7 +478,7 @@ static struct dmi_system_id __initdata i
2380c486
JR
18522 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
18523 },
18524 },
18525- { }
18526+ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL }
18527 };
18528
18529 #endif /* CONFIG_X86 */
017d2877
AM
18530diff -urNp linux-2.6.30.4/drivers/input/serio/serio_raw.c linux-2.6.30.4/drivers/input/serio/serio_raw.c
18531--- linux-2.6.30.4/drivers/input/serio/serio_raw.c 2009-07-24 17:47:51.000000000 -0400
18532+++ linux-2.6.30.4/drivers/input/serio/serio_raw.c 2009-07-30 09:48:10.027427071 -0400
18533@@ -376,7 +376,7 @@ static struct serio_device_id serio_raw_
2380c486
JR
18534 .id = SERIO_ANY,
18535 .extra = SERIO_ANY,
18536 },
18537- { 0 }
18538+ { 0, 0, 0, 0 }
18539 };
18540
18541 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
017d2877
AM
18542diff -urNp linux-2.6.30.4/drivers/isdn/capi/kcapi_proc.c linux-2.6.30.4/drivers/isdn/capi/kcapi_proc.c
18543--- linux-2.6.30.4/drivers/isdn/capi/kcapi_proc.c 2009-07-24 17:47:51.000000000 -0400
18544+++ linux-2.6.30.4/drivers/isdn/capi/kcapi_proc.c 2009-07-30 09:48:10.027427071 -0400
18545@@ -89,14 +89,14 @@ static int contrstats_show(struct seq_fi
18546 return 0;
18547 }
18548
18549-static struct seq_operations seq_controller_ops = {
18550+static const struct seq_operations seq_controller_ops = {
18551 .start = controller_start,
18552 .next = controller_next,
18553 .stop = controller_stop,
18554 .show = controller_show,
18555 };
18556
18557-static struct seq_operations seq_contrstats_ops = {
18558+static const struct seq_operations seq_contrstats_ops = {
18559 .start = controller_start,
18560 .next = controller_next,
18561 .stop = controller_stop,
18562@@ -194,14 +194,14 @@ applstats_show(struct seq_file *seq, voi
18563 return 0;
18564 }
18565
18566-static struct seq_operations seq_applications_ops = {
18567+static const struct seq_operations seq_applications_ops = {
18568 .start = applications_start,
18569 .next = applications_next,
18570 .stop = applications_stop,
18571 .show = applications_show,
18572 };
18573
18574-static struct seq_operations seq_applstats_ops = {
18575+static const struct seq_operations seq_applstats_ops = {
18576 .start = applications_start,
18577 .next = applications_next,
18578 .stop = applications_stop,
18579@@ -264,7 +264,7 @@ static int capi_driver_show(struct seq_f
18580 return 0;
18581 }
18582
18583-static struct seq_operations seq_capi_driver_ops = {
18584+static const struct seq_operations seq_capi_driver_ops = {
18585 .start = capi_driver_start,
18586 .next = capi_driver_next,
18587 .stop = capi_driver_stop,
18588diff -urNp linux-2.6.30.4/drivers/isdn/mISDN/timerdev.c linux-2.6.30.4/drivers/isdn/mISDN/timerdev.c
18589--- linux-2.6.30.4/drivers/isdn/mISDN/timerdev.c 2009-07-24 17:47:51.000000000 -0400
18590+++ linux-2.6.30.4/drivers/isdn/mISDN/timerdev.c 2009-07-30 09:48:10.028469662 -0400
18591@@ -259,7 +259,7 @@ mISDN_ioctl(struct inode *inode, struct
18592 return ret;
18593 }
18594
18595-static struct file_operations mISDN_fops = {
18596+static const struct file_operations mISDN_fops = {
18597 .read = mISDN_read,
18598 .poll = mISDN_poll,
18599 .ioctl = mISDN_ioctl,
18600diff -urNp linux-2.6.30.4/drivers/lguest/core.c linux-2.6.30.4/drivers/lguest/core.c
18601--- linux-2.6.30.4/drivers/lguest/core.c 2009-07-24 17:47:51.000000000 -0400
18602+++ linux-2.6.30.4/drivers/lguest/core.c 2009-07-30 09:48:10.028469662 -0400
2380c486
JR
18603@@ -80,9 +80,17 @@ static __init int map_switcher(void)
18604 * (SWITCHER_ADDR). We might not get it in theory, but in practice
18605 * it's worked so far. The end address needs +1 because __get_vm_area
18606 * allocates an extra guard page, so we need space for that. */
18607+
18608+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
18609+ switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
18610+ VM_ALLOC | VM_KERNEXEC, SWITCHER_ADDR, SWITCHER_ADDR
18611+ + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
18612+#else
18613 switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE,
18614 VM_ALLOC, SWITCHER_ADDR, SWITCHER_ADDR
18615 + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE);
18616+#endif
18617+
18618 if (!switcher_vma) {
18619 err = -ENOMEM;
18620 printk("lguest: could not map switcher pages high\n");
017d2877
AM
18621diff -urNp linux-2.6.30.4/drivers/lguest/lguest_user.c linux-2.6.30.4/drivers/lguest/lguest_user.c
18622--- linux-2.6.30.4/drivers/lguest/lguest_user.c 2009-07-24 17:47:51.000000000 -0400
18623+++ linux-2.6.30.4/drivers/lguest/lguest_user.c 2009-07-30 09:48:10.028469662 -0400
18624@@ -329,7 +329,7 @@ static int close(struct inode *inode, st
18625 * We begin our understanding with the Host kernel interface which the Launcher
18626 * uses: reading and writing a character device called /dev/lguest. All the
18627 * work happens in the read(), write() and close() routines: */
18628-static struct file_operations lguest_fops = {
18629+static const struct file_operations lguest_fops = {
18630 .owner = THIS_MODULE,
18631 .release = close,
18632 .write = write,
18633diff -urNp linux-2.6.30.4/drivers/md/bitmap.c linux-2.6.30.4/drivers/md/bitmap.c
18634--- linux-2.6.30.4/drivers/md/bitmap.c 2009-07-24 17:47:51.000000000 -0400
18635+++ linux-2.6.30.4/drivers/md/bitmap.c 2009-07-30 09:48:10.029590223 -0400
18636@@ -58,7 +58,7 @@
2380c486
JR
18637 # if DEBUG > 0
18638 # define PRINTK(x...) printk(KERN_DEBUG x)
18639 # else
18640-# define PRINTK(x...)
18641+# define PRINTK(x...) do {} while (0)
18642 # endif
18643 #endif
18644
017d2877
AM
18645diff -urNp linux-2.6.30.4/drivers/md/md.c linux-2.6.30.4/drivers/md/md.c
18646--- linux-2.6.30.4/drivers/md/md.c 2009-07-24 17:47:51.000000000 -0400
18647+++ linux-2.6.30.4/drivers/md/md.c 2009-07-30 09:48:10.031075937 -0400
18648@@ -5973,7 +5973,7 @@ static int md_seq_show(struct seq_file *
2380c486
JR
18649 chunk_kb ? "KB" : "B");
18650 if (bitmap->file) {
18651 seq_printf(seq, ", file: ");
18652- seq_path(seq, &bitmap->file->f_path, " \t\n");
18653+ seq_path(seq, &bitmap->file->f_path, " \t\n\\");
18654 }
18655
18656 seq_printf(seq, "\n");
017d2877
AM
18657diff -urNp linux-2.6.30.4/drivers/md/md.h linux-2.6.30.4/drivers/md/md.h
18658--- linux-2.6.30.4/drivers/md/md.h 2009-07-24 17:47:51.000000000 -0400
18659+++ linux-2.6.30.4/drivers/md/md.h 2009-07-30 09:48:10.031075937 -0400
18660@@ -299,7 +299,7 @@ static inline void rdev_dec_pending(mdk_
18661
18662 static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sectors)
18663 {
18664- atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
18665+ atomic_add_unchecked(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
18666 }
18667
18668 struct mdk_personality
18669diff -urNp linux-2.6.30.4/drivers/media/dvb/dvb-core/dmxdev.c linux-2.6.30.4/drivers/media/dvb/dvb-core/dmxdev.c
18670--- linux-2.6.30.4/drivers/media/dvb/dvb-core/dmxdev.c 2009-07-24 17:47:51.000000000 -0400
18671+++ linux-2.6.30.4/drivers/media/dvb/dvb-core/dmxdev.c 2009-07-30 12:06:52.108842402 -0400
18672@@ -1092,7 +1092,7 @@ static unsigned int dvb_dvr_poll(struct
18673 return mask;
18674 }
18675
18676-static struct file_operations dvb_dvr_fops = {
18677+static const struct file_operations dvb_dvr_fops = {
18678 .owner = THIS_MODULE,
18679 .read = dvb_dvr_read,
18680 .write = dvb_dvr_write,
18681diff -urNp linux-2.6.30.4/drivers/media/dvb/firewire/firedtv-ci.c linux-2.6.30.4/drivers/media/dvb/firewire/firedtv-ci.c
18682--- linux-2.6.30.4/drivers/media/dvb/firewire/firedtv-ci.c 2009-07-24 17:47:51.000000000 -0400
18683+++ linux-2.6.30.4/drivers/media/dvb/firewire/firedtv-ci.c 2009-07-30 12:06:52.110732547 -0400
18684@@ -215,7 +215,7 @@ static unsigned int fdtv_ca_io_poll(stru
18685 return POLLIN;
18686 }
18687
18688-static struct file_operations fdtv_ca_fops = {
18689+static const struct file_operations fdtv_ca_fops = {
18690 .owner = THIS_MODULE,
18691 .ioctl = dvb_generic_ioctl,
18692 .open = dvb_generic_open,
18693diff -urNp linux-2.6.30.4/drivers/media/video/cafe_ccic.c linux-2.6.30.4/drivers/media/video/cafe_ccic.c
18694--- linux-2.6.30.4/drivers/media/video/cafe_ccic.c 2009-07-24 17:47:51.000000000 -0400
18695+++ linux-2.6.30.4/drivers/media/video/cafe_ccic.c 2009-07-30 09:48:10.031530096 -0400
18696@@ -1326,7 +1326,7 @@ static void cafe_v4l_vm_close(struct vm_
18697 mutex_unlock(&sbuf->cam->s_mutex);
18698 }
18699
18700-static struct vm_operations_struct cafe_v4l_vm_ops = {
18701+static const struct vm_operations_struct cafe_v4l_vm_ops = {
18702 .open = cafe_v4l_vm_open,
18703 .close = cafe_v4l_vm_close
18704 };
18705diff -urNp linux-2.6.30.4/drivers/media/video/et61x251/et61x251_core.c linux-2.6.30.4/drivers/media/video/et61x251/et61x251_core.c
18706--- linux-2.6.30.4/drivers/media/video/et61x251/et61x251_core.c 2009-07-24 17:47:51.000000000 -0400
18707+++ linux-2.6.30.4/drivers/media/video/et61x251/et61x251_core.c 2009-07-30 09:48:10.031530096 -0400
18708@@ -1494,7 +1494,7 @@ static void et61x251_vm_close(struct vm_
18709 }
18710
18711
18712-static struct vm_operations_struct et61x251_vm_ops = {
18713+static const struct vm_operations_struct et61x251_vm_ops = {
18714 .open = et61x251_vm_open,
18715 .close = et61x251_vm_close,
18716 };
18717diff -urNp linux-2.6.30.4/drivers/media/video/gspca/gspca.c linux-2.6.30.4/drivers/media/video/gspca/gspca.c
18718--- linux-2.6.30.4/drivers/media/video/gspca/gspca.c 2009-07-24 17:47:51.000000000 -0400
18719+++ linux-2.6.30.4/drivers/media/video/gspca/gspca.c 2009-07-30 09:48:10.032627590 -0400
18720@@ -99,7 +99,7 @@ static void gspca_vm_close(struct vm_are
18721 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_MAPPED;
18722 }
18723
18724-static struct vm_operations_struct gspca_vm_ops = {
18725+static const struct vm_operations_struct gspca_vm_ops = {
18726 .open = gspca_vm_open,
18727 .close = gspca_vm_close,
18728 };
18729diff -urNp linux-2.6.30.4/drivers/media/video/meye.c linux-2.6.30.4/drivers/media/video/meye.c
18730--- linux-2.6.30.4/drivers/media/video/meye.c 2009-07-24 17:47:51.000000000 -0400
18731+++ linux-2.6.30.4/drivers/media/video/meye.c 2009-07-30 09:48:10.032627590 -0400
18732@@ -1589,7 +1589,7 @@ static void meye_vm_close(struct vm_area
18733 meye.vma_use_count[idx]--;
18734 }
18735
18736-static struct vm_operations_struct meye_vm_ops = {
18737+static const struct vm_operations_struct meye_vm_ops = {
18738 .open = meye_vm_open,
18739 .close = meye_vm_close,
18740 };
18741diff -urNp linux-2.6.30.4/drivers/media/video/sn9c102/sn9c102_core.c linux-2.6.30.4/drivers/media/video/sn9c102/sn9c102_core.c
18742--- linux-2.6.30.4/drivers/media/video/sn9c102/sn9c102_core.c 2009-07-24 17:47:51.000000000 -0400
18743+++ linux-2.6.30.4/drivers/media/video/sn9c102/sn9c102_core.c 2009-07-30 09:48:10.033630131 -0400
18744@@ -2075,7 +2075,7 @@ static void sn9c102_vm_close(struct vm_a
18745 }
18746
18747
18748-static struct vm_operations_struct sn9c102_vm_ops = {
18749+static const struct vm_operations_struct sn9c102_vm_ops = {
18750 .open = sn9c102_vm_open,
18751 .close = sn9c102_vm_close,
18752 };
18753diff -urNp linux-2.6.30.4/drivers/media/video/stk-webcam.c linux-2.6.30.4/drivers/media/video/stk-webcam.c
18754--- linux-2.6.30.4/drivers/media/video/stk-webcam.c 2009-07-24 17:47:51.000000000 -0400
18755+++ linux-2.6.30.4/drivers/media/video/stk-webcam.c 2009-07-30 09:48:10.033630131 -0400
18756@@ -789,7 +789,7 @@ static void stk_v4l_vm_close(struct vm_a
18757 if (sbuf->mapcount == 0)
18758 sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_MAPPED;
18759 }
18760-static struct vm_operations_struct stk_v4l_vm_ops = {
18761+static const struct vm_operations_struct stk_v4l_vm_ops = {
18762 .open = stk_v4l_vm_open,
18763 .close = stk_v4l_vm_close
18764 };
18765diff -urNp linux-2.6.30.4/drivers/media/video/uvc/uvc_v4l2.c linux-2.6.30.4/drivers/media/video/uvc/uvc_v4l2.c
18766--- linux-2.6.30.4/drivers/media/video/uvc/uvc_v4l2.c 2009-07-24 17:47:51.000000000 -0400
18767+++ linux-2.6.30.4/drivers/media/video/uvc/uvc_v4l2.c 2009-07-30 09:48:10.034661447 -0400
18768@@ -1036,7 +1036,7 @@ static void uvc_vm_close(struct vm_area_
18769 buffer->vma_use_count--;
18770 }
18771
18772-static struct vm_operations_struct uvc_vm_ops = {
18773+static const struct vm_operations_struct uvc_vm_ops = {
18774 .open = uvc_vm_open,
18775 .close = uvc_vm_close,
18776 };
18777diff -urNp linux-2.6.30.4/drivers/media/video/videobuf-dma-contig.c linux-2.6.30.4/drivers/media/video/videobuf-dma-contig.c
18778--- linux-2.6.30.4/drivers/media/video/videobuf-dma-contig.c 2009-07-24 17:47:51.000000000 -0400
18779+++ linux-2.6.30.4/drivers/media/video/videobuf-dma-contig.c 2009-07-30 09:48:10.034661447 -0400
18780@@ -103,7 +103,7 @@ static void videobuf_vm_close(struct vm_
18781 }
18782 }
18783
18784-static struct vm_operations_struct videobuf_vm_ops = {
18785+static const struct vm_operations_struct videobuf_vm_ops = {
18786 .open = videobuf_vm_open,
18787 .close = videobuf_vm_close,
18788 };
18789diff -urNp linux-2.6.30.4/drivers/media/video/vino.c linux-2.6.30.4/drivers/media/video/vino.c
18790--- linux-2.6.30.4/drivers/media/video/vino.c 2009-07-24 17:47:51.000000000 -0400
18791+++ linux-2.6.30.4/drivers/media/video/vino.c 2009-07-30 09:48:10.035537043 -0400
18792@@ -3858,7 +3858,7 @@ static void vino_vm_close(struct vm_area
18793 dprintk("vino_vm_close(): count = %d\n", fb->map_count);
18794 }
18795
18796-static struct vm_operations_struct vino_vm_ops = {
18797+static const struct vm_operations_struct vino_vm_ops = {
18798 .open = vino_vm_open,
18799 .close = vino_vm_close,
18800 };
18801diff -urNp linux-2.6.30.4/drivers/media/video/zc0301/zc0301_core.c linux-2.6.30.4/drivers/media/video/zc0301/zc0301_core.c
18802--- linux-2.6.30.4/drivers/media/video/zc0301/zc0301_core.c 2009-07-24 17:47:51.000000000 -0400
18803+++ linux-2.6.30.4/drivers/media/video/zc0301/zc0301_core.c 2009-07-30 09:48:10.036598829 -0400
18804@@ -933,7 +933,7 @@ static void zc0301_vm_close(struct vm_ar
18805 }
18806
18807
18808-static struct vm_operations_struct zc0301_vm_ops = {
18809+static const struct vm_operations_struct zc0301_vm_ops = {
18810 .open = zc0301_vm_open,
18811 .close = zc0301_vm_close,
18812 };
18813diff -urNp linux-2.6.30.4/drivers/media/video/zoran/zoran_driver.c linux-2.6.30.4/drivers/media/video/zoran/zoran_driver.c
18814--- linux-2.6.30.4/drivers/media/video/zoran/zoran_driver.c 2009-07-24 17:47:51.000000000 -0400
18815+++ linux-2.6.30.4/drivers/media/video/zoran/zoran_driver.c 2009-07-30 12:07:09.597971485 -0400
18816@@ -3177,7 +3177,7 @@ zoran_vm_close (struct vm_area_struct *v
18817 mutex_unlock(&zr->resource_lock);
18818 }
18819
18820-static struct vm_operations_struct zoran_vm_ops = {
18821+static const struct vm_operations_struct zoran_vm_ops = {
18822 .open = zoran_vm_open,
18823 .close = zoran_vm_close,
18824 };
18825diff -urNp linux-2.6.30.4/drivers/misc/ibmasm/ibmasmfs.c linux-2.6.30.4/drivers/misc/ibmasm/ibmasmfs.c
18826--- linux-2.6.30.4/drivers/misc/ibmasm/ibmasmfs.c 2009-07-24 17:47:51.000000000 -0400
18827+++ linux-2.6.30.4/drivers/misc/ibmasm/ibmasmfs.c 2009-07-30 09:48:10.036598829 -0400
18828@@ -97,7 +97,7 @@ static int ibmasmfs_get_super(struct fil
18829 return get_sb_single(fst, flags, data, ibmasmfs_fill_super, mnt);
18830 }
18831
18832-static struct super_operations ibmasmfs_s_ops = {
18833+static const struct super_operations ibmasmfs_s_ops = {
18834 .statfs = simple_statfs,
18835 .drop_inode = generic_delete_inode,
18836 };
18837diff -urNp linux-2.6.30.4/drivers/misc/phantom.c linux-2.6.30.4/drivers/misc/phantom.c
18838--- linux-2.6.30.4/drivers/misc/phantom.c 2009-07-24 17:47:51.000000000 -0400
18839+++ linux-2.6.30.4/drivers/misc/phantom.c 2009-07-30 09:48:10.037448258 -0400
18840@@ -271,7 +271,7 @@ static unsigned int phantom_poll(struct
18841 return mask;
18842 }
18843
18844-static struct file_operations phantom_file_ops = {
18845+static const struct file_operations phantom_file_ops = {
18846 .open = phantom_open,
18847 .release = phantom_release,
18848 .unlocked_ioctl = phantom_ioctl,
18849diff -urNp linux-2.6.30.4/drivers/misc/sgi-gru/grufile.c linux-2.6.30.4/drivers/misc/sgi-gru/grufile.c
18850--- linux-2.6.30.4/drivers/misc/sgi-gru/grufile.c 2009-07-24 17:47:51.000000000 -0400
18851+++ linux-2.6.30.4/drivers/misc/sgi-gru/grufile.c 2009-07-30 17:46:03.273720317 -0400
18852@@ -53,7 +53,7 @@ struct gru_stats_s gru_stats;
18853 /* Guaranteed user available resources on each node */
18854 static int max_user_cbrs, max_user_dsr_bytes;
18855
18856-static struct file_operations gru_fops;
18857+static const struct file_operations gru_fops;
18858 static struct miscdevice gru_miscdev;
18859
18860
18861@@ -460,7 +460,7 @@ static void __exit gru_exit(void)
18862 gru_proc_exit();
18863 }
18864
18865-static struct file_operations gru_fops = {
18866+static const struct file_operations gru_fops = {
18867 .owner = THIS_MODULE,
18868 .unlocked_ioctl = gru_file_unlocked_ioctl,
18869 .mmap = gru_file_mmap,
18870@@ -472,7 +472,7 @@ static struct miscdevice gru_miscdev = {
18871 .fops = &gru_fops,
18872 };
18873
18874-struct vm_operations_struct gru_vm_ops = {
18875+const struct vm_operations_struct gru_vm_ops = {
18876 .close = gru_vma_close,
18877 .fault = gru_fault,
18878 };
18879diff -urNp linux-2.6.30.4/drivers/misc/sgi-gru/grutables.h linux-2.6.30.4/drivers/misc/sgi-gru/grutables.h
18880--- linux-2.6.30.4/drivers/misc/sgi-gru/grutables.h 2009-07-24 17:47:51.000000000 -0400
18881+++ linux-2.6.30.4/drivers/misc/sgi-gru/grutables.h 2009-07-30 17:46:28.013592240 -0400
18882@@ -589,7 +589,7 @@ static inline void unlock_tgh_handle(str
18883 */
18884 struct gru_unload_context_req;
18885
18886-extern struct vm_operations_struct gru_vm_ops;
18887+extern const struct vm_operations_struct gru_vm_ops;
18888 extern struct device *grudev;
18889
18890 extern struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma,
18891diff -urNp linux-2.6.30.4/drivers/mmc/core/debugfs.c linux-2.6.30.4/drivers/mmc/core/debugfs.c
18892--- linux-2.6.30.4/drivers/mmc/core/debugfs.c 2009-07-24 17:47:51.000000000 -0400
18893+++ linux-2.6.30.4/drivers/mmc/core/debugfs.c 2009-07-30 12:06:52.113899680 -0400
18894@@ -240,7 +240,7 @@ static int mmc_ext_csd_release(struct in
18895 return 0;
18896 }
18897
18898-static struct file_operations mmc_dbg_ext_csd_fops = {
18899+static const struct file_operations mmc_dbg_ext_csd_fops = {
18900 .open = mmc_ext_csd_open,
18901 .read = mmc_ext_csd_read,
18902 .release = mmc_ext_csd_release,
18903diff -urNp linux-2.6.30.4/drivers/mtd/devices/doc2000.c linux-2.6.30.4/drivers/mtd/devices/doc2000.c
18904--- linux-2.6.30.4/drivers/mtd/devices/doc2000.c 2009-07-24 17:47:51.000000000 -0400
18905+++ linux-2.6.30.4/drivers/mtd/devices/doc2000.c 2009-07-30 09:48:10.037448258 -0400
18906@@ -776,7 +776,7 @@ static int doc_write(struct mtd_info *mt
2380c486
JR
18907
18908 /* The ECC will not be calculated correctly if less than 512 is written */
18909 /* DBB-
18910- if (len != 0x200 && eccbuf)
18911+ if (len != 0x200)
18912 printk(KERN_WARNING
18913 "ECC needs a full sector write (adr: %lx size %lx)\n",
18914 (long) to, (long) len);
017d2877
AM
18915diff -urNp linux-2.6.30.4/drivers/mtd/devices/doc2001.c linux-2.6.30.4/drivers/mtd/devices/doc2001.c
18916--- linux-2.6.30.4/drivers/mtd/devices/doc2001.c 2009-07-24 17:47:51.000000000 -0400
18917+++ linux-2.6.30.4/drivers/mtd/devices/doc2001.c 2009-07-30 11:10:49.040301758 -0400
18918@@ -395,6 +395,8 @@ static int doc_read (struct mtd_info *mt
2380c486
JR
18919 /* Don't allow read past end of device */
18920 if (from >= this->totlen)
18921 return -EINVAL;
18922+ if (!len)
18923+ return -EINVAL;
18924
18925 /* Don't allow a single read to cross a 512-byte block boundary */
18926 if (from + len > ((from | 0x1ff) + 1))
017d2877
AM
18927diff -urNp linux-2.6.30.4/drivers/mtd/ubi/build.c linux-2.6.30.4/drivers/mtd/ubi/build.c
18928--- linux-2.6.30.4/drivers/mtd/ubi/build.c 2009-07-24 17:47:51.000000000 -0400
18929+++ linux-2.6.30.4/drivers/mtd/ubi/build.c 2009-07-30 09:48:10.038828720 -0400
2380c486
JR
18930@@ -1112,7 +1112,7 @@ static int __init bytes_str_to_int(const
18931 unsigned long result;
18932
18933 result = simple_strtoul(str, &endp, 0);
18934- if (str == endp || result < 0) {
18935+ if (str == endp) {
18936 printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
18937 str);
18938 return -EINVAL;
017d2877
AM
18939diff -urNp linux-2.6.30.4/drivers/net/irda/vlsi_ir.c linux-2.6.30.4/drivers/net/irda/vlsi_ir.c
18940--- linux-2.6.30.4/drivers/net/irda/vlsi_ir.c 2009-07-24 17:47:51.000000000 -0400
18941+++ linux-2.6.30.4/drivers/net/irda/vlsi_ir.c 2009-07-30 09:48:10.038828720 -0400
2380c486
JR
18942@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
18943 /* no race - tx-ring already empty */
18944 vlsi_set_baud(idev, iobase);
18945 netif_wake_queue(ndev);
18946- }
18947- else
18948- ;
18949+ } else {
18950 /* keep the speed change pending like it would
18951 * for any len>0 packet. tx completion interrupt
18952 * will apply it when the tx ring becomes empty.
18953 */
18954+ }
18955 spin_unlock_irqrestore(&idev->lock, flags);
18956 dev_kfree_skb_any(skb);
18957 return 0;
017d2877
AM
18958diff -urNp linux-2.6.30.4/drivers/net/pcnet32.c linux-2.6.30.4/drivers/net/pcnet32.c
18959--- linux-2.6.30.4/drivers/net/pcnet32.c 2009-07-24 17:47:51.000000000 -0400
18960+++ linux-2.6.30.4/drivers/net/pcnet32.c 2009-07-30 09:48:10.039525961 -0400
2380c486
JR
18961@@ -78,7 +78,7 @@ static int cards_found;
18962 /*
18963 * VLB I/O addresses
18964 */
18965-static unsigned int pcnet32_portlist[] __initdata =
18966+static unsigned int pcnet32_portlist[] __devinitdata =
18967 { 0x300, 0x320, 0x340, 0x360, 0 };
18968
18969 static int pcnet32_debug = 0;
017d2877
AM
18970diff -urNp linux-2.6.30.4/drivers/net/tg3.h linux-2.6.30.4/drivers/net/tg3.h
18971--- linux-2.6.30.4/drivers/net/tg3.h 2009-07-24 17:47:51.000000000 -0400
18972+++ linux-2.6.30.4/drivers/net/tg3.h 2009-07-30 09:48:10.040563677 -0400
2380c486
JR
18973@@ -89,6 +89,7 @@
18974 #define CHIPREV_ID_5750_A0 0x4000
18975 #define CHIPREV_ID_5750_A1 0x4001
18976 #define CHIPREV_ID_5750_A3 0x4003
18977+#define CHIPREV_ID_5750_C1 0x4201
18978 #define CHIPREV_ID_5750_C2 0x4202
18979 #define CHIPREV_ID_5752_A0_HW 0x5000
18980 #define CHIPREV_ID_5752_A0 0x6000
017d2877
AM
18981diff -urNp linux-2.6.30.4/drivers/oprofile/buffer_sync.c linux-2.6.30.4/drivers/oprofile/buffer_sync.c
18982--- linux-2.6.30.4/drivers/oprofile/buffer_sync.c 2009-07-24 17:47:51.000000000 -0400
18983+++ linux-2.6.30.4/drivers/oprofile/buffer_sync.c 2009-07-30 09:48:10.040563677 -0400
18984@@ -341,7 +341,7 @@ static void add_data(struct op_entry *en
de855c5d
AM
18985 if (cookie == NO_COOKIE)
18986 offset = pc;
18987 if (cookie == INVALID_COOKIE) {
18988- atomic_inc(&oprofile_stats.sample_lost_no_mapping);
18989+ atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
18990 offset = pc;
18991 }
18992 if (cookie != last_cookie) {
017d2877 18993@@ -385,14 +385,14 @@ add_sample(struct mm_struct *mm, struct
de855c5d
AM
18994 /* add userspace sample */
18995
18996 if (!mm) {
18997- atomic_inc(&oprofile_stats.sample_lost_no_mm);
18998+ atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mm);
18999 return 0;
19000 }
19001
19002 cookie = lookup_dcookie(mm, s->eip, &offset);
19003
19004 if (cookie == INVALID_COOKIE) {
19005- atomic_inc(&oprofile_stats.sample_lost_no_mapping);
19006+ atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
19007 return 0;
19008 }
19009
017d2877 19010@@ -561,7 +561,7 @@ void sync_buffer(int cpu)
de855c5d
AM
19011 /* ignore backtraces if failed to add a sample */
19012 if (state == sb_bt_start) {
19013 state = sb_bt_ignore;
19014- atomic_inc(&oprofile_stats.bt_lost_no_mapping);
19015+ atomic_inc_unchecked(&oprofile_stats.bt_lost_no_mapping);
19016 }
19017 }
19018 release_mm(mm);
017d2877
AM
19019diff -urNp linux-2.6.30.4/drivers/oprofile/event_buffer.c linux-2.6.30.4/drivers/oprofile/event_buffer.c
19020--- linux-2.6.30.4/drivers/oprofile/event_buffer.c 2009-07-24 17:47:51.000000000 -0400
19021+++ linux-2.6.30.4/drivers/oprofile/event_buffer.c 2009-07-30 09:48:10.040563677 -0400
de855c5d
AM
19022@@ -42,7 +42,7 @@ static atomic_t buffer_ready = ATOMIC_IN
19023 void add_event_entry(unsigned long value)
19024 {
19025 if (buffer_pos == buffer_size) {
19026- atomic_inc(&oprofile_stats.event_lost_overflow);
19027+ atomic_inc_unchecked(&oprofile_stats.event_lost_overflow);
19028 return;
19029 }
19030
017d2877
AM
19031diff -urNp linux-2.6.30.4/drivers/oprofile/oprofilefs.c linux-2.6.30.4/drivers/oprofile/oprofilefs.c
19032--- linux-2.6.30.4/drivers/oprofile/oprofilefs.c 2009-07-24 17:47:51.000000000 -0400
19033+++ linux-2.6.30.4/drivers/oprofile/oprofilefs.c 2009-07-30 09:48:10.043540480 -0400
19034@@ -35,7 +35,7 @@ static struct inode *oprofilefs_get_inod
19035 }
19036
19037
19038-static struct super_operations s_ops = {
19039+static const struct super_operations s_ops = {
19040 .statfs = simple_statfs,
19041 .drop_inode = generic_delete_inode,
19042 };
de855c5d
AM
19043@@ -187,7 +187,7 @@ static const struct file_operations atom
19044
19045
19046 int oprofilefs_create_ro_atomic(struct super_block *sb, struct dentry *root,
19047- char const *name, atomic_t *val)
19048+ char const *name, atomic_unchecked_t *val)
19049 {
19050 struct dentry *d = __oprofilefs_create_file(sb, root, name,
19051 &atomic_ro_fops, 0444);
017d2877
AM
19052diff -urNp linux-2.6.30.4/drivers/oprofile/oprofile_stats.h linux-2.6.30.4/drivers/oprofile/oprofile_stats.h
19053--- linux-2.6.30.4/drivers/oprofile/oprofile_stats.h 2009-07-24 17:47:51.000000000 -0400
19054+++ linux-2.6.30.4/drivers/oprofile/oprofile_stats.h 2009-07-30 09:48:10.043540480 -0400
de855c5d
AM
19055@@ -13,10 +13,10 @@
19056 #include <asm/atomic.h>
19057
19058 struct oprofile_stat_struct {
19059- atomic_t sample_lost_no_mm;
19060- atomic_t sample_lost_no_mapping;
19061- atomic_t bt_lost_no_mapping;
19062- atomic_t event_lost_overflow;
19063+ atomic_unchecked_t sample_lost_no_mm;
19064+ atomic_unchecked_t sample_lost_no_mapping;
19065+ atomic_unchecked_t bt_lost_no_mapping;
19066+ atomic_unchecked_t event_lost_overflow;
19067 };
19068
19069 extern struct oprofile_stat_struct oprofile_stats;
017d2877
AM
19070diff -urNp linux-2.6.30.4/drivers/pci/hotplug/cpqphp.h linux-2.6.30.4/drivers/pci/hotplug/cpqphp.h
19071--- linux-2.6.30.4/drivers/pci/hotplug/cpqphp.h 2009-07-24 17:47:51.000000000 -0400
19072+++ linux-2.6.30.4/drivers/pci/hotplug/cpqphp.h 2009-07-30 09:48:10.043540480 -0400
19073@@ -449,7 +449,7 @@ extern u8 cpqhp_disk_irq;
19074
19075 /* inline functions */
19076
19077-static inline char *slot_name(struct slot *slot)
19078+static inline const char *slot_name(struct slot *slot)
19079 {
19080 return hotplug_slot_name(slot->hotplug_slot);
19081 }
19082diff -urNp linux-2.6.30.4/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.30.4/drivers/pci/hotplug/cpqphp_nvram.c
19083--- linux-2.6.30.4/drivers/pci/hotplug/cpqphp_nvram.c 2009-07-24 17:47:51.000000000 -0400
19084+++ linux-2.6.30.4/drivers/pci/hotplug/cpqphp_nvram.c 2009-07-30 09:48:10.043540480 -0400
2380c486
JR
19085@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
19086
19087 void compaq_nvram_init (void __iomem *rom_start)
19088 {
19089+
19090+#ifndef CONFIG_PAX_KERNEXEC
19091 if (rom_start) {
19092 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
19093 }
19094+#endif
19095+
19096 dbg("int15 entry = %p\n", compaq_int15_entry_point);
19097
19098 /* initialize our int15 lock */
017d2877
AM
19099diff -urNp linux-2.6.30.4/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.30.4/drivers/pci/pcie/aer/aerdrv_core.c
19100--- linux-2.6.30.4/drivers/pci/pcie/aer/aerdrv_core.c 2009-07-24 17:47:51.000000000 -0400
19101+++ linux-2.6.30.4/drivers/pci/pcie/aer/aerdrv_core.c 2009-07-30 09:48:10.044753152 -0400
2380c486
JR
19102@@ -670,7 +670,7 @@ static void aer_isr_one_error(struct pci
19103 struct aer_err_source *e_src)
19104 {
19105 struct device *s_device;
19106- struct aer_err_info e_info = {0, 0, 0,};
19107+ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
19108 int i;
19109 u16 id;
19110
017d2877
AM
19111diff -urNp linux-2.6.30.4/drivers/pci/pcie/portdrv_pci.c linux-2.6.30.4/drivers/pci/pcie/portdrv_pci.c
19112--- linux-2.6.30.4/drivers/pci/pcie/portdrv_pci.c 2009-07-24 17:47:51.000000000 -0400
19113+++ linux-2.6.30.4/drivers/pci/pcie/portdrv_pci.c 2009-07-30 09:48:10.044753152 -0400
19114@@ -249,7 +249,7 @@ static void pcie_portdrv_err_resume(stru
2380c486
JR
19115 static const struct pci_device_id port_pci_ids[] = { {
19116 /* handle any PCI-Express port */
19117 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
19118- }, { /* end: all zeroes */ }
19119+ }, { 0, 0, 0, 0, 0, 0, 0 }
19120 };
19121 MODULE_DEVICE_TABLE(pci, port_pci_ids);
19122
017d2877
AM
19123diff -urNp linux-2.6.30.4/drivers/pci/proc.c linux-2.6.30.4/drivers/pci/proc.c
19124--- linux-2.6.30.4/drivers/pci/proc.c 2009-07-24 17:47:51.000000000 -0400
19125+++ linux-2.6.30.4/drivers/pci/proc.c 2009-07-30 11:10:49.067392504 -0400
2380c486
JR
19126@@ -480,7 +480,16 @@ static const struct file_operations proc
19127 static int __init pci_proc_init(void)
19128 {
19129 struct pci_dev *dev = NULL;
19130+
19131+#ifdef CONFIG_GRKERNSEC_PROC_ADD
19132+#ifdef CONFIG_GRKERNSEC_PROC_USER
19133+ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
19134+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19135+ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
19136+#endif
19137+#else
19138 proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
19139+#endif
19140 proc_create("devices", 0, proc_bus_pci_dir,
19141 &proc_bus_pci_dev_operations);
19142 proc_initialized = 1;
017d2877
AM
19143diff -urNp linux-2.6.30.4/drivers/pcmcia/ti113x.h linux-2.6.30.4/drivers/pcmcia/ti113x.h
19144--- linux-2.6.30.4/drivers/pcmcia/ti113x.h 2009-07-24 17:47:51.000000000 -0400
19145+++ linux-2.6.30.4/drivers/pcmcia/ti113x.h 2009-07-30 09:48:10.044753152 -0400
2380c486
JR
19146@@ -903,7 +903,7 @@ static struct pci_device_id ene_tune_tbl
19147 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
19148 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
19149
19150- {}
19151+ { 0, 0, 0, 0, 0, 0, 0 }
19152 };
19153
19154 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
017d2877
AM
19155diff -urNp linux-2.6.30.4/drivers/pcmcia/yenta_socket.c linux-2.6.30.4/drivers/pcmcia/yenta_socket.c
19156--- linux-2.6.30.4/drivers/pcmcia/yenta_socket.c 2009-07-24 17:47:51.000000000 -0400
19157+++ linux-2.6.30.4/drivers/pcmcia/yenta_socket.c 2009-07-30 09:48:10.045642944 -0400
2380c486
JR
19158@@ -1366,7 +1366,7 @@ static struct pci_device_id yenta_table
19159
19160 /* match any cardbus bridge */
19161 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
19162- { /* all zeroes */ }
19163+ { 0, 0, 0, 0, 0, 0, 0 }
19164 };
19165 MODULE_DEVICE_TABLE(pci, yenta_table);
19166
017d2877
AM
19167diff -urNp linux-2.6.30.4/drivers/pnp/pnpbios/bioscalls.c linux-2.6.30.4/drivers/pnp/pnpbios/bioscalls.c
19168--- linux-2.6.30.4/drivers/pnp/pnpbios/bioscalls.c 2009-07-24 17:47:51.000000000 -0400
19169+++ linux-2.6.30.4/drivers/pnp/pnpbios/bioscalls.c 2009-07-30 09:48:10.045642944 -0400
2380c486
JR
19170@@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
19171 set_limit(gdt[(selname) >> 3], size); \
19172 } while(0)
19173
19174-static struct desc_struct bad_bios_desc;
19175+static struct desc_struct bad_bios_desc __read_only;
19176
19177 /*
19178 * At some point we want to use this stack frame pointer to unwind
19179@@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
19180 struct desc_struct save_desc_40;
19181 int cpu;
19182
19183+#ifdef CONFIG_PAX_KERNEXEC
19184+ unsigned long cr0;
19185+#endif
19186+
19187 /*
19188 * PnP BIOSes are generally not terribly re-entrant.
19189 * Also, don't rely on them to save everything correctly.
19190@@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
19191
19192 cpu = get_cpu();
19193 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
19194+
19195+#ifdef CONFIG_PAX_KERNEXEC
19196+ pax_open_kernel(cr0);
19197+#endif
19198+
19199 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
19200
19201+#ifdef CONFIG_PAX_KERNEXEC
19202+ pax_close_kernel(cr0);
19203+#endif
19204+
19205 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
19206 spin_lock_irqsave(&pnp_bios_lock, flags);
19207
19208@@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
19209 :"memory");
19210 spin_unlock_irqrestore(&pnp_bios_lock, flags);
19211
19212+#ifdef CONFIG_PAX_KERNEXEC
19213+ pax_open_kernel(cr0);
19214+#endif
19215+
19216 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
19217+
19218+#ifdef CONFIG_PAX_KERNEXEC
19219+ pax_close_kernel(cr0);
19220+#endif
19221+
19222 put_cpu();
19223
19224 /* If we get here and this is set then the PnP BIOS faulted on us. */
19225@@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
19226 return status;
19227 }
19228
19229-void pnpbios_calls_init(union pnp_bios_install_struct *header)
19230+void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
19231 {
19232 int i;
19233
19234+#ifdef CONFIG_PAX_KERNEXEC
19235+ unsigned long cr0;
19236+#endif
19237+
19238 spin_lock_init(&pnp_bios_lock);
19239 pnp_bios_callpoint.offset = header->fields.pm16offset;
19240 pnp_bios_callpoint.segment = PNP_CS16;
19241
19242+#ifdef CONFIG_PAX_KERNEXEC
19243+ pax_open_kernel(cr0);
19244+#endif
19245+
19246 bad_bios_desc.a = 0;
19247- bad_bios_desc.b = 0x00409200;
19248+ bad_bios_desc.b = 0x00409300;
19249
19250 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
19251 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
19252@@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
19253 set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
19254 __va(header->fields.pm16dseg));
19255 }
19256+
19257+#ifdef CONFIG_PAX_KERNEXEC
19258+ pax_close_kernel(cr0);
19259+#endif
19260+
19261 }
017d2877
AM
19262diff -urNp linux-2.6.30.4/drivers/pnp/quirks.c linux-2.6.30.4/drivers/pnp/quirks.c
19263--- linux-2.6.30.4/drivers/pnp/quirks.c 2009-07-24 17:47:51.000000000 -0400
19264+++ linux-2.6.30.4/drivers/pnp/quirks.c 2009-07-30 09:48:10.045642944 -0400
2380c486
JR
19265@@ -327,7 +327,7 @@ static struct pnp_fixup pnp_fixups[] = {
19266 /* PnP resources that might overlap PCI BARs */
19267 {"PNP0c01", quirk_system_pci_resources},
19268 {"PNP0c02", quirk_system_pci_resources},
19269- {""}
19270+ {"", NULL}
19271 };
19272
19273 void pnp_fixup_device(struct pnp_dev *dev)
017d2877
AM
19274diff -urNp linux-2.6.30.4/drivers/pnp/resource.c linux-2.6.30.4/drivers/pnp/resource.c
19275--- linux-2.6.30.4/drivers/pnp/resource.c 2009-07-24 17:47:51.000000000 -0400
19276+++ linux-2.6.30.4/drivers/pnp/resource.c 2009-07-30 09:48:10.045642944 -0400
2380c486
JR
19277@@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
19278 return 1;
19279
19280 /* check if the resource is valid */
19281- if (*irq < 0 || *irq > 15)
19282+ if (*irq > 15)
19283 return 0;
19284
19285 /* check if the resource is reserved */
19286@@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
19287 return 1;
19288
19289 /* check if the resource is valid */
19290- if (*dma < 0 || *dma == 4 || *dma > 7)
19291+ if (*dma == 4 || *dma > 7)
19292 return 0;
19293
19294 /* check if the resource is reserved */
017d2877
AM
19295diff -urNp linux-2.6.30.4/drivers/s390/cio/qdio_debug.c linux-2.6.30.4/drivers/s390/cio/qdio_debug.c
19296--- linux-2.6.30.4/drivers/s390/cio/qdio_debug.c 2009-07-24 17:47:51.000000000 -0400
19297+++ linux-2.6.30.4/drivers/s390/cio/qdio_debug.c 2009-07-30 09:48:10.046735063 -0400
19298@@ -145,7 +145,7 @@ static void remove_debugfs_entry(struct
19299 }
19300 }
19301
19302-static struct file_operations debugfs_fops = {
19303+static const struct file_operations debugfs_fops = {
19304 .owner = THIS_MODULE,
19305 .open = qstat_seq_open,
19306 .read = seq_read,
19307diff -urNp linux-2.6.30.4/drivers/s390/cio/qdio_perf.c linux-2.6.30.4/drivers/s390/cio/qdio_perf.c
19308--- linux-2.6.30.4/drivers/s390/cio/qdio_perf.c 2009-07-24 17:47:51.000000000 -0400
19309+++ linux-2.6.30.4/drivers/s390/cio/qdio_perf.c 2009-07-30 09:48:10.046735063 -0400
19310@@ -96,7 +96,7 @@ static int qdio_perf_seq_open(struct ino
19311 return single_open(filp, qdio_perf_proc_show, NULL);
19312 }
19313
19314-static struct file_operations qdio_perf_proc_fops = {
19315+static const struct file_operations qdio_perf_proc_fops = {
19316 .owner = THIS_MODULE,
19317 .open = qdio_perf_seq_open,
19318 .read = seq_read,
19319diff -urNp linux-2.6.30.4/drivers/scsi/libfc/fc_exch.c linux-2.6.30.4/drivers/scsi/libfc/fc_exch.c
19320--- linux-2.6.30.4/drivers/scsi/libfc/fc_exch.c 2009-07-24 17:47:51.000000000 -0400
19321+++ linux-2.6.30.4/drivers/scsi/libfc/fc_exch.c 2009-07-30 09:48:10.047458850 -0400
de855c5d
AM
19322@@ -84,12 +84,12 @@ struct fc_exch_mgr {
19323 * all together if not used XXX
19324 */
19325 struct {
19326- atomic_t no_free_exch;
19327- atomic_t no_free_exch_xid;
19328- atomic_t xid_not_found;
19329- atomic_t xid_busy;
19330- atomic_t seq_not_found;
19331- atomic_t non_bls_resp;
19332+ atomic_unchecked_t no_free_exch;
19333+ atomic_unchecked_t no_free_exch_xid;
19334+ atomic_unchecked_t xid_not_found;
19335+ atomic_unchecked_t xid_busy;
19336+ atomic_unchecked_t seq_not_found;
19337+ atomic_unchecked_t non_bls_resp;
19338 } stats;
19339 struct fc_exch **exches; /* for exch pointers indexed by xid */
19340 };
19341@@ -534,7 +534,7 @@ struct fc_exch *fc_exch_alloc(struct fc_
19342 /* allocate memory for exchange */
19343 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
19344 if (!ep) {
19345- atomic_inc(&mp->stats.no_free_exch);
19346+ atomic_inc_unchecked(&mp->stats.no_free_exch);
19347 goto out;
19348 }
19349 memset(ep, 0, sizeof(*ep));
19350@@ -579,7 +579,7 @@ out:
19351 return ep;
19352 err:
19353 spin_unlock_bh(&mp->em_lock);
19354- atomic_inc(&mp->stats.no_free_exch_xid);
19355+ atomic_inc_unchecked(&mp->stats.no_free_exch_xid);
19356 mempool_free(ep, mp->ep_pool);
19357 return NULL;
19358 }
19359@@ -682,7 +682,7 @@ static enum fc_pf_rjt_reason fc_seq_look
19360 xid = ntohs(fh->fh_ox_id); /* we originated exch */
19361 ep = fc_exch_find(mp, xid);
19362 if (!ep) {
19363- atomic_inc(&mp->stats.xid_not_found);
19364+ atomic_inc_unchecked(&mp->stats.xid_not_found);
19365 reject = FC_RJT_OX_ID;
19366 goto out;
19367 }
19368@@ -712,7 +712,7 @@ static enum fc_pf_rjt_reason fc_seq_look
19369 ep = fc_exch_find(mp, xid);
19370 if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) {
19371 if (ep) {
19372- atomic_inc(&mp->stats.xid_busy);
19373+ atomic_inc_unchecked(&mp->stats.xid_busy);
19374 reject = FC_RJT_RX_ID;
19375 goto rel;
19376 }
19377@@ -723,7 +723,7 @@ static enum fc_pf_rjt_reason fc_seq_look
19378 }
19379 xid = ep->xid; /* get our XID */
19380 } else if (!ep) {
19381- atomic_inc(&mp->stats.xid_not_found);
19382+ atomic_inc_unchecked(&mp->stats.xid_not_found);
19383 reject = FC_RJT_RX_ID; /* XID not found */
19384 goto out;
19385 }
19386@@ -744,7 +744,7 @@ static enum fc_pf_rjt_reason fc_seq_look
19387 } else {
19388 sp = &ep->seq;
19389 if (sp->id != fh->fh_seq_id) {
19390- atomic_inc(&mp->stats.seq_not_found);
19391+ atomic_inc_unchecked(&mp->stats.seq_not_found);
19392 reject = FC_RJT_SEQ_ID; /* sequence/exch should exist */
19393 goto rel;
19394 }
19395@@ -1156,18 +1156,18 @@ static void fc_exch_recv_seq_resp(struct
19396
19397 ep = fc_exch_find(mp, ntohs(fh->fh_ox_id));
19398 if (!ep) {
19399- atomic_inc(&mp->stats.xid_not_found);
19400+ atomic_inc_unchecked(&mp->stats.xid_not_found);
19401 goto out;
19402 }
19403 if (ep->rxid == FC_XID_UNKNOWN)
19404 ep->rxid = ntohs(fh->fh_rx_id);
19405 if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) {
19406- atomic_inc(&mp->stats.xid_not_found);
19407+ atomic_inc_unchecked(&mp->stats.xid_not_found);
19408 goto rel;
19409 }
19410 if (ep->did != ntoh24(fh->fh_s_id) &&
19411 ep->did != FC_FID_FLOGI) {
19412- atomic_inc(&mp->stats.xid_not_found);
19413+ atomic_inc_unchecked(&mp->stats.xid_not_found);
19414 goto rel;
19415 }
19416 sof = fr_sof(fp);
19417@@ -1178,7 +1178,7 @@ static void fc_exch_recv_seq_resp(struct
19418 } else {
19419 sp = &ep->seq;
19420 if (sp->id != fh->fh_seq_id) {
19421- atomic_inc(&mp->stats.seq_not_found);
19422+ atomic_inc_unchecked(&mp->stats.seq_not_found);
19423 goto rel;
19424 }
19425 }
19426@@ -1237,10 +1237,10 @@ static void fc_exch_recv_resp(struct fc_
19427
19428 sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */
19429 if (!sp) {
19430- atomic_inc(&mp->stats.xid_not_found);
19431+ atomic_inc_unchecked(&mp->stats.xid_not_found);
19432 FC_DEBUG_EXCH("seq lookup failed\n");
19433 } else {
19434- atomic_inc(&mp->stats.non_bls_resp);
19435+ atomic_inc_unchecked(&mp->stats.non_bls_resp);
19436 FC_DEBUG_EXCH("non-BLS response to sequence");
19437 }
19438 fc_frame_free(fp);
017d2877
AM
19439diff -urNp linux-2.6.30.4/drivers/scsi/scsi_logging.h linux-2.6.30.4/drivers/scsi/scsi_logging.h
19440--- linux-2.6.30.4/drivers/scsi/scsi_logging.h 2009-07-24 17:47:51.000000000 -0400
19441+++ linux-2.6.30.4/drivers/scsi/scsi_logging.h 2009-07-30 09:48:10.047458850 -0400
2380c486
JR
19442@@ -51,7 +51,7 @@ do { \
19443 } while (0); \
19444 } while (0)
19445 #else
19446-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
19447+#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
19448 #endif /* CONFIG_SCSI_LOGGING */
19449
19450 /*
017d2877
AM
19451diff -urNp linux-2.6.30.4/drivers/scsi/sg.c linux-2.6.30.4/drivers/scsi/sg.c
19452--- linux-2.6.30.4/drivers/scsi/sg.c 2009-07-30 20:32:40.512605937 -0400
19453+++ linux-2.6.30.4/drivers/scsi/sg.c 2009-07-30 20:32:47.966608613 -0400
19454@@ -1186,7 +1186,7 @@ sg_vma_fault(struct vm_area_struct *vma,
19455 return VM_FAULT_SIGBUS;
19456 }
19457
19458-static struct vm_operations_struct sg_mmap_vm_ops = {
19459+static const struct vm_operations_struct sg_mmap_vm_ops = {
19460 .fault = sg_vma_fault,
19461 };
19462
19463@@ -1318,7 +1318,7 @@ static void sg_rq_end_io(struct request
19464 }
19465 }
19466
19467-static struct file_operations sg_fops = {
19468+static const struct file_operations sg_fops = {
19469 .owner = THIS_MODULE,
19470 .read = sg_read,
19471 .write = sg_write,
19472@@ -2194,8 +2194,11 @@ static int sg_proc_seq_show_int(struct s
19473 static int sg_proc_single_open_adio(struct inode *inode, struct file *file);
19474 static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer,
19475 size_t count, loff_t *off);
19476-static struct file_operations adio_fops = {
19477- /* .owner, .read and .llseek added in sg_proc_init() */
19478+
19479+static const struct file_operations adio_fops = {
19480+ .owner = THIS_MODULE,
19481+ .read = seq_read,
19482+ .llseek = seq_lseek,
19483 .open = sg_proc_single_open_adio,
19484 .write = sg_proc_write_adio,
19485 .release = single_release,
19486@@ -2204,7 +2207,10 @@ static struct file_operations adio_fops
19487 static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
19488 static ssize_t sg_proc_write_dressz(struct file *filp,
19489 const char __user *buffer, size_t count, loff_t *off);
19490-static struct file_operations dressz_fops = {
19491+static const struct file_operations dressz_fops = {
19492+ .owner = THIS_MODULE,
19493+ .read = seq_read,
19494+ .llseek = seq_lseek,
19495 .open = sg_proc_single_open_dressz,
19496 .write = sg_proc_write_dressz,
19497 .release = single_release,
19498@@ -2212,14 +2218,20 @@ static struct file_operations dressz_fop
19499
19500 static int sg_proc_seq_show_version(struct seq_file *s, void *v);
19501 static int sg_proc_single_open_version(struct inode *inode, struct file *file);
19502-static struct file_operations version_fops = {
19503+static const struct file_operations version_fops = {
19504+ .owner = THIS_MODULE,
19505+ .read = seq_read,
19506+ .llseek = seq_lseek,
19507 .open = sg_proc_single_open_version,
19508 .release = single_release,
19509 };
19510
19511 static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v);
19512 static int sg_proc_single_open_devhdr(struct inode *inode, struct file *file);
19513-static struct file_operations devhdr_fops = {
19514+static const struct file_operations devhdr_fops = {
19515+ .owner = THIS_MODULE,
19516+ .read = seq_read,
19517+ .llseek = seq_lseek,
19518 .open = sg_proc_single_open_devhdr,
19519 .release = single_release,
19520 };
19521@@ -2229,11 +2241,14 @@ static int sg_proc_open_dev(struct inode
19522 static void * dev_seq_start(struct seq_file *s, loff_t *pos);
19523 static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos);
19524 static void dev_seq_stop(struct seq_file *s, void *v);
19525-static struct file_operations dev_fops = {
19526+static const struct file_operations dev_fops = {
19527+ .owner = THIS_MODULE,
19528+ .read = seq_read,
19529+ .llseek = seq_lseek,
19530 .open = sg_proc_open_dev,
19531 .release = seq_release,
19532 };
19533-static struct seq_operations dev_seq_ops = {
19534+static const struct seq_operations dev_seq_ops = {
19535 .start = dev_seq_start,
19536 .next = dev_seq_next,
19537 .stop = dev_seq_stop,
19538@@ -2242,11 +2257,14 @@ static struct seq_operations dev_seq_ops
19539
19540 static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v);
19541 static int sg_proc_open_devstrs(struct inode *inode, struct file *file);
19542-static struct file_operations devstrs_fops = {
19543+static const struct file_operations devstrs_fops = {
19544+ .owner = THIS_MODULE,
19545+ .read = seq_read,
19546+ .llseek = seq_lseek,
19547 .open = sg_proc_open_devstrs,
19548 .release = seq_release,
19549 };
19550-static struct seq_operations devstrs_seq_ops = {
19551+static const struct seq_operations devstrs_seq_ops = {
19552 .start = dev_seq_start,
19553 .next = dev_seq_next,
19554 .stop = dev_seq_stop,
19555@@ -2255,11 +2273,14 @@ static struct seq_operations devstrs_seq
19556
19557 static int sg_proc_seq_show_debug(struct seq_file *s, void *v);
19558 static int sg_proc_open_debug(struct inode *inode, struct file *file);
19559-static struct file_operations debug_fops = {
19560+static const struct file_operations debug_fops = {
19561+ .owner = THIS_MODULE,
19562+ .read = seq_read,
19563+ .llseek = seq_lseek,
19564 .open = sg_proc_open_debug,
19565 .release = seq_release,
19566 };
19567-static struct seq_operations debug_seq_ops = {
19568+static const struct seq_operations debug_seq_ops = {
19569 .start = dev_seq_start,
19570 .next = dev_seq_next,
19571 .stop = dev_seq_stop,
19572@@ -2269,7 +2290,7 @@ static struct seq_operations debug_seq_o
19573
19574 struct sg_proc_leaf {
19575 const char * name;
19576- struct file_operations * fops;
19577+ const struct file_operations * fops;
19578 };
19579
19580 static struct sg_proc_leaf sg_proc_leaf_arr[] = {
19581@@ -2295,9 +2316,6 @@ sg_proc_init(void)
19582 for (k = 0; k < num_leaves; ++k) {
19583 leaf = &sg_proc_leaf_arr[k];
19584 mask = leaf->fops->write ? S_IRUGO | S_IWUSR : S_IRUGO;
19585- leaf->fops->owner = THIS_MODULE;
19586- leaf->fops->read = seq_read;
19587- leaf->fops->llseek = seq_lseek;
19588 proc_create(leaf->name, mask, sg_proc_sgp, leaf->fops);
19589 }
19590 return 0;
19591diff -urNp linux-2.6.30.4/drivers/serial/8250_pci.c linux-2.6.30.4/drivers/serial/8250_pci.c
19592--- linux-2.6.30.4/drivers/serial/8250_pci.c 2009-07-24 17:47:51.000000000 -0400
19593+++ linux-2.6.30.4/drivers/serial/8250_pci.c 2009-07-30 09:48:10.048531085 -0400
19594@@ -3572,7 +3572,7 @@ static struct pci_device_id serial_pci_t
2380c486
JR
19595 PCI_ANY_ID, PCI_ANY_ID,
19596 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
19597 0xffff00, pbn_default },
19598- { 0, }
19599+ { 0, 0, 0, 0, 0, 0, 0 }
19600 };
19601
19602 static struct pci_driver serial_pci_driver = {
017d2877
AM
19603diff -urNp linux-2.6.30.4/drivers/spi/spidev.c linux-2.6.30.4/drivers/spi/spidev.c
19604--- linux-2.6.30.4/drivers/spi/spidev.c 2009-07-24 17:47:51.000000000 -0400
19605+++ linux-2.6.30.4/drivers/spi/spidev.c 2009-07-30 09:48:10.049614710 -0400
19606@@ -532,7 +532,7 @@ static int spidev_release(struct inode *
19607 return status;
19608 }
19609
19610-static struct file_operations spidev_fops = {
19611+static const struct file_operations spidev_fops = {
19612 .owner = THIS_MODULE,
19613 /* REVISIT switch to aio primitives, so that userspace
19614 * gets more complete API coverage. It'll simplify things
19615diff -urNp linux-2.6.30.4/drivers/staging/android/binder.c linux-2.6.30.4/drivers/staging/android/binder.c
19616--- linux-2.6.30.4/drivers/staging/android/binder.c 2009-07-24 17:47:51.000000000 -0400
19617+++ linux-2.6.30.4/drivers/staging/android/binder.c 2009-07-30 12:07:09.614975906 -0400
19618@@ -2699,7 +2699,7 @@ static void binder_vma_close(struct vm_a
19619 binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
19620 }
19621
19622-static struct vm_operations_struct binder_vm_ops = {
19623+static const struct vm_operations_struct binder_vm_ops = {
19624 .open = binder_vma_open,
19625 .close = binder_vma_close,
19626 };
19627@@ -3579,7 +3579,7 @@ static int binder_read_proc_transaction_
19628 return len < count ? len : count;
19629 }
19630
19631-static struct file_operations binder_fops = {
19632+static const struct file_operations binder_fops = {
19633 .owner = THIS_MODULE,
19634 .poll = binder_poll,
19635 .unlocked_ioctl = binder_ioctl,
19636diff -urNp linux-2.6.30.4/drivers/staging/android/logger.c linux-2.6.30.4/drivers/staging/android/logger.c
19637--- linux-2.6.30.4/drivers/staging/android/logger.c 2009-07-24 17:47:51.000000000 -0400
19638+++ linux-2.6.30.4/drivers/staging/android/logger.c 2009-07-30 09:48:10.050638667 -0400
19639@@ -519,7 +519,7 @@ static long logger_ioctl(struct file *fi
19640 return ret;
19641 }
19642
19643-static struct file_operations logger_fops = {
19644+static const struct file_operations logger_fops = {
19645 .owner = THIS_MODULE,
19646 .read = logger_read,
19647 .aio_write = logger_aio_write,
19648diff -urNp linux-2.6.30.4/drivers/staging/android/ram_console.c linux-2.6.30.4/drivers/staging/android/ram_console.c
19649--- linux-2.6.30.4/drivers/staging/android/ram_console.c 2009-07-24 17:47:51.000000000 -0400
19650+++ linux-2.6.30.4/drivers/staging/android/ram_console.c 2009-07-30 09:48:10.050638667 -0400
19651@@ -365,7 +365,7 @@ static ssize_t ram_console_read_old(stru
19652 return count;
19653 }
19654
19655-static struct file_operations ram_console_file_ops = {
19656+static const struct file_operations ram_console_file_ops = {
19657 .owner = THIS_MODULE,
19658 .read = ram_console_read_old,
19659 };
19660diff -urNp linux-2.6.30.4/drivers/staging/b3dfg/b3dfg.c linux-2.6.30.4/drivers/staging/b3dfg/b3dfg.c
19661--- linux-2.6.30.4/drivers/staging/b3dfg/b3dfg.c 2009-07-24 17:47:51.000000000 -0400
19662+++ linux-2.6.30.4/drivers/staging/b3dfg/b3dfg.c 2009-07-30 12:07:09.622002360 -0400
19663@@ -455,7 +455,7 @@ static int b3dfg_vma_fault(struct vm_are
19664 return VM_FAULT_NOPAGE;
19665 }
19666
19667-static struct vm_operations_struct b3dfg_vm_ops = {
19668+static const struct vm_operations_struct b3dfg_vm_ops = {
19669 .fault = b3dfg_vma_fault,
19670 };
19671
19672@@ -855,7 +855,7 @@ static int b3dfg_mmap(struct file *filp,
19673 return r;
19674 }
19675
19676-static struct file_operations b3dfg_fops = {
19677+static const struct file_operations b3dfg_fops = {
19678 .owner = THIS_MODULE,
19679 .open = b3dfg_open,
19680 .release = b3dfg_release,
19681diff -urNp linux-2.6.30.4/drivers/staging/comedi/comedi_fops.c linux-2.6.30.4/drivers/staging/comedi/comedi_fops.c
19682--- linux-2.6.30.4/drivers/staging/comedi/comedi_fops.c 2009-07-24 17:47:51.000000000 -0400
19683+++ linux-2.6.30.4/drivers/staging/comedi/comedi_fops.c 2009-07-30 09:48:10.051586138 -0400
19684@@ -1395,7 +1395,7 @@ void comedi_unmap(struct vm_area_struct
19685 mutex_unlock(&dev->mutex);
19686 }
19687
19688-static struct vm_operations_struct comedi_vm_ops = {
19689+static const struct vm_operations_struct comedi_vm_ops = {
19690 .close = comedi_unmap,
19691 };
19692
19693diff -urNp linux-2.6.30.4/drivers/staging/epl/EplApiLinuxKernel.c linux-2.6.30.4/drivers/staging/epl/EplApiLinuxKernel.c
19694--- linux-2.6.30.4/drivers/staging/epl/EplApiLinuxKernel.c 2009-07-24 17:47:51.000000000 -0400
19695+++ linux-2.6.30.4/drivers/staging/epl/EplApiLinuxKernel.c 2009-07-30 09:48:10.051586138 -0400
19696@@ -203,7 +203,7 @@ static int EplLinIoctl(struct inode *pDe
19697 module_init(EplLinInit);
19698 module_exit(EplLinExit);
19699
19700-static struct file_operations EplLinFileOps_g = {
19701+static const struct file_operations EplLinFileOps_g = {
19702 .owner = THIS_MODULE,
19703 .open = EplLinOpen,
19704 .release = EplLinRelease,
19705diff -urNp linux-2.6.30.4/drivers/staging/go7007/go7007-v4l2.c linux-2.6.30.4/drivers/staging/go7007/go7007-v4l2.c
19706--- linux-2.6.30.4/drivers/staging/go7007/go7007-v4l2.c 2009-07-24 17:47:51.000000000 -0400
19707+++ linux-2.6.30.4/drivers/staging/go7007/go7007-v4l2.c 2009-07-30 09:48:10.052768252 -0400
19708@@ -1717,7 +1717,7 @@ static int go7007_vm_fault(struct vm_are
19709 return 0;
19710 }
19711
19712-static struct vm_operations_struct go7007_vm_ops = {
19713+static const struct vm_operations_struct go7007_vm_ops = {
19714 .open = go7007_vm_open,
19715 .close = go7007_vm_close,
19716 .fault = go7007_vm_fault,
19717diff -urNp linux-2.6.30.4/drivers/staging/meilhaus/memain.c linux-2.6.30.4/drivers/staging/meilhaus/memain.c
19718--- linux-2.6.30.4/drivers/staging/meilhaus/memain.c 2009-07-24 17:47:51.000000000 -0400
19719+++ linux-2.6.30.4/drivers/staging/meilhaus/memain.c 2009-07-30 09:48:10.052768252 -0400
19720@@ -108,7 +108,7 @@ static struct cdev *cdevp;
19721 /* File operations provided by the module
19722 */
19723
19724-static struct file_operations me_file_operations = {
19725+static const struct file_operations me_file_operations = {
19726 .owner = THIS_MODULE,
19727 .ioctl = me_ioctl,
19728 .open = me_open,
19729diff -urNp linux-2.6.30.4/drivers/staging/panel/panel.c linux-2.6.30.4/drivers/staging/panel/panel.c
19730--- linux-2.6.30.4/drivers/staging/panel/panel.c 2009-07-24 17:47:51.000000000 -0400
19731+++ linux-2.6.30.4/drivers/staging/panel/panel.c 2009-07-30 09:48:10.053870849 -0400
19732@@ -1263,7 +1263,7 @@ static int lcd_release(struct inode *ino
19733 return 0;
19734 }
19735
19736-static struct file_operations lcd_fops = {
19737+static const struct file_operations lcd_fops = {
19738 .write = lcd_write,
19739 .open = lcd_open,
19740 .release = lcd_release,
19741@@ -1519,7 +1519,7 @@ static int keypad_release(struct inode *
19742 return 0;
19743 }
19744
19745-static struct file_operations keypad_fops = {
19746+static const struct file_operations keypad_fops = {
19747 .read = keypad_read, /* read */
19748 .open = keypad_open, /* open */
19749 .release = keypad_release, /* close */
19750diff -urNp linux-2.6.30.4/drivers/staging/poch/poch.c linux-2.6.30.4/drivers/staging/poch/poch.c
19751--- linux-2.6.30.4/drivers/staging/poch/poch.c 2009-07-24 17:47:51.000000000 -0400
19752+++ linux-2.6.30.4/drivers/staging/poch/poch.c 2009-07-30 09:48:10.053870849 -0400
19753@@ -1056,7 +1056,7 @@ static int poch_ioctl(struct inode *inod
19754 return 0;
19755 }
19756
19757-static struct file_operations poch_fops = {
19758+static const struct file_operations poch_fops = {
19759 .owner = THIS_MODULE,
19760 .open = poch_open,
19761 .release = poch_release,
19762diff -urNp linux-2.6.30.4/drivers/staging/rspiusb/rspiusb.c linux-2.6.30.4/drivers/staging/rspiusb/rspiusb.c
19763--- linux-2.6.30.4/drivers/staging/rspiusb/rspiusb.c 2009-07-24 17:47:51.000000000 -0400
19764+++ linux-2.6.30.4/drivers/staging/rspiusb/rspiusb.c 2009-07-30 09:48:10.053870849 -0400
19765@@ -708,7 +708,7 @@ static int MapUserBuffer(struct ioctl_st
19766 return 0;
19767 }
19768
19769-static struct file_operations piusb_fops = {
19770+static const struct file_operations piusb_fops = {
19771 .owner = THIS_MODULE,
19772 .ioctl = piusb_ioctl,
19773 .open = piusb_open,
19774diff -urNp linux-2.6.30.4/drivers/uio/uio.c linux-2.6.30.4/drivers/uio/uio.c
19775--- linux-2.6.30.4/drivers/uio/uio.c 2009-07-24 17:47:51.000000000 -0400
19776+++ linux-2.6.30.4/drivers/uio/uio.c 2009-07-30 09:48:10.053870849 -0400
19777@@ -658,7 +658,7 @@ static int uio_vma_fault(struct vm_area_
19778 return 0;
19779 }
19780
19781-static struct vm_operations_struct uio_vm_ops = {
19782+static const struct vm_operations_struct uio_vm_ops = {
19783 .open = uio_vma_open,
19784 .close = uio_vma_close,
19785 .fault = uio_vma_fault,
19786diff -urNp linux-2.6.30.4/drivers/usb/atm/usbatm.c linux-2.6.30.4/drivers/usb/atm/usbatm.c
19787--- linux-2.6.30.4/drivers/usb/atm/usbatm.c 2009-07-24 17:47:51.000000000 -0400
19788+++ linux-2.6.30.4/drivers/usb/atm/usbatm.c 2009-07-30 09:48:10.055402995 -0400
de855c5d
AM
19789@@ -333,7 +333,7 @@ static void usbatm_extract_one_cell(stru
19790 if (printk_ratelimit())
19791 atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n",
19792 __func__, vpi, vci);
19793- atomic_inc(&vcc->stats->rx_err);
19794+ atomic_inc_unchecked(&vcc->stats->rx_err);
19795 return;
19796 }
19797
19798@@ -361,7 +361,7 @@ static void usbatm_extract_one_cell(stru
19799 if (length > ATM_MAX_AAL5_PDU) {
19800 atm_rldbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n",
19801 __func__, length, vcc);
19802- atomic_inc(&vcc->stats->rx_err);
19803+ atomic_inc_unchecked(&vcc->stats->rx_err);
19804 goto out;
19805 }
19806
19807@@ -370,14 +370,14 @@ static void usbatm_extract_one_cell(stru
19808 if (sarb->len < pdu_length) {
19809 atm_rldbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n",
19810 __func__, pdu_length, sarb->len, vcc);
19811- atomic_inc(&vcc->stats->rx_err);
19812+ atomic_inc_unchecked(&vcc->stats->rx_err);
19813 goto out;
19814 }
19815
19816 if (crc32_be(~0, skb_tail_pointer(sarb) - pdu_length, pdu_length) != 0xc704dd7b) {
19817 atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n",
19818 __func__, vcc);
19819- atomic_inc(&vcc->stats->rx_err);
19820+ atomic_inc_unchecked(&vcc->stats->rx_err);
19821 goto out;
19822 }
19823
19824@@ -387,7 +387,7 @@ static void usbatm_extract_one_cell(stru
19825 if (printk_ratelimit())
19826 atm_err(instance, "%s: no memory for skb (length: %u)!\n",
19827 __func__, length);
19828- atomic_inc(&vcc->stats->rx_drop);
19829+ atomic_inc_unchecked(&vcc->stats->rx_drop);
19830 goto out;
19831 }
19832
19833@@ -412,7 +412,7 @@ static void usbatm_extract_one_cell(stru
19834
19835 vcc->push(vcc, skb);
19836
19837- atomic_inc(&vcc->stats->rx);
19838+ atomic_inc_unchecked(&vcc->stats->rx);
19839 out:
19840 skb_trim(sarb, 0);
19841 }
19842@@ -616,7 +616,7 @@ static void usbatm_tx_process(unsigned l
19843 struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc;
19844
19845 usbatm_pop(vcc, skb);
19846- atomic_inc(&vcc->stats->tx);
19847+ atomic_inc_unchecked(&vcc->stats->tx);
19848
19849 skb = skb_dequeue(&instance->sndqueue);
19850 }
017d2877
AM
19851diff -urNp linux-2.6.30.4/drivers/usb/class/cdc-acm.c linux-2.6.30.4/drivers/usb/class/cdc-acm.c
19852--- linux-2.6.30.4/drivers/usb/class/cdc-acm.c 2009-07-24 17:47:51.000000000 -0400
19853+++ linux-2.6.30.4/drivers/usb/class/cdc-acm.c 2009-07-30 09:48:10.055402995 -0400
19854@@ -1403,7 +1403,7 @@ static struct usb_device_id acm_ids[] =
2380c486
JR
19855 USB_CDC_ACM_PROTO_AT_CDMA) },
19856
19857 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
19858- { }
19859+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
19860 };
19861
19862 MODULE_DEVICE_TABLE (usb, acm_ids);
017d2877
AM
19863diff -urNp linux-2.6.30.4/drivers/usb/class/usblp.c linux-2.6.30.4/drivers/usb/class/usblp.c
19864--- linux-2.6.30.4/drivers/usb/class/usblp.c 2009-07-24 17:47:51.000000000 -0400
19865+++ linux-2.6.30.4/drivers/usb/class/usblp.c 2009-07-30 09:48:10.055402995 -0400
2380c486
JR
19866@@ -228,7 +228,7 @@ static const struct quirk_printer_struct
19867 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
19868 { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */
19869 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
19870- { 0, 0 }
19871+ { 0, 0, 0 }
19872 };
19873
19874 static int usblp_wwait(struct usblp *usblp, int nonblock);
017d2877 19875@@ -1406,7 +1406,7 @@ static struct usb_device_id usblp_ids []
2380c486
JR
19876 { USB_INTERFACE_INFO(7, 1, 2) },
19877 { USB_INTERFACE_INFO(7, 1, 3) },
19878 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
19879- { } /* Terminating entry */
19880+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
19881 };
19882
19883 MODULE_DEVICE_TABLE (usb, usblp_ids);
017d2877
AM
19884diff -urNp linux-2.6.30.4/drivers/usb/class/usbtmc.c linux-2.6.30.4/drivers/usb/class/usbtmc.c
19885--- linux-2.6.30.4/drivers/usb/class/usbtmc.c 2009-07-24 17:47:51.000000000 -0400
19886+++ linux-2.6.30.4/drivers/usb/class/usbtmc.c 2009-07-30 09:48:10.055402995 -0400
19887@@ -954,7 +954,7 @@ static long usbtmc_ioctl(struct file *fi
19888 return retval;
19889 }
19890
19891-static struct file_operations fops = {
19892+static const struct file_operations fops = {
19893 .owner = THIS_MODULE,
19894 .read = usbtmc_read,
19895 .write = usbtmc_write,
19896diff -urNp linux-2.6.30.4/drivers/usb/core/hub.c linux-2.6.30.4/drivers/usb/core/hub.c
19897--- linux-2.6.30.4/drivers/usb/core/hub.c 2009-07-24 17:47:51.000000000 -0400
19898+++ linux-2.6.30.4/drivers/usb/core/hub.c 2009-07-30 09:48:10.057446184 -0400
19899@@ -3194,7 +3194,7 @@ static struct usb_device_id hub_id_table
2380c486
JR
19900 .bDeviceClass = USB_CLASS_HUB},
19901 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
19902 .bInterfaceClass = USB_CLASS_HUB},
19903- { } /* Terminating entry */
19904+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
19905 };
19906
19907 MODULE_DEVICE_TABLE (usb, hub_id_table);
017d2877
AM
19908diff -urNp linux-2.6.30.4/drivers/usb/core/inode.c linux-2.6.30.4/drivers/usb/core/inode.c
19909--- linux-2.6.30.4/drivers/usb/core/inode.c 2009-07-24 17:47:51.000000000 -0400
19910+++ linux-2.6.30.4/drivers/usb/core/inode.c 2009-07-30 09:48:10.057446184 -0400
19911@@ -47,7 +47,7 @@
19912 #define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO)
19913 #define USBFS_DEFAULT_LISTMODE S_IRUGO
19914
19915-static struct super_operations usbfs_ops;
19916+static const struct super_operations usbfs_ops;
19917 static const struct file_operations default_file_operations;
19918 static struct vfsmount *usbfs_mount;
19919 static int usbfs_mount_count; /* = 0 */
19920@@ -444,7 +444,7 @@ static const struct file_operations defa
19921 .llseek = default_file_lseek,
19922 };
19923
19924-static struct super_operations usbfs_ops = {
19925+static const struct super_operations usbfs_ops = {
19926 .statfs = simple_statfs,
19927 .drop_inode = generic_delete_inode,
19928 .remount_fs = remount,
19929diff -urNp linux-2.6.30.4/drivers/usb/core/message.c linux-2.6.30.4/drivers/usb/core/message.c
19930--- linux-2.6.30.4/drivers/usb/core/message.c 2009-07-30 20:32:40.522633558 -0400
19931+++ linux-2.6.30.4/drivers/usb/core/message.c 2009-07-30 20:32:47.970590702 -0400
19932@@ -890,8 +890,8 @@ char *usb_cache_string(struct usb_device
19933 buf = kmalloc(256, GFP_KERNEL);
de855c5d
AM
19934 if (buf) {
19935 len = usb_string(udev, index, buf, 256);
017d2877 19936- if (len > 0) {
de855c5d 19937- smallbuf = kmalloc(++len, GFP_KERNEL);
017d2877 19938+ if (len++ > 0) {
de855c5d
AM
19939+ smallbuf = kmalloc(len, GFP_KERNEL);
19940 if (!smallbuf)
19941 return buf;
19942 memcpy(smallbuf, buf, len);
017d2877
AM
19943diff -urNp linux-2.6.30.4/drivers/usb/gadget/inode.c linux-2.6.30.4/drivers/usb/gadget/inode.c
19944--- linux-2.6.30.4/drivers/usb/gadget/inode.c 2009-07-24 17:47:51.000000000 -0400
19945+++ linux-2.6.30.4/drivers/usb/gadget/inode.c 2009-07-30 09:48:10.057446184 -0400
19946@@ -2035,7 +2035,7 @@ gadgetfs_create_file (struct super_block
19947 return inode;
19948 }
19949
19950-static struct super_operations gadget_fs_operations = {
19951+static const struct super_operations gadget_fs_operations = {
19952 .statfs = simple_statfs,
19953 .drop_inode = generic_delete_inode,
19954 };
19955diff -urNp linux-2.6.30.4/drivers/usb/gadget/printer.c linux-2.6.30.4/drivers/usb/gadget/printer.c
19956--- linux-2.6.30.4/drivers/usb/gadget/printer.c 2009-07-24 17:47:51.000000000 -0400
19957+++ linux-2.6.30.4/drivers/usb/gadget/printer.c 2009-07-30 09:48:10.059376894 -0400
19958@@ -875,7 +875,7 @@ printer_ioctl(struct file *fd, unsigned
19959 }
19960
19961 /* used after endpoint configuration */
19962-static struct file_operations printer_io_operations = {
19963+static const struct file_operations printer_io_operations = {
19964 .owner = THIS_MODULE,
19965 .open = printer_open,
19966 .read = printer_read,
19967diff -urNp linux-2.6.30.4/drivers/usb/host/ehci-pci.c linux-2.6.30.4/drivers/usb/host/ehci-pci.c
19968--- linux-2.6.30.4/drivers/usb/host/ehci-pci.c 2009-07-24 17:47:51.000000000 -0400
19969+++ linux-2.6.30.4/drivers/usb/host/ehci-pci.c 2009-07-30 09:48:10.059376894 -0400
2380c486
JR
19970@@ -418,7 +418,7 @@ static const struct pci_device_id pci_id
19971 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
19972 .driver_data = (unsigned long) &ehci_pci_hc_driver,
19973 },
19974- { /* end: all zeroes */ }
19975+ { 0, 0, 0, 0, 0, 0, 0 }
19976 };
19977 MODULE_DEVICE_TABLE(pci, pci_ids);
19978
017d2877
AM
19979diff -urNp linux-2.6.30.4/drivers/usb/host/uhci-hcd.c linux-2.6.30.4/drivers/usb/host/uhci-hcd.c
19980--- linux-2.6.30.4/drivers/usb/host/uhci-hcd.c 2009-07-24 17:47:51.000000000 -0400
19981+++ linux-2.6.30.4/drivers/usb/host/uhci-hcd.c 2009-07-30 09:48:10.059941908 -0400
2380c486
JR
19982@@ -927,7 +927,7 @@ static const struct pci_device_id uhci_p
19983 /* handle any USB UHCI controller */
19984 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
19985 .driver_data = (unsigned long) &uhci_driver,
19986- }, { /* end: all zeroes */ }
19987+ }, { 0, 0, 0, 0, 0, 0, 0 }
19988 };
19989
19990 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
017d2877
AM
19991diff -urNp linux-2.6.30.4/drivers/usb/host/whci/debug.c linux-2.6.30.4/drivers/usb/host/whci/debug.c
19992--- linux-2.6.30.4/drivers/usb/host/whci/debug.c 2009-07-24 17:47:51.000000000 -0400
19993+++ linux-2.6.30.4/drivers/usb/host/whci/debug.c 2009-07-30 09:48:10.059941908 -0400
19994@@ -134,7 +134,7 @@ static int pzl_open(struct inode *inode,
19995 return single_open(file, pzl_print, inode->i_private);
19996 }
19997
19998-static struct file_operations di_fops = {
19999+static const struct file_operations di_fops = {
20000 .open = di_open,
20001 .read = seq_read,
20002 .llseek = seq_lseek,
20003@@ -142,7 +142,7 @@ static struct file_operations di_fops =
20004 .owner = THIS_MODULE,
20005 };
20006
20007-static struct file_operations asl_fops = {
20008+static const struct file_operations asl_fops = {
20009 .open = asl_open,
20010 .read = seq_read,
20011 .llseek = seq_lseek,
20012@@ -150,7 +150,7 @@ static struct file_operations asl_fops =
20013 .owner = THIS_MODULE,
20014 };
20015
20016-static struct file_operations pzl_fops = {
20017+static const struct file_operations pzl_fops = {
20018 .open = pzl_open,
20019 .read = seq_read,
20020 .llseek = seq_lseek,
20021diff -urNp linux-2.6.30.4/drivers/usb/mon/mon_bin.c linux-2.6.30.4/drivers/usb/mon/mon_bin.c
20022--- linux-2.6.30.4/drivers/usb/mon/mon_bin.c 2009-07-24 17:47:51.000000000 -0400
20023+++ linux-2.6.30.4/drivers/usb/mon/mon_bin.c 2009-07-30 09:48:10.059941908 -0400
20024@@ -1184,7 +1184,7 @@ static int mon_bin_vma_fault(struct vm_a
20025 return 0;
20026 }
20027
20028-static struct vm_operations_struct mon_bin_vm_ops = {
20029+static const struct vm_operations_struct mon_bin_vm_ops = {
20030 .open = mon_bin_vma_open,
20031 .close = mon_bin_vma_close,
20032 .fault = mon_bin_vma_fault,
20033diff -urNp linux-2.6.30.4/drivers/usb/storage/debug.h linux-2.6.30.4/drivers/usb/storage/debug.h
20034--- linux-2.6.30.4/drivers/usb/storage/debug.h 2009-07-24 17:47:51.000000000 -0400
20035+++ linux-2.6.30.4/drivers/usb/storage/debug.h 2009-07-30 09:48:10.059941908 -0400
2380c486
JR
20036@@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char
20037 #define US_DEBUGPX(x...) printk( x )
20038 #define US_DEBUG(x) x
20039 #else
20040-#define US_DEBUGP(x...)
20041-#define US_DEBUGPX(x...)
20042-#define US_DEBUG(x)
20043+#define US_DEBUGP(x...) do {} while (0)
20044+#define US_DEBUGPX(x...) do {} while (0)
20045+#define US_DEBUG(x) do {} while (0)
20046 #endif
20047
20048 #endif
017d2877
AM
20049diff -urNp linux-2.6.30.4/drivers/usb/storage/usb.c linux-2.6.30.4/drivers/usb/storage/usb.c
20050--- linux-2.6.30.4/drivers/usb/storage/usb.c 2009-07-24 17:47:51.000000000 -0400
20051+++ linux-2.6.30.4/drivers/usb/storage/usb.c 2009-07-30 09:48:10.061383402 -0400
20052@@ -118,7 +118,7 @@ MODULE_PARM_DESC(quirks, "supplemental l
20053
20054 static struct us_unusual_dev us_unusual_dev_list[] = {
20055 # include "unusual_devs.h"
20056- { } /* Terminating entry */
20057+ { NULL, NULL, 0, 0, NULL } /* Terminating entry */
2380c486
JR
20058 };
20059
017d2877
AM
20060 #undef UNUSUAL_DEV
20061diff -urNp linux-2.6.30.4/drivers/usb/storage/usual-tables.c linux-2.6.30.4/drivers/usb/storage/usual-tables.c
20062--- linux-2.6.30.4/drivers/usb/storage/usual-tables.c 2009-07-24 17:47:51.000000000 -0400
20063+++ linux-2.6.30.4/drivers/usb/storage/usual-tables.c 2009-07-30 09:48:10.061383402 -0400
20064@@ -48,7 +48,7 @@
2380c486 20065
017d2877
AM
20066 struct usb_device_id usb_storage_usb_ids[] = {
20067 # include "unusual_devs.h"
20068- { } /* Terminating entry */
20069+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
2380c486 20070 };
017d2877
AM
20071 EXPORT_SYMBOL_GPL(usb_storage_usb_ids);
20072
20073diff -urNp linux-2.6.30.4/drivers/uwb/uwb-debug.c linux-2.6.30.4/drivers/uwb/uwb-debug.c
20074--- linux-2.6.30.4/drivers/uwb/uwb-debug.c 2009-07-24 17:47:51.000000000 -0400
20075+++ linux-2.6.30.4/drivers/uwb/uwb-debug.c 2009-07-30 09:48:10.061383402 -0400
20076@@ -205,7 +205,7 @@ static ssize_t command_write(struct file
20077 return ret < 0 ? ret : len;
20078 }
20079
20080-static struct file_operations command_fops = {
20081+static const struct file_operations command_fops = {
20082 .open = command_open,
20083 .write = command_write,
20084 .read = NULL,
20085@@ -255,7 +255,7 @@ static int reservations_open(struct inod
20086 return single_open(file, reservations_print, inode->i_private);
20087 }
20088
20089-static struct file_operations reservations_fops = {
20090+static const struct file_operations reservations_fops = {
20091 .open = reservations_open,
20092 .read = seq_read,
20093 .llseek = seq_lseek,
20094@@ -283,7 +283,7 @@ static int drp_avail_open(struct inode *
20095 return single_open(file, drp_avail_print, inode->i_private);
20096 }
20097
20098-static struct file_operations drp_avail_fops = {
20099+static const struct file_operations drp_avail_fops = {
20100 .open = drp_avail_open,
20101 .read = seq_read,
20102 .llseek = seq_lseek,
20103diff -urNp linux-2.6.30.4/drivers/uwb/wlp/messages.c linux-2.6.30.4/drivers/uwb/wlp/messages.c
20104--- linux-2.6.30.4/drivers/uwb/wlp/messages.c 2009-07-24 17:47:51.000000000 -0400
20105+++ linux-2.6.30.4/drivers/uwb/wlp/messages.c 2009-07-30 09:48:10.062348453 -0400
2380c486
JR
20106@@ -903,7 +903,7 @@ int wlp_parse_f0(struct wlp *wlp, struct
20107 size_t len = skb->len;
20108 size_t used;
20109 ssize_t result;
20110- struct wlp_nonce enonce, rnonce;
20111+ struct wlp_nonce enonce = {{0}}, rnonce = {{0}};
20112 enum wlp_assc_error assc_err;
20113 char enonce_buf[WLP_WSS_NONCE_STRSIZE];
20114 char rnonce_buf[WLP_WSS_NONCE_STRSIZE];
017d2877
AM
20115diff -urNp linux-2.6.30.4/drivers/video/fb_defio.c linux-2.6.30.4/drivers/video/fb_defio.c
20116--- linux-2.6.30.4/drivers/video/fb_defio.c 2009-07-24 17:47:51.000000000 -0400
20117+++ linux-2.6.30.4/drivers/video/fb_defio.c 2009-07-30 09:48:10.062348453 -0400
20118@@ -125,7 +125,7 @@ page_already_added:
20119 return 0;
20120 }
20121
20122-static struct vm_operations_struct fb_deferred_io_vm_ops = {
20123+static const struct vm_operations_struct fb_deferred_io_vm_ops = {
20124 .fault = fb_deferred_io_fault,
20125 .page_mkwrite = fb_deferred_io_mkwrite,
20126 };
20127diff -urNp linux-2.6.30.4/drivers/video/fbmem.c linux-2.6.30.4/drivers/video/fbmem.c
20128--- linux-2.6.30.4/drivers/video/fbmem.c 2009-07-24 17:47:51.000000000 -0400
20129+++ linux-2.6.30.4/drivers/video/fbmem.c 2009-07-30 09:48:10.062348453 -0400
20130@@ -404,7 +404,7 @@ static void fb_do_show_logo(struct fb_in
2380c486
JR
20131 image->dx += image->width + 8;
20132 }
20133 } else if (rotate == FB_ROTATE_UD) {
20134- for (x = 0; x < num && image->dx >= 0; x++) {
20135+ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
20136 info->fbops->fb_imageblit(info, image);
20137 image->dx -= image->width + 8;
20138 }
017d2877 20139@@ -416,7 +416,7 @@ static void fb_do_show_logo(struct fb_in
2380c486
JR
20140 image->dy += image->height + 8;
20141 }
20142 } else if (rotate == FB_ROTATE_CCW) {
20143- for (x = 0; x < num && image->dy >= 0; x++) {
20144+ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
20145 info->fbops->fb_imageblit(info, image);
20146 image->dy -= image->height + 8;
20147 }
017d2877 20148@@ -1109,7 +1109,7 @@ static long do_fb_ioctl(struct fb_info *
2380c486
JR
20149 return -EFAULT;
20150 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
20151 return -EINVAL;
20152- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
20153+ if (con2fb.framebuffer >= FB_MAX)
20154 return -EINVAL;
20155 if (!registered_fb[con2fb.framebuffer])
20156 request_module("fb%d", con2fb.framebuffer);
017d2877
AM
20157diff -urNp linux-2.6.30.4/drivers/video/fbmon.c linux-2.6.30.4/drivers/video/fbmon.c
20158--- linux-2.6.30.4/drivers/video/fbmon.c 2009-07-24 17:47:51.000000000 -0400
20159+++ linux-2.6.30.4/drivers/video/fbmon.c 2009-07-30 09:48:10.063350135 -0400
2380c486
JR
20160@@ -45,7 +45,7 @@
20161 #ifdef DEBUG
20162 #define DPRINTK(fmt, args...) printk(fmt,## args)
20163 #else
20164-#define DPRINTK(fmt, args...)
20165+#define DPRINTK(fmt, args...) do {} while (0)
20166 #endif
20167
20168 #define FBMON_FIX_HEADER 1
017d2877
AM
20169diff -urNp linux-2.6.30.4/drivers/video/i810/i810_accel.c linux-2.6.30.4/drivers/video/i810/i810_accel.c
20170--- linux-2.6.30.4/drivers/video/i810/i810_accel.c 2009-07-24 17:47:51.000000000 -0400
20171+++ linux-2.6.30.4/drivers/video/i810/i810_accel.c 2009-07-30 09:48:10.063350135 -0400
2380c486
JR
20172@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
20173 }
20174 }
20175 printk("ringbuffer lockup!!!\n");
20176+ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
20177 i810_report_error(mmio);
20178 par->dev_flags |= LOCKUP;
20179 info->pixmap.scan_align = 1;
017d2877
AM
20180diff -urNp linux-2.6.30.4/drivers/video/i810/i810_main.c linux-2.6.30.4/drivers/video/i810/i810_main.c
20181--- linux-2.6.30.4/drivers/video/i810/i810_main.c 2009-07-24 17:47:51.000000000 -0400
20182+++ linux-2.6.30.4/drivers/video/i810/i810_main.c 2009-07-30 09:48:10.064300485 -0400
2380c486
JR
20183@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
20184 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
20185 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
20186 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
20187- { 0 },
20188+ { 0, 0, 0, 0, 0, 0, 0 },
20189 };
20190
20191 static struct pci_driver i810fb_driver = {
017d2877
AM
20192diff -urNp linux-2.6.30.4/drivers/video/modedb.c linux-2.6.30.4/drivers/video/modedb.c
20193--- linux-2.6.30.4/drivers/video/modedb.c 2009-07-24 17:47:51.000000000 -0400
20194+++ linux-2.6.30.4/drivers/video/modedb.c 2009-07-30 09:48:10.064300485 -0400
2380c486
JR
20195@@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
20196 {
20197 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
20198 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
20199- 0, FB_VMODE_NONINTERLACED
20200+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20201 }, {
20202 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
20203 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
20204- 0, FB_VMODE_NONINTERLACED
20205+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20206 }, {
20207 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
20208 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
20209- 0, FB_VMODE_NONINTERLACED
20210+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20211 }, {
20212 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
20213 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
20214- 0, FB_VMODE_INTERLACED
20215+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
20216 }, {
20217 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
20218 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
20219- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20220+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20221 }, {
20222 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
20223 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
20224- 0, FB_VMODE_NONINTERLACED
20225+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20226 }, {
20227 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
20228 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
20229- 0, FB_VMODE_NONINTERLACED
20230+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20231 }, {
20232 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
20233 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
20234- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20235+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20236 }, {
20237 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
20238 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
20239- 0, FB_VMODE_NONINTERLACED
20240+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20241 }, {
20242 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
20243 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
20244- 0, FB_VMODE_INTERLACED
20245+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
20246 }, {
20247 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
20248 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
20249- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20250+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20251 }, {
20252 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
20253 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
20254- 0, FB_VMODE_NONINTERLACED
20255+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20256 }, {
20257 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
20258 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
20259- 0, FB_VMODE_NONINTERLACED
20260+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20261 }, {
20262 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
20263 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
20264- 0, FB_VMODE_NONINTERLACED
20265+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20266 }, {
20267 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
20268 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
20269- 0, FB_VMODE_NONINTERLACED
20270+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20271 }, {
20272 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
20273 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
20274- 0, FB_VMODE_NONINTERLACED
20275+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20276 }, {
20277 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
20278 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
20279- 0, FB_VMODE_INTERLACED
20280+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
20281 }, {
20282 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
20283 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
20284- 0, FB_VMODE_NONINTERLACED
20285+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20286 }, {
20287 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
20288 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
20289- 0, FB_VMODE_NONINTERLACED
20290+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20291 }, {
20292 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
20293 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
20294- 0, FB_VMODE_NONINTERLACED
20295+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20296 }, {
20297 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
20298 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
20299- 0, FB_VMODE_NONINTERLACED
20300+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20301 }, {
20302 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
20303 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
20304- 0, FB_VMODE_NONINTERLACED
20305+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20306 }, {
20307 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
20308 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
20309- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20310+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20311 }, {
20312 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
20313 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
20314- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20315+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20316 }, {
20317 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
20318 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
20319- 0, FB_VMODE_NONINTERLACED
20320+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20321 }, {
20322 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
20323 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
20324- 0, FB_VMODE_NONINTERLACED
20325+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20326 }, {
20327 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
20328 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
20329- 0, FB_VMODE_NONINTERLACED
20330+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20331 }, {
20332 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
20333 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
20334- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20335+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20336 }, {
20337 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
20338 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
20339- 0, FB_VMODE_NONINTERLACED
20340+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20341 }, {
20342 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
20343 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
20344- 0, FB_VMODE_NONINTERLACED
20345+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20346 }, {
20347 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
20348 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
20349- 0, FB_VMODE_NONINTERLACED
20350+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20351 }, {
20352 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
20353 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
20354- 0, FB_VMODE_NONINTERLACED
20355+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20356 }, {
20357 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
20358 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
20359- 0, FB_VMODE_NONINTERLACED
20360+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20361 }, {
20362 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
20363 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
20364- 0, FB_VMODE_NONINTERLACED
20365+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20366 }, {
20367 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
20368 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
20369- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20370+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20371 }, {
20372 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
20373 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
20374- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20375+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20376 }, {
20377 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
20378 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
20379- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20380+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20381 }, {
20382 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
20383 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
20384- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20385+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20386 }, {
20387 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
20388 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
20389- 0, FB_VMODE_NONINTERLACED
20390+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20391 }, {
20392 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
20393 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
20394- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20395+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20396 }, {
20397 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
20398 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
20399- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20400+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20401 }, {
20402 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
20403 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
20404- 0, FB_VMODE_NONINTERLACED
20405+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20406 }, {
20407 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
20408 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
20409- 0, FB_VMODE_NONINTERLACED
20410+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20411 }, {
20412 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
20413 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
20414- 0, FB_VMODE_DOUBLE
20415+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
20416 }, {
20417 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
20418 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
20419- 0, FB_VMODE_DOUBLE
20420+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
20421 }, {
20422 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
20423 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
20424- 0, FB_VMODE_DOUBLE
20425+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
20426 }, {
20427 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
20428 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
20429- 0, FB_VMODE_DOUBLE
20430+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
20431 }, {
20432 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
20433 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
20434- 0, FB_VMODE_DOUBLE
20435+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
20436 }, {
20437 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
20438 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
20439- 0, FB_VMODE_DOUBLE
20440+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
20441 }, {
20442 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
20443 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
20444- 0, FB_VMODE_DOUBLE
20445+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
20446 }, {
20447 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
20448 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
20449- 0, FB_VMODE_DOUBLE
20450+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
20451 }, {
20452 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
20453 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
20454- 0, FB_VMODE_DOUBLE
20455+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
20456 }, {
20457 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
20458 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
20459- 0, FB_VMODE_DOUBLE
20460+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
20461 }, {
20462 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
20463 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
20464 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
20465- FB_VMODE_NONINTERLACED
20466+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20467 }, {
20468 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
20469 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
20470- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
20471+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20472 }, {
20473 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
20474 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
20475- 0, FB_VMODE_NONINTERLACED
20476+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20477 }, {
20478 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
20479 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
20480- 0, FB_VMODE_NONINTERLACED
20481+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
20482 },
20483 };
20484
017d2877
AM
20485diff -urNp linux-2.6.30.4/drivers/video/omap/dispc.c linux-2.6.30.4/drivers/video/omap/dispc.c
20486--- linux-2.6.30.4/drivers/video/omap/dispc.c 2009-07-24 17:47:51.000000000 -0400
20487+++ linux-2.6.30.4/drivers/video/omap/dispc.c 2009-07-30 09:48:10.065250322 -0400
20488@@ -1013,7 +1013,7 @@ static void mmap_user_close(struct vm_ar
20489 atomic_dec(&dispc.map_count[plane]);
20490 }
20491
20492-static struct vm_operations_struct mmap_user_ops = {
20493+static const struct vm_operations_struct mmap_user_ops = {
20494 .open = mmap_user_open,
20495 .close = mmap_user_close,
20496 };
20497diff -urNp linux-2.6.30.4/drivers/video/uvesafb.c linux-2.6.30.4/drivers/video/uvesafb.c
20498--- linux-2.6.30.4/drivers/video/uvesafb.c 2009-07-24 17:47:51.000000000 -0400
20499+++ linux-2.6.30.4/drivers/video/uvesafb.c 2009-07-30 09:48:10.065250322 -0400
2380c486
JR
20500@@ -18,6 +18,7 @@
20501 #include <linux/fb.h>
20502 #include <linux/io.h>
20503 #include <linux/mutex.h>
20504+#include <linux/moduleloader.h>
20505 #include <video/edid.h>
20506 #include <video/uvesafb.h>
20507 #ifdef CONFIG_X86
017d2877 20508@@ -118,7 +119,7 @@ static int uvesafb_helper_start(void)
2380c486
JR
20509 NULL,
20510 };
20511
20512- return call_usermodehelper(v86d_path, argv, envp, 1);
20513+ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
20514 }
20515
20516 /*
017d2877 20517@@ -566,10 +567,34 @@ static int __devinit uvesafb_vbe_getpmi(
2380c486
JR
20518 if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
20519 par->pmi_setpal = par->ypan = 0;
20520 } else {
20521+
20522+#ifdef CONFIG_PAX_KERNEXEC
20523+#ifdef CONFIG_MODULES
20524+ unsigned long cr0;
20525+
20526+ par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
20527+#endif
20528+ if (!par->pmi_code) {
20529+ par->pmi_setpal = par->ypan = 0;
20530+ return 0;
20531+ }
20532+#endif
20533+
20534 par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
20535 + task->t.regs.edi);
20536+
20537+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
20538+ pax_open_kernel(cr0);
20539+ memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
20540+ pax_close_kernel(cr0);
20541+
20542+ par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
20543+ par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
20544+#else
20545 par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
20546 par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
20547+#endif
20548+
20549 printk(KERN_INFO "uvesafb: protected mode interface info at "
20550 "%04x:%04x\n",
20551 (u16)task->t.regs.es, (u16)task->t.regs.edi);
017d2877 20552@@ -1825,6 +1850,11 @@ out:
2380c486
JR
20553 if (par->vbe_modes)
20554 kfree(par->vbe_modes);
20555
20556+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
20557+ if (par->pmi_code)
20558+ module_free_exec(NULL, par->pmi_code);
20559+#endif
20560+
20561 framebuffer_release(info);
20562 return err;
20563 }
017d2877 20564@@ -1851,6 +1881,12 @@ static int uvesafb_remove(struct platfor
2380c486
JR
20565 kfree(par->vbe_state_orig);
20566 if (par->vbe_state_saved)
20567 kfree(par->vbe_state_saved);
20568+
20569+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
20570+ if (par->pmi_code)
20571+ module_free_exec(NULL, par->pmi_code);
20572+#endif
20573+
20574 }
20575
20576 framebuffer_release(info);
017d2877
AM
20577diff -urNp linux-2.6.30.4/drivers/video/vesafb.c linux-2.6.30.4/drivers/video/vesafb.c
20578--- linux-2.6.30.4/drivers/video/vesafb.c 2009-07-24 17:47:51.000000000 -0400
20579+++ linux-2.6.30.4/drivers/video/vesafb.c 2009-07-30 09:48:10.066262821 -0400
2380c486
JR
20580@@ -9,6 +9,7 @@
20581 */
20582
20583 #include <linux/module.h>
20584+#include <linux/moduleloader.h>
20585 #include <linux/kernel.h>
20586 #include <linux/errno.h>
20587 #include <linux/string.h>
20588@@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
20589 static int vram_total __initdata; /* Set total amount of memory */
20590 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
20591 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
20592-static void (*pmi_start)(void) __read_mostly;
20593-static void (*pmi_pal) (void) __read_mostly;
20594+static void (*pmi_start)(void) __read_only;
20595+static void (*pmi_pal) (void) __read_only;
20596 static int depth __read_mostly;
20597 static int vga_compat __read_mostly;
20598 /* --------------------------------------------------------------------- */
20599@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
20600 unsigned int size_vmode;
20601 unsigned int size_remap;
20602 unsigned int size_total;
20603+ void *pmi_code = NULL;
20604
20605 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
20606 return -ENODEV;
20607@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
20608 size_remap = size_total;
20609 vesafb_fix.smem_len = size_remap;
20610
20611-#ifndef __i386__
20612- screen_info.vesapm_seg = 0;
20613-#endif
20614-
20615 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
20616 printk(KERN_WARNING
20617 "vesafb: cannot reserve video memory at 0x%lx\n",
20618@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
20619 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
20620 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
20621
20622+#ifdef __i386__
20623+
20624+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
20625+ pmi_code = module_alloc_exec(screen_info.vesapm_size);
20626+ if (!pmi_code)
20627+#elif !defined(CONFIG_PAX_KERNEXEC)
20628+ if (0)
20629+#endif
20630+
20631+#endif
20632+ screen_info.vesapm_seg = 0;
20633+
20634 if (screen_info.vesapm_seg) {
20635- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
20636- screen_info.vesapm_seg,screen_info.vesapm_off);
20637+ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
20638+ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
20639 }
20640
20641 if (screen_info.vesapm_seg < 0xc000)
20642@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
20643
20644 if (ypan || pmi_setpal) {
20645 unsigned short *pmi_base;
20646- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
20647- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
20648- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
20649+
20650+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
20651+ unsigned long cr0;
20652+#endif
20653+
20654+ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
20655+
20656+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
20657+ pax_open_kernel(cr0);
20658+ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
20659+#else
20660+ pmi_code = pmi_base;
20661+#endif
20662+
20663+ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
20664+ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
20665+
20666+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
20667+ pmi_start = ktva_ktla(pmi_start);
20668+ pmi_pal = ktva_ktla(pmi_pal);
20669+ pax_close_kernel(cr0);
20670+#endif
20671+
20672 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
20673 if (pmi_base[3]) {
20674 printk(KERN_INFO "vesafb: pmi: ports = ");
20675@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
20676 info->node, info->fix.id);
20677 return 0;
20678 err:
20679+
20680+#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
20681+ module_free_exec(NULL, pmi_code);
20682+#endif
20683+
20684 if (info->screen_base)
20685 iounmap(info->screen_base);
20686 framebuffer_release(info);
017d2877
AM
20687diff -urNp linux-2.6.30.4/fs/9p/vfs_inode.c linux-2.6.30.4/fs/9p/vfs_inode.c
20688--- linux-2.6.30.4/fs/9p/vfs_inode.c 2009-07-24 17:47:51.000000000 -0400
20689+++ linux-2.6.30.4/fs/9p/vfs_inode.c 2009-07-30 09:48:10.066262821 -0400
2380c486
JR
20690@@ -1021,7 +1021,7 @@ static void *v9fs_vfs_follow_link(struct
20691 static void
20692 v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
20693 {
20694- char *s = nd_get_link(nd);
20695+ const char *s = nd_get_link(nd);
20696
20697 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name,
20698 IS_ERR(s) ? "<error>" : s);
017d2877
AM
20699diff -urNp linux-2.6.30.4/fs/afs/proc.c linux-2.6.30.4/fs/afs/proc.c
20700--- linux-2.6.30.4/fs/afs/proc.c 2009-07-24 17:47:51.000000000 -0400
20701+++ linux-2.6.30.4/fs/afs/proc.c 2009-07-30 09:48:10.066262821 -0400
20702@@ -28,7 +28,7 @@ static int afs_proc_cells_show(struct se
20703 static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
20704 size_t size, loff_t *_pos);
20705
20706-static struct seq_operations afs_proc_cells_ops = {
20707+static const struct seq_operations afs_proc_cells_ops = {
20708 .start = afs_proc_cells_start,
20709 .next = afs_proc_cells_next,
20710 .stop = afs_proc_cells_stop,
20711@@ -70,7 +70,7 @@ static void *afs_proc_cell_volumes_next(
20712 static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v);
20713 static int afs_proc_cell_volumes_show(struct seq_file *m, void *v);
20714
20715-static struct seq_operations afs_proc_cell_volumes_ops = {
20716+static const struct seq_operations afs_proc_cell_volumes_ops = {
20717 .start = afs_proc_cell_volumes_start,
20718 .next = afs_proc_cell_volumes_next,
20719 .stop = afs_proc_cell_volumes_stop,
20720@@ -95,7 +95,7 @@ static void *afs_proc_cell_vlservers_nex
20721 static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v);
20722 static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v);
20723
20724-static struct seq_operations afs_proc_cell_vlservers_ops = {
20725+static const struct seq_operations afs_proc_cell_vlservers_ops = {
20726 .start = afs_proc_cell_vlservers_start,
20727 .next = afs_proc_cell_vlservers_next,
20728 .stop = afs_proc_cell_vlservers_stop,
20729@@ -119,7 +119,7 @@ static void *afs_proc_cell_servers_next(
20730 static void afs_proc_cell_servers_stop(struct seq_file *p, void *v);
20731 static int afs_proc_cell_servers_show(struct seq_file *m, void *v);
20732
20733-static struct seq_operations afs_proc_cell_servers_ops = {
20734+static const struct seq_operations afs_proc_cell_servers_ops = {
20735 .start = afs_proc_cell_servers_start,
20736 .next = afs_proc_cell_servers_next,
20737 .stop = afs_proc_cell_servers_stop,
20738diff -urNp linux-2.6.30.4/fs/aio.c linux-2.6.30.4/fs/aio.c
20739--- linux-2.6.30.4/fs/aio.c 2009-07-24 17:47:51.000000000 -0400
20740+++ linux-2.6.30.4/fs/aio.c 2009-07-30 09:48:10.067233652 -0400
2380c486
JR
20741@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
20742 size += sizeof(struct io_event) * nr_events;
20743 nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
20744
20745- if (nr_pages < 0)
20746+ if (nr_pages <= 0)
20747 return -EINVAL;
20748
20749 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
017d2877
AM
20750diff -urNp linux-2.6.30.4/fs/autofs/root.c linux-2.6.30.4/fs/autofs/root.c
20751--- linux-2.6.30.4/fs/autofs/root.c 2009-07-24 17:47:51.000000000 -0400
20752+++ linux-2.6.30.4/fs/autofs/root.c 2009-07-30 09:48:10.067811135 -0400
de855c5d
AM
20753@@ -299,7 +299,8 @@ static int autofs_root_symlink(struct in
20754 set_bit(n,sbi->symlink_bitmap);
20755 sl = &sbi->symlink[n];
20756 sl->len = strlen(symname);
20757- sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL);
017d2877 20758+ slsize = sl->len+1;
de855c5d
AM
20759+ sl->data = kmalloc(slsize, GFP_KERNEL);
20760 if (!sl->data) {
20761 clear_bit(n,sbi->symlink_bitmap);
20762 unlock_kernel();
017d2877
AM
20763diff -urNp linux-2.6.30.4/fs/autofs4/symlink.c linux-2.6.30.4/fs/autofs4/symlink.c
20764--- linux-2.6.30.4/fs/autofs4/symlink.c 2009-07-24 17:47:51.000000000 -0400
20765+++ linux-2.6.30.4/fs/autofs4/symlink.c 2009-07-30 09:48:10.067811135 -0400
2380c486
JR
20766@@ -15,7 +15,7 @@
20767 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
20768 {
20769 struct autofs_info *ino = autofs4_dentry_ino(dentry);
20770- nd_set_link(nd, (char *)ino->u.symlink);
20771+ nd_set_link(nd, ino->u.symlink);
20772 return NULL;
20773 }
20774
017d2877
AM
20775diff -urNp linux-2.6.30.4/fs/befs/linuxvfs.c linux-2.6.30.4/fs/befs/linuxvfs.c
20776--- linux-2.6.30.4/fs/befs/linuxvfs.c 2009-07-24 17:47:51.000000000 -0400
20777+++ linux-2.6.30.4/fs/befs/linuxvfs.c 2009-07-30 09:48:10.067811135 -0400
2380c486
JR
20778@@ -493,7 +493,7 @@ static void befs_put_link(struct dentry
20779 {
20780 befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
20781 if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
20782- char *link = nd_get_link(nd);
20783+ const char *link = nd_get_link(nd);
20784 if (!IS_ERR(link))
20785 kfree(link);
20786 }
017d2877
AM
20787diff -urNp linux-2.6.30.4/fs/binfmt_aout.c linux-2.6.30.4/fs/binfmt_aout.c
20788--- linux-2.6.30.4/fs/binfmt_aout.c 2009-07-24 17:47:51.000000000 -0400
20789+++ linux-2.6.30.4/fs/binfmt_aout.c 2009-07-30 11:10:49.111321779 -0400
2380c486
JR
20790@@ -16,6 +16,7 @@
20791 #include <linux/string.h>
20792 #include <linux/fs.h>
20793 #include <linux/file.h>
20794+#include <linux/security.h>
20795 #include <linux/stat.h>
20796 #include <linux/fcntl.h>
20797 #include <linux/ptrace.h>
20798@@ -113,10 +114,12 @@ static int aout_core_dump(long signr, st
20799
20800 /* If the size of the dump file exceeds the rlimit, then see what would happen
20801 if we wrote the stack, but not the data area. */
20802+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
20803 if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
20804 dump.u_dsize = 0;
20805
20806 /* Make sure we have enough room to write the stack and data areas. */
20807+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
20808 if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
20809 dump.u_ssize = 0;
20810
20811@@ -249,6 +252,8 @@ static int load_aout_binary(struct linux
20812 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
20813 if (rlim >= RLIM_INFINITY)
20814 rlim = ~0;
20815+
20816+ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
20817 if (ex.a_data + ex.a_bss > rlim)
20818 return -ENOMEM;
20819
20820@@ -276,6 +281,27 @@ static int load_aout_binary(struct linux
20821 install_exec_creds(bprm);
20822 current->flags &= ~PF_FORKNOEXEC;
20823
20824+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
20825+ current->mm->pax_flags = 0UL;
20826+#endif
20827+
20828+#ifdef CONFIG_PAX_PAGEEXEC
20829+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
20830+ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
20831+
20832+#ifdef CONFIG_PAX_EMUTRAMP
20833+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
20834+ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
20835+#endif
20836+
20837+#ifdef CONFIG_PAX_MPROTECT
20838+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
20839+ current->mm->pax_flags |= MF_PAX_MPROTECT;
20840+#endif
20841+
20842+ }
20843+#endif
20844+
20845 if (N_MAGIC(ex) == OMAGIC) {
20846 unsigned long text_addr, map_size;
20847 loff_t pos;
20848@@ -348,7 +374,7 @@ static int load_aout_binary(struct linux
20849
20850 down_write(&current->mm->mmap_sem);
20851 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
20852- PROT_READ | PROT_WRITE | PROT_EXEC,
20853+ PROT_READ | PROT_WRITE,
20854 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
20855 fd_offset + ex.a_text);
20856 up_write(&current->mm->mmap_sem);
017d2877
AM
20857diff -urNp linux-2.6.30.4/fs/binfmt_elf.c linux-2.6.30.4/fs/binfmt_elf.c
20858--- linux-2.6.30.4/fs/binfmt_elf.c 2009-07-30 20:32:40.526845645 -0400
20859+++ linux-2.6.30.4/fs/binfmt_elf.c 2009-07-30 20:32:47.974595765 -0400
20860@@ -35,6 +35,10 @@
2380c486
JR
20861 #include <asm/param.h>
20862 #include <asm/page.h>
20863
20864+#ifdef CONFIG_PAX_SEGMEXEC
20865+#include <asm/desc.h>
20866+#endif
20867+
20868 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
20869 static int load_elf_library(struct file *);
20870 static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
017d2877 20871@@ -50,6 +54,10 @@ static int elf_core_dump(long signr, str
2380c486
JR
20872 #define elf_core_dump NULL
20873 #endif
20874
20875+#ifdef CONFIG_PAX_MPROTECT
20876+static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags);
20877+#endif
20878+
20879 #if ELF_EXEC_PAGESIZE > PAGE_SIZE
20880 #define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE
20881 #else
017d2877 20882@@ -69,6 +77,11 @@ static struct linux_binfmt elf_format =
2380c486
JR
20883 .load_binary = load_elf_binary,
20884 .load_shlib = load_elf_library,
20885 .core_dump = elf_core_dump,
20886+
20887+#ifdef CONFIG_PAX_MPROTECT
20888+ .handle_mprotect= elf_handle_mprotect,
20889+#endif
20890+
20891 .min_coredump = ELF_EXEC_PAGESIZE,
20892 .hasvdso = 1
20893 };
017d2877 20894@@ -77,6 +90,8 @@ static struct linux_binfmt elf_format =
2380c486
JR
20895
20896 static int set_brk(unsigned long start, unsigned long end)
20897 {
20898+ unsigned long e = end;
20899+
20900 start = ELF_PAGEALIGN(start);
20901 end = ELF_PAGEALIGN(end);
20902 if (end > start) {
017d2877 20903@@ -87,7 +102,7 @@ static int set_brk(unsigned long start,
2380c486
JR
20904 if (BAD_ADDR(addr))
20905 return addr;
20906 }
20907- current->mm->start_brk = current->mm->brk = end;
20908+ current->mm->start_brk = current->mm->brk = e;
20909 return 0;
20910 }
20911
017d2877 20912@@ -148,7 +163,7 @@ create_elf_tables(struct linux_binprm *b
de855c5d
AM
20913 elf_addr_t __user *u_rand_bytes;
20914 const char *k_platform = ELF_PLATFORM;
20915 const char *k_base_platform = ELF_BASE_PLATFORM;
20916- unsigned char k_rand_bytes[16];
20917+ u32 k_rand_bytes[4];
20918 int items;
20919 elf_addr_t *elf_info;
20920 int ei_index = 0;
017d2877 20921@@ -195,6 +210,10 @@ create_elf_tables(struct linux_binprm *b
de855c5d
AM
20922 * Generate 16 random bytes for userspace PRNG seeding.
20923 */
20924 get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes));
20925+ srandom32(k_rand_bytes[0] ^ random32());
20926+ srandom32(k_rand_bytes[1] ^ random32());
20927+ srandom32(k_rand_bytes[2] ^ random32());
20928+ srandom32(k_rand_bytes[3] ^ random32());
20929 u_rand_bytes = (elf_addr_t __user *)
20930 STACK_ALLOC(p, sizeof(k_rand_bytes));
20931 if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes)))
017d2877 20932@@ -385,10 +404,10 @@ static unsigned long load_elf_interp(str
2380c486
JR
20933 {
20934 struct elf_phdr *elf_phdata;
20935 struct elf_phdr *eppnt;
20936- unsigned long load_addr = 0;
20937+ unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
20938 int load_addr_set = 0;
20939 unsigned long last_bss = 0, elf_bss = 0;
20940- unsigned long error = ~0UL;
20941+ unsigned long error = -EINVAL;
20942 unsigned long total_size;
20943 int retval, i, size;
20944
017d2877 20945@@ -434,6 +453,11 @@ static unsigned long load_elf_interp(str
2380c486
JR
20946 goto out_close;
20947 }
20948
20949+#ifdef CONFIG_PAX_SEGMEXEC
20950+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
20951+ pax_task_size = SEGMEXEC_TASK_SIZE;
20952+#endif
20953+
20954 eppnt = elf_phdata;
20955 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
20956 if (eppnt->p_type == PT_LOAD) {
017d2877 20957@@ -477,8 +501,8 @@ static unsigned long load_elf_interp(str
2380c486
JR
20958 k = load_addr + eppnt->p_vaddr;
20959 if (BAD_ADDR(k) ||
20960 eppnt->p_filesz > eppnt->p_memsz ||
20961- eppnt->p_memsz > TASK_SIZE ||
20962- TASK_SIZE - eppnt->p_memsz < k) {
20963+ eppnt->p_memsz > pax_task_size ||
20964+ pax_task_size - eppnt->p_memsz < k) {
20965 error = -ENOMEM;
20966 goto out_close;
20967 }
017d2877 20968@@ -532,6 +556,177 @@ out:
2380c486
JR
20969 return error;
20970 }
20971
20972+#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
20973+static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
20974+{
20975+ unsigned long pax_flags = 0UL;
20976+
20977+#ifdef CONFIG_PAX_PAGEEXEC
20978+ if (elf_phdata->p_flags & PF_PAGEEXEC)
20979+ pax_flags |= MF_PAX_PAGEEXEC;
20980+#endif
20981+
20982+#ifdef CONFIG_PAX_SEGMEXEC
20983+ if (elf_phdata->p_flags & PF_SEGMEXEC)
20984+ pax_flags |= MF_PAX_SEGMEXEC;
20985+#endif
20986+
20987+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
20988+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
20989+ if (nx_enabled)
20990+ pax_flags &= ~MF_PAX_SEGMEXEC;
20991+ else
20992+ pax_flags &= ~MF_PAX_PAGEEXEC;
20993+ }
20994+#endif
20995+
20996+#ifdef CONFIG_PAX_EMUTRAMP
20997+ if (elf_phdata->p_flags & PF_EMUTRAMP)
20998+ pax_flags |= MF_PAX_EMUTRAMP;
20999+#endif
21000+
21001+#ifdef CONFIG_PAX_MPROTECT
21002+ if (elf_phdata->p_flags & PF_MPROTECT)
21003+ pax_flags |= MF_PAX_MPROTECT;
21004+#endif
21005+
21006+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
21007+ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
21008+ pax_flags |= MF_PAX_RANDMMAP;
21009+#endif
21010+
21011+ return pax_flags;
21012+}
21013+#endif
21014+
21015+#ifdef CONFIG_PAX_PT_PAX_FLAGS
21016+static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
21017+{
21018+ unsigned long pax_flags = 0UL;
21019+
21020+#ifdef CONFIG_PAX_PAGEEXEC
21021+ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
21022+ pax_flags |= MF_PAX_PAGEEXEC;
21023+#endif
21024+
21025+#ifdef CONFIG_PAX_SEGMEXEC
21026+ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
21027+ pax_flags |= MF_PAX_SEGMEXEC;
21028+#endif
21029+
21030+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
21031+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
21032+ if (nx_enabled)
21033+ pax_flags &= ~MF_PAX_SEGMEXEC;
21034+ else
21035+ pax_flags &= ~MF_PAX_PAGEEXEC;
21036+ }
21037+#endif
21038+
21039+#ifdef CONFIG_PAX_EMUTRAMP
21040+ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
21041+ pax_flags |= MF_PAX_EMUTRAMP;
21042+#endif
21043+
21044+#ifdef CONFIG_PAX_MPROTECT
21045+ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
21046+ pax_flags |= MF_PAX_MPROTECT;
21047+#endif
21048+
21049+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
21050+ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
21051+ pax_flags |= MF_PAX_RANDMMAP;
21052+#endif
21053+
21054+ return pax_flags;
21055+}
21056+#endif
21057+
21058+#ifdef CONFIG_PAX_EI_PAX
21059+static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
21060+{
21061+ unsigned long pax_flags = 0UL;
21062+
21063+#ifdef CONFIG_PAX_PAGEEXEC
21064+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
21065+ pax_flags |= MF_PAX_PAGEEXEC;
21066+#endif
21067+
21068+#ifdef CONFIG_PAX_SEGMEXEC
21069+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
21070+ pax_flags |= MF_PAX_SEGMEXEC;
21071+#endif
21072+
21073+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
21074+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
21075+ if (nx_enabled)
21076+ pax_flags &= ~MF_PAX_SEGMEXEC;
21077+ else
21078+ pax_flags &= ~MF_PAX_PAGEEXEC;
21079+ }
21080+#endif
21081+
21082+#ifdef CONFIG_PAX_EMUTRAMP
21083+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
21084+ pax_flags |= MF_PAX_EMUTRAMP;
21085+#endif
21086+
21087+#ifdef CONFIG_PAX_MPROTECT
21088+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
21089+ pax_flags |= MF_PAX_MPROTECT;
21090+#endif
21091+
21092+#ifdef CONFIG_PAX_ASLR
21093+ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
21094+ pax_flags |= MF_PAX_RANDMMAP;
21095+#endif
21096+
21097+ return pax_flags;
21098+}
21099+#endif
21100+
21101+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
21102+static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
21103+{
21104+ unsigned long pax_flags = 0UL;
21105+
21106+#ifdef CONFIG_PAX_PT_PAX_FLAGS
21107+ unsigned long i;
21108+#endif
21109+
21110+#ifdef CONFIG_PAX_EI_PAX
21111+ pax_flags = pax_parse_ei_pax(elf_ex);
21112+#endif
21113+
21114+#ifdef CONFIG_PAX_PT_PAX_FLAGS
21115+ for (i = 0UL; i < elf_ex->e_phnum; i++)
21116+ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
21117+ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
21118+ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
21119+ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
21120+ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
21121+ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
21122+ return -EINVAL;
21123+
21124+#ifdef CONFIG_PAX_SOFTMODE
21125+ if (pax_softmode)
21126+ pax_flags = pax_parse_softmode(&elf_phdata[i]);
21127+ else
21128+#endif
21129+
21130+ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
21131+ break;
21132+ }
21133+#endif
21134+
21135+ if (0 > pax_check_flags(&pax_flags))
21136+ return -EINVAL;
21137+
21138+ current->mm->pax_flags = pax_flags;
21139+ return 0;
21140+}
21141+#endif
21142+
21143 /*
21144 * These are the functions used to load ELF style executables and shared
21145 * libraries. There is no binary dependent code anywhere else.
017d2877 21146@@ -548,6 +743,11 @@ static unsigned long randomize_stack_top
2380c486
JR
21147 {
21148 unsigned int random_variable = 0;
21149
21150+#ifdef CONFIG_PAX_RANDUSTACK
21151+ if (randomize_va_space)
21152+ return stack_top - current->mm->delta_stack;
21153+#endif
21154+
21155 if ((current->flags & PF_RANDOMIZE) &&
21156 !(current->personality & ADDR_NO_RANDOMIZE)) {
21157 random_variable = get_random_int() & STACK_RND_MASK;
017d2877 21158@@ -566,7 +766,7 @@ static int load_elf_binary(struct linux_
2380c486
JR
21159 unsigned long load_addr = 0, load_bias = 0;
21160 int load_addr_set = 0;
21161 char * elf_interpreter = NULL;
21162- unsigned long error;
21163+ unsigned long error = 0;
21164 struct elf_phdr *elf_ppnt, *elf_phdata;
21165 unsigned long elf_bss, elf_brk;
017d2877
AM
21166 int retval, i;
21167@@ -576,11 +776,11 @@ static int load_elf_binary(struct linux_
2380c486
JR
21168 unsigned long start_code, end_code, start_data, end_data;
21169 unsigned long reloc_func_desc = 0;
21170 int executable_stack = EXSTACK_DEFAULT;
21171- unsigned long def_flags = 0;
21172 struct {
21173 struct elfhdr elf_ex;
21174 struct elfhdr interp_elf_ex;
21175 } *loc;
21176+ unsigned long pax_task_size = TASK_SIZE;
21177
21178 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
21179 if (!loc) {
017d2877 21180@@ -742,11 +942,80 @@ static int load_elf_binary(struct linux_
2380c486
JR
21181
21182 /* OK, This is the point of no return */
21183 current->flags &= ~PF_FORKNOEXEC;
21184- current->mm->def_flags = def_flags;
21185+
21186+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21187+ current->mm->pax_flags = 0UL;
21188+#endif
21189+
21190+#ifdef CONFIG_PAX_DLRESOLVE
21191+ current->mm->call_dl_resolve = 0UL;
21192+#endif
21193+
21194+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
21195+ current->mm->call_syscall = 0UL;
21196+#endif
21197+
21198+#ifdef CONFIG_PAX_ASLR
21199+ current->mm->delta_mmap = 0UL;
21200+ current->mm->delta_stack = 0UL;
21201+#endif
21202+
21203+ current->mm->def_flags = 0;
21204+
21205+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
21206+ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
21207+ send_sig(SIGKILL, current, 0);
21208+ goto out_free_dentry;
21209+ }
21210+#endif
21211+
21212+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
21213+ pax_set_initial_flags(bprm);
21214+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
21215+ if (pax_set_initial_flags_func)
21216+ (pax_set_initial_flags_func)(bprm);
21217+#endif
21218+
21219+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
21220+ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
21221+ current->mm->context.user_cs_limit = PAGE_SIZE;
21222+ current->mm->def_flags |= VM_PAGEEXEC;
21223+ }
21224+#endif
21225+
21226+#ifdef CONFIG_PAX_SEGMEXEC
21227+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
21228+ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
21229+ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
21230+ pax_task_size = SEGMEXEC_TASK_SIZE;
21231+ }
21232+#endif
21233+
21234+#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
21235+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
21236+ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
21237+ put_cpu_no_resched();
21238+ }
21239+#endif
21240+
21241+#ifdef CONFIG_PAX_ASLR
21242+ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
21243+ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
21244+ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
21245+ }
21246+#endif
21247
21248 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
21249 may depend on the personality. */
21250 SET_PERSONALITY(loc->elf_ex);
21251+
21252+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21253+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
21254+ executable_stack = EXSTACK_DISABLE_X;
21255+ current->personality &= ~READ_IMPLIES_EXEC;
21256+ } else
21257+#endif
21258+
21259 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
21260 current->personality |= READ_IMPLIES_EXEC;
21261
017d2877 21262@@ -827,6 +1096,20 @@ static int load_elf_binary(struct linux_
2380c486
JR
21263 #else
21264 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
21265 #endif
21266+
21267+#ifdef CONFIG_PAX_RANDMMAP
21268+ /* PaX: randomize base address at the default exe base if requested */
21269+ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
21270+#ifdef CONFIG_SPARC64
21271+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
21272+#else
21273+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
21274+#endif
21275+ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
21276+ elf_flags |= MAP_FIXED;
21277+ }
21278+#endif
21279+
21280 }
21281
21282 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
017d2877 21283@@ -859,9 +1142,9 @@ static int load_elf_binary(struct linux_
2380c486
JR
21284 * allowed task size. Note that p_filesz must always be
21285 * <= p_memsz so it is only necessary to check p_memsz.
21286 */
21287- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
21288- elf_ppnt->p_memsz > TASK_SIZE ||
21289- TASK_SIZE - elf_ppnt->p_memsz < k) {
21290+ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
21291+ elf_ppnt->p_memsz > pax_task_size ||
21292+ pax_task_size - elf_ppnt->p_memsz < k) {
21293 /* set_brk can never work. Avoid overflows. */
21294 send_sig(SIGKILL, current, 0);
21295 retval = -EINVAL;
017d2877 21296@@ -889,6 +1172,11 @@ static int load_elf_binary(struct linux_
2380c486
JR
21297 start_data += load_bias;
21298 end_data += load_bias;
21299
21300+#ifdef CONFIG_PAX_RANDMMAP
21301+ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
21302+ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
21303+#endif
21304+
21305 /* Calling set_brk effectively mmaps the pages that we need
21306 * for the bss and break sections. We must do this before
21307 * mapping in the interpreter, to make sure it doesn't wind
017d2877 21308@@ -900,9 +1188,11 @@ static int load_elf_binary(struct linux_
2380c486
JR
21309 goto out_free_dentry;
21310 }
21311 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
21312- send_sig(SIGSEGV, current, 0);
21313- retval = -EFAULT; /* Nobody gets to see this, but.. */
21314- goto out_free_dentry;
21315+ /*
21316+ * This bss-zeroing can fail if the ELF
21317+ * file specifies odd protections. So
21318+ * we don't check the return value
21319+ */
21320 }
21321
21322 if (elf_interpreter) {
017d2877 21323@@ -1135,8 +1425,10 @@ static int dump_seek(struct file *file,
2380c486
JR
21324 unsigned long n = off;
21325 if (n > PAGE_SIZE)
21326 n = PAGE_SIZE;
21327- if (!dump_write(file, buf, n))
21328+ if (!dump_write(file, buf, n)) {
21329+ free_page((unsigned long)buf);
21330 return 0;
21331+ }
21332 off -= n;
21333 }
21334 free_page((unsigned long)buf);
017d2877 21335@@ -1148,7 +1440,7 @@ static int dump_seek(struct file *file,
2380c486
JR
21336 * Decide what to dump of a segment, part, all or none.
21337 */
21338 static unsigned long vma_dump_size(struct vm_area_struct *vma,
21339- unsigned long mm_flags)
21340+ unsigned long mm_flags, long signr)
21341 {
21342 #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
21343
017d2877 21344@@ -1182,7 +1474,7 @@ static unsigned long vma_dump_size(struc
2380c486
JR
21345 if (vma->vm_file == NULL)
21346 return 0;
21347
21348- if (FILTER(MAPPED_PRIVATE))
21349+ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
21350 goto whole;
21351
21352 /*
017d2877 21353@@ -1278,8 +1570,11 @@ static int writenote(struct memelfnote *
2380c486
JR
21354 #undef DUMP_WRITE
21355
21356 #define DUMP_WRITE(addr, nr) \
21357+ do { \
21358+ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
21359 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
21360- goto end_coredump;
21361+ goto end_coredump; \
21362+ } while (0);
21363 #define DUMP_SEEK(off) \
21364 if (!dump_seek(file, (off))) \
21365 goto end_coredump;
017d2877 21366@@ -1984,7 +2279,7 @@ static int elf_core_dump(long signr, str
2380c486
JR
21367 phdr.p_offset = offset;
21368 phdr.p_vaddr = vma->vm_start;
21369 phdr.p_paddr = 0;
21370- phdr.p_filesz = vma_dump_size(vma, mm_flags);
21371+ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
21372 phdr.p_memsz = vma->vm_end - vma->vm_start;
21373 offset += phdr.p_filesz;
21374 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
017d2877 21375@@ -2016,7 +2311,7 @@ static int elf_core_dump(long signr, str
2380c486
JR
21376 unsigned long addr;
21377 unsigned long end;
21378
21379- end = vma->vm_start + vma_dump_size(vma, mm_flags);
21380+ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
21381
21382 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
21383 struct page *page;
017d2877 21384@@ -2036,6 +2331,7 @@ static int elf_core_dump(long signr, str
2380c486
JR
21385 flush_cache_page(tmp_vma, addr,
21386 page_to_pfn(page));
21387 kaddr = kmap(page);
21388+ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
21389 if ((size += PAGE_SIZE) > limit ||
21390 !dump_write(file, kaddr,
21391 PAGE_SIZE)) {
017d2877 21392@@ -2066,6 +2362,99 @@ out:
2380c486
JR
21393
21394 #endif /* USE_ELF_CORE_DUMP */
21395
21396+#ifdef CONFIG_PAX_MPROTECT
21397+/* PaX: non-PIC ELF libraries need relocations on their executable segments
21398+ * therefore we'll grant them VM_MAYWRITE once during their life. Similarly
21399+ * we'll remove VM_MAYWRITE for good on RELRO segments.
21400+ *
21401+ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
21402+ * basis because we want to allow the common case and not the special ones.
21403+ */
21404+static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags)
21405+{
21406+ struct elfhdr elf_h;
21407+ struct elf_phdr elf_p;
21408+ unsigned long i;
21409+ unsigned long oldflags;
21410+ bool is_textrel_rw, is_textrel_rx, is_relro;
21411+
21412+ if (!(vma->vm_mm->pax_flags & MF_PAX_MPROTECT))
21413+ return;
21414+
21415+ oldflags = vma->vm_flags & (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ);
21416+ newflags &= VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ;
21417+
21418+#ifdef CONFIG_PAX_NOELFRELOCS
21419+ is_textrel_rw = false;
21420+ is_textrel_rx = false;
21421+#else
21422+ /* possible TEXTREL */
21423+ is_textrel_rw = vma->vm_file && !vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYREAD | VM_EXEC | VM_READ) && newflags == (VM_WRITE | VM_READ);
21424+ 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);
21425+#endif
21426+
21427+ /* possible RELRO */
21428+ is_relro = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ) && newflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ);
21429+
21430+ if (!is_textrel_rw && !is_textrel_rx && !is_relro)
21431+ return;
21432+
21433+ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
21434+ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
21435+
21436+#ifdef CONFIG_PAX_ETEXECRELOCS
21437+ ((is_textrel_rw || is_textrel_rx) && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
21438+#else
21439+ ((is_textrel_rw || is_textrel_rx) && elf_h.e_type != ET_DYN) ||
21440+#endif
21441+
21442+ (is_relro && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
21443+ !elf_check_arch(&elf_h) ||
21444+ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
21445+ elf_h.e_phnum > 65536UL / sizeof(struct elf_phdr))
21446+ return;
21447+
21448+ for (i = 0UL; i < elf_h.e_phnum; i++) {
21449+ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
21450+ return;
21451+ switch (elf_p.p_type) {
21452+ case PT_DYNAMIC: {
21453+ elf_addr_t dyn_offset = 0UL;
21454+ elf_dyn dyn;
21455+
21456+ if (!is_textrel_rw && !is_textrel_rx)
21457+ continue;
21458+ dyn_offset = elf_p.p_offset;
21459+ i = 0UL;
21460+ do {
21461+ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
21462+ return;
21463+ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
21464+ gr_log_textrel(vma);
21465+ if (is_textrel_rw)
21466+ vma->vm_flags |= VM_MAYWRITE;
21467+ else
21468+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
21469+ vma->vm_flags &= ~VM_MAYWRITE;
21470+ return;
21471+ }
21472+ i++;
21473+ } while (dyn.d_tag != DT_NULL);
21474+ return;
21475+ }
21476+
21477+ case PT_GNU_RELRO:
21478+ if (!is_relro)
21479+ continue;
21480+ if ((elf_p.p_offset >> PAGE_SHIFT) == vma->vm_pgoff && ELF_PAGEALIGN(elf_p.p_memsz) == vma->vm_end - vma->vm_start) {
21481+ vma->vm_flags &= ~VM_MAYWRITE;
21482+ }
21483+ return;
21484+ }
21485+ }
21486+}
21487+#endif
21488+
21489 static int __init init_elf_binfmt(void)
21490 {
21491 return register_binfmt(&elf_format);
017d2877
AM
21492diff -urNp linux-2.6.30.4/fs/binfmt_flat.c linux-2.6.30.4/fs/binfmt_flat.c
21493--- linux-2.6.30.4/fs/binfmt_flat.c 2009-07-24 17:47:51.000000000 -0400
21494+++ linux-2.6.30.4/fs/binfmt_flat.c 2009-07-30 09:48:10.069189169 -0400
21495@@ -565,7 +565,9 @@ static int load_flat_file(struct linux_b
2380c486
JR
21496 realdatastart = (unsigned long) -ENOMEM;
21497 printk("Unable to allocate RAM for process data, errno %d\n",
21498 (int)-realdatastart);
21499+ down_write(&current->mm->mmap_sem);
21500 do_munmap(current->mm, textpos, text_len);
21501+ up_write(&current->mm->mmap_sem);
21502 ret = realdatastart;
21503 goto err;
21504 }
017d2877 21505@@ -589,8 +591,10 @@ static int load_flat_file(struct linux_b
2380c486
JR
21506 }
21507 if (result >= (unsigned long)-4096) {
21508 printk("Unable to read data+bss, errno %d\n", (int)-result);
21509+ down_write(&current->mm->mmap_sem);
21510 do_munmap(current->mm, textpos, text_len);
21511 do_munmap(current->mm, realdatastart, data_len + extra);
21512+ up_write(&current->mm->mmap_sem);
21513 ret = result;
21514 goto err;
21515 }
017d2877 21516@@ -659,8 +663,10 @@ static int load_flat_file(struct linux_b
2380c486
JR
21517 }
21518 if (result >= (unsigned long)-4096) {
21519 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
21520+ down_write(&current->mm->mmap_sem);
21521 do_munmap(current->mm, textpos, text_len + data_len + extra +
21522 MAX_SHARED_LIBS * sizeof(unsigned long));
21523+ up_write(&current->mm->mmap_sem);
21524 ret = result;
21525 goto err;
21526 }
017d2877
AM
21527diff -urNp linux-2.6.30.4/fs/binfmt_misc.c linux-2.6.30.4/fs/binfmt_misc.c
21528--- linux-2.6.30.4/fs/binfmt_misc.c 2009-07-24 17:47:51.000000000 -0400
21529+++ linux-2.6.30.4/fs/binfmt_misc.c 2009-07-30 09:48:10.070138647 -0400
2380c486
JR
21530@@ -693,7 +693,7 @@ static int bm_fill_super(struct super_bl
21531 static struct tree_descr bm_files[] = {
21532 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
21533 [3] = {"register", &bm_register_operations, S_IWUSR},
21534- /* last one */ {""}
21535+ /* last one */ {"", NULL, 0}
21536 };
21537 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
21538 if (!err)
017d2877
AM
21539diff -urNp linux-2.6.30.4/fs/bio.c linux-2.6.30.4/fs/bio.c
21540--- linux-2.6.30.4/fs/bio.c 2009-07-30 20:32:40.527789063 -0400
21541+++ linux-2.6.30.4/fs/bio.c 2009-07-30 20:32:47.975645587 -0400
21542@@ -720,7 +720,7 @@ static int __bio_copy_iov(struct bio *bi
2380c486
JR
21543
21544 while (bv_len && iov_idx < iov_count) {
21545 unsigned int bytes;
21546- char *iov_addr;
21547+ char __user *iov_addr;
21548
21549 bytes = min_t(unsigned int,
21550 iov[iov_idx].iov_len - iov_off, bv_len);
017d2877
AM
21551diff -urNp linux-2.6.30.4/fs/btrfs/ctree.h linux-2.6.30.4/fs/btrfs/ctree.h
21552--- linux-2.6.30.4/fs/btrfs/ctree.h 2009-07-24 17:47:51.000000000 -0400
21553+++ linux-2.6.30.4/fs/btrfs/ctree.h 2009-07-30 09:48:10.071936994 -0400
21554@@ -2174,7 +2174,7 @@ int btrfs_sync_file(struct file *file, s
21555 int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
21556 int skip_pinned);
21557 int btrfs_check_file(struct btrfs_root *root, struct inode *inode);
21558-extern struct file_operations btrfs_file_operations;
21559+extern const struct file_operations btrfs_file_operations;
21560 int btrfs_drop_extents(struct btrfs_trans_handle *trans,
21561 struct btrfs_root *root, struct inode *inode,
21562 u64 start, u64 end, u64 locked_end,
21563diff -urNp linux-2.6.30.4/fs/btrfs/disk-io.c linux-2.6.30.4/fs/btrfs/disk-io.c
21564--- linux-2.6.30.4/fs/btrfs/disk-io.c 2009-07-24 17:47:51.000000000 -0400
21565+++ linux-2.6.30.4/fs/btrfs/disk-io.c 2009-07-30 12:07:28.366973168 -0400
21566@@ -771,7 +771,7 @@ static void btree_invalidatepage(struct
21567 }
21568 }
21569
21570-static struct address_space_operations btree_aops = {
21571+static const struct address_space_operations btree_aops = {
21572 .readpage = btree_readpage,
21573 .writepage = btree_writepage,
21574 .writepages = btree_writepages,
21575diff -urNp linux-2.6.30.4/fs/btrfs/file.c linux-2.6.30.4/fs/btrfs/file.c
21576--- linux-2.6.30.4/fs/btrfs/file.c 2009-07-24 17:47:51.000000000 -0400
21577+++ linux-2.6.30.4/fs/btrfs/file.c 2009-07-30 09:48:10.073009918 -0400
21578@@ -1231,7 +1231,7 @@ out:
21579 return ret > 0 ? EIO : ret;
21580 }
21581
21582-static struct vm_operations_struct btrfs_file_vm_ops = {
21583+static const struct vm_operations_struct btrfs_file_vm_ops = {
21584 .fault = filemap_fault,
21585 .page_mkwrite = btrfs_page_mkwrite,
21586 };
21587@@ -1243,7 +1243,7 @@ static int btrfs_file_mmap(struct file *
21588 return 0;
21589 }
21590
21591-struct file_operations btrfs_file_operations = {
21592+const struct file_operations btrfs_file_operations = {
21593 .llseek = generic_file_llseek,
21594 .read = do_sync_read,
21595 .aio_read = generic_file_aio_read,
21596diff -urNp linux-2.6.30.4/fs/btrfs/inode.c linux-2.6.30.4/fs/btrfs/inode.c
21597--- linux-2.6.30.4/fs/btrfs/inode.c 2009-07-24 17:47:51.000000000 -0400
21598+++ linux-2.6.30.4/fs/btrfs/inode.c 2009-07-30 09:48:10.073009918 -0400
21599@@ -57,14 +57,14 @@ struct btrfs_iget_args {
21600 struct btrfs_root *root;
21601 };
21602
21603-static struct inode_operations btrfs_dir_inode_operations;
21604-static struct inode_operations btrfs_symlink_inode_operations;
21605-static struct inode_operations btrfs_dir_ro_inode_operations;
21606-static struct inode_operations btrfs_special_inode_operations;
21607-static struct inode_operations btrfs_file_inode_operations;
21608-static struct address_space_operations btrfs_aops;
21609-static struct address_space_operations btrfs_symlink_aops;
21610-static struct file_operations btrfs_dir_file_operations;
21611+static const struct inode_operations btrfs_dir_inode_operations;
21612+static const struct inode_operations btrfs_symlink_inode_operations;
21613+static const struct inode_operations btrfs_dir_ro_inode_operations;
21614+static const struct inode_operations btrfs_special_inode_operations;
21615+static const struct inode_operations btrfs_file_inode_operations;
21616+static const struct address_space_operations btrfs_aops;
21617+static const struct address_space_operations btrfs_symlink_aops;
21618+static const struct file_operations btrfs_dir_file_operations;
21619 static struct extent_io_ops btrfs_extent_io_ops;
21620
21621 static struct kmem_cache *btrfs_inode_cachep;
21622@@ -5187,7 +5187,7 @@ static int btrfs_permission(struct inode
21623 return generic_permission(inode, mask, btrfs_check_acl);
21624 }
21625
21626-static struct inode_operations btrfs_dir_inode_operations = {
21627+static const struct inode_operations btrfs_dir_inode_operations = {
21628 .getattr = btrfs_getattr,
21629 .lookup = btrfs_lookup,
21630 .create = btrfs_create,
21631@@ -5205,11 +5205,11 @@ static struct inode_operations btrfs_dir
21632 .removexattr = btrfs_removexattr,
21633 .permission = btrfs_permission,
21634 };
21635-static struct inode_operations btrfs_dir_ro_inode_operations = {
21636+static const struct inode_operations btrfs_dir_ro_inode_operations = {
21637 .lookup = btrfs_lookup,
21638 .permission = btrfs_permission,
21639 };
21640-static struct file_operations btrfs_dir_file_operations = {
21641+static const struct file_operations btrfs_dir_file_operations = {
21642 .llseek = generic_file_llseek,
21643 .read = generic_read_dir,
21644 .readdir = btrfs_real_readdir,
21645@@ -5245,7 +5245,7 @@ static struct extent_io_ops btrfs_extent
21646 *
21647 * For now we're avoiding this by dropping bmap.
21648 */
21649-static struct address_space_operations btrfs_aops = {
21650+static const struct address_space_operations btrfs_aops = {
21651 .readpage = btrfs_readpage,
21652 .writepage = btrfs_writepage,
21653 .writepages = btrfs_writepages,
21654@@ -5257,14 +5257,14 @@ static struct address_space_operations b
21655 .set_page_dirty = btrfs_set_page_dirty,
21656 };
21657
21658-static struct address_space_operations btrfs_symlink_aops = {
21659+static const struct address_space_operations btrfs_symlink_aops = {
21660 .readpage = btrfs_readpage,
21661 .writepage = btrfs_writepage,
21662 .invalidatepage = btrfs_invalidatepage,
21663 .releasepage = btrfs_releasepage,
21664 };
21665
21666-static struct inode_operations btrfs_file_inode_operations = {
21667+static const struct inode_operations btrfs_file_inode_operations = {
21668 .truncate = btrfs_truncate,
21669 .getattr = btrfs_getattr,
21670 .setattr = btrfs_setattr,
21671@@ -5276,7 +5276,7 @@ static struct inode_operations btrfs_fil
21672 .fallocate = btrfs_fallocate,
21673 .fiemap = btrfs_fiemap,
21674 };
21675-static struct inode_operations btrfs_special_inode_operations = {
21676+static const struct inode_operations btrfs_special_inode_operations = {
21677 .getattr = btrfs_getattr,
21678 .setattr = btrfs_setattr,
21679 .permission = btrfs_permission,
21680@@ -5285,7 +5285,7 @@ static struct inode_operations btrfs_spe
21681 .listxattr = btrfs_listxattr,
21682 .removexattr = btrfs_removexattr,
21683 };
21684-static struct inode_operations btrfs_symlink_inode_operations = {
21685+static const struct inode_operations btrfs_symlink_inode_operations = {
21686 .readlink = generic_readlink,
21687 .follow_link = page_follow_link_light,
21688 .put_link = page_put_link,
21689diff -urNp linux-2.6.30.4/fs/btrfs/super.c linux-2.6.30.4/fs/btrfs/super.c
21690--- linux-2.6.30.4/fs/btrfs/super.c 2009-07-24 17:47:51.000000000 -0400
21691+++ linux-2.6.30.4/fs/btrfs/super.c 2009-07-30 09:48:10.074085184 -0400
21692@@ -53,7 +53,7 @@
21693 #include "compression.h"
21694
21695
21696-static struct super_operations btrfs_super_ops;
21697+static const struct super_operations btrfs_super_ops;
21698
21699 static void btrfs_put_super(struct super_block *sb)
21700 {
21701@@ -675,7 +675,7 @@ static int btrfs_unfreeze(struct super_b
21702 return 0;
21703 }
21704
21705-static struct super_operations btrfs_super_ops = {
21706+static const struct super_operations btrfs_super_ops = {
21707 .delete_inode = btrfs_delete_inode,
21708 .put_super = btrfs_put_super,
21709 .write_super = btrfs_write_super,
21710diff -urNp linux-2.6.30.4/fs/buffer.c linux-2.6.30.4/fs/buffer.c
21711--- linux-2.6.30.4/fs/buffer.c 2009-07-24 17:47:51.000000000 -0400
21712+++ linux-2.6.30.4/fs/buffer.c 2009-07-30 11:10:49.132480423 -0400
2380c486
JR
21713@@ -25,6 +25,7 @@
21714 #include <linux/percpu.h>
21715 #include <linux/slab.h>
21716 #include <linux/capability.h>
21717+#include <linux/security.h>
21718 #include <linux/blkdev.h>
21719 #include <linux/file.h>
21720 #include <linux/quotaops.h>
017d2877 21721@@ -2230,6 +2231,7 @@ int generic_cont_expand_simple(struct in
2380c486
JR
21722
21723 err = -EFBIG;
21724 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
21725+ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
21726 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
21727 send_sig(SIGXFSZ, current, 0);
21728 goto out;
017d2877
AM
21729diff -urNp linux-2.6.30.4/fs/cifs/cifs_dfs_ref.c linux-2.6.30.4/fs/cifs/cifs_dfs_ref.c
21730--- linux-2.6.30.4/fs/cifs/cifs_dfs_ref.c 2009-07-24 17:47:51.000000000 -0400
21731+++ linux-2.6.30.4/fs/cifs/cifs_dfs_ref.c 2009-07-30 09:48:10.074085184 -0400
21732@@ -379,7 +379,7 @@ out_err:
21733 goto out;
21734 }
21735
21736-struct inode_operations cifs_dfs_referral_inode_operations = {
21737+const struct inode_operations cifs_dfs_referral_inode_operations = {
21738 .follow_link = cifs_dfs_follow_mountpoint,
21739 };
21740
21741diff -urNp linux-2.6.30.4/fs/cifs/cifsfs.h linux-2.6.30.4/fs/cifs/cifsfs.h
21742--- linux-2.6.30.4/fs/cifs/cifsfs.h 2009-07-24 17:47:51.000000000 -0400
21743+++ linux-2.6.30.4/fs/cifs/cifsfs.h 2009-07-30 09:48:10.075044089 -0400
21744@@ -54,7 +54,7 @@ extern int cifs_setattr(struct dentry *,
21745
21746 extern const struct inode_operations cifs_file_inode_ops;
21747 extern const struct inode_operations cifs_symlink_inode_ops;
21748-extern struct inode_operations cifs_dfs_referral_inode_operations;
21749+extern const struct inode_operations cifs_dfs_referral_inode_operations;
21750
21751
21752 /* Functions related to files and directories */
21753diff -urNp linux-2.6.30.4/fs/cifs/cifs_uniupr.h linux-2.6.30.4/fs/cifs/cifs_uniupr.h
21754--- linux-2.6.30.4/fs/cifs/cifs_uniupr.h 2009-07-24 17:47:51.000000000 -0400
21755+++ linux-2.6.30.4/fs/cifs/cifs_uniupr.h 2009-07-30 09:48:10.074085184 -0400
2380c486
JR
21756@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
21757 {0x0490, 0x04cc, UniCaseRangeU0490},
21758 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
21759 {0xff40, 0xff5a, UniCaseRangeUff40},
21760- {0}
21761+ {0, 0, NULL}
21762 };
21763 #endif
21764
017d2877
AM
21765diff -urNp linux-2.6.30.4/fs/cifs/link.c linux-2.6.30.4/fs/cifs/link.c
21766--- linux-2.6.30.4/fs/cifs/link.c 2009-07-24 17:47:51.000000000 -0400
21767+++ linux-2.6.30.4/fs/cifs/link.c 2009-07-30 09:48:10.075668043 -0400
21768@@ -214,7 +214,7 @@ cifs_symlink(struct inode *inode, struct
2380c486
JR
21769
21770 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
21771 {
21772- char *p = nd_get_link(nd);
21773+ const char *p = nd_get_link(nd);
21774 if (!IS_ERR(p))
21775 kfree(p);
21776 }
017d2877
AM
21777diff -urNp linux-2.6.30.4/fs/compat.c linux-2.6.30.4/fs/compat.c
21778--- linux-2.6.30.4/fs/compat.c 2009-07-24 17:47:51.000000000 -0400
21779+++ linux-2.6.30.4/fs/compat.c 2009-07-30 11:10:49.133453691 -0400
21780@@ -1420,14 +1420,12 @@ static int compat_copy_strings(int argc,
2380c486
JR
21781 if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
21782 struct page *page;
21783
21784-#ifdef CONFIG_STACK_GROWSUP
21785 ret = expand_stack_downwards(bprm->vma, pos);
21786 if (ret < 0) {
21787 /* We've exceed the stack rlimit. */
21788 ret = -E2BIG;
21789 goto out;
21790 }
21791-#endif
21792 ret = get_user_pages(current, bprm->mm, pos,
21793 1, 1, 1, &page, NULL);
21794 if (ret <= 0) {
017d2877 21795@@ -1473,6 +1471,11 @@ int compat_do_execve(char * filename,
2380c486
JR
21796 compat_uptr_t __user *envp,
21797 struct pt_regs * regs)
21798 {
21799+#ifdef CONFIG_GRKERNSEC
21800+ struct file *old_exec_file;
21801+ struct acl_subject_label *old_acl;
21802+ struct rlimit old_rlim[RLIM_NLIMITS];
21803+#endif
21804 struct linux_binprm *bprm;
21805 struct file *file;
de855c5d 21806 struct files_struct *displaced;
017d2877 21807@@ -1514,6 +1517,14 @@ int compat_do_execve(char * filename,
2380c486
JR
21808 bprm->filename = filename;
21809 bprm->interp = filename;
21810
21811+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->cred->user->processes), 1);
21812+ retval = -EAGAIN;
21813+ if (gr_handle_nproc())
21814+ goto out_file;
21815+ retval = -EACCES;
21816+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
21817+ goto out_file;
21818+
21819 retval = bprm_mm_init(bprm);
21820 if (retval)
21821 goto out_file;
017d2877 21822@@ -1543,9 +1554,40 @@ int compat_do_execve(char * filename,
2380c486
JR
21823 if (retval < 0)
21824 goto out;
21825
21826+ if (!gr_tpe_allow(file)) {
21827+ retval = -EACCES;
21828+ goto out;
21829+ }
21830+
21831+ if (gr_check_crash_exec(file)) {
21832+ retval = -EACCES;
21833+ goto out;
21834+ }
21835+
21836+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
21837+
21838+ gr_handle_exec_args(bprm, (char __user * __user *)argv);
21839+
21840+#ifdef CONFIG_GRKERNSEC
21841+ old_acl = current->acl;
21842+ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
21843+ old_exec_file = current->exec_file;
21844+ get_file(file);
21845+ current->exec_file = file;
21846+#endif
21847+
de855c5d
AM
21848+ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
21849+ bprm->unsafe & LSM_UNSAFE_SHARE);
2380c486
JR
21850+ if (retval < 0)
21851+ goto out_fail;
21852+
21853 retval = search_binary_handler(bprm, regs);
21854 if (retval < 0)
21855- goto out;
21856+ goto out_fail;
21857+#ifdef CONFIG_GRKERNSEC
21858+ if (old_exec_file)
21859+ fput(old_exec_file);
21860+#endif
21861
21862 /* execve succeeded */
de855c5d 21863 current->fs->in_exec = 0;
017d2877 21864@@ -1557,6 +1599,14 @@ int compat_do_execve(char * filename,
de855c5d 21865 put_files_struct(displaced);
2380c486
JR
21866 return retval;
21867
21868+out_fail:
21869+#ifdef CONFIG_GRKERNSEC
21870+ current->acl = old_acl;
21871+ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
21872+ fput(current->exec_file);
21873+ current->exec_file = old_exec_file;
21874+#endif
21875+
21876 out:
21877 if (bprm->mm)
21878 mmput(bprm->mm);
017d2877
AM
21879diff -urNp linux-2.6.30.4/fs/compat_ioctl.c linux-2.6.30.4/fs/compat_ioctl.c
21880--- linux-2.6.30.4/fs/compat_ioctl.c 2009-07-24 17:47:51.000000000 -0400
21881+++ linux-2.6.30.4/fs/compat_ioctl.c 2009-07-30 09:48:10.080197700 -0400
21882@@ -1837,15 +1837,15 @@ struct ioctl_trans {
2380c486
JR
21883 };
21884
21885 #define HANDLE_IOCTL(cmd,handler) \
21886- { (cmd), (ioctl_trans_handler_t)(handler) },
21887+ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
21888
21889 /* pointer to compatible structure or no argument */
21890 #define COMPATIBLE_IOCTL(cmd) \
21891- { (cmd), do_ioctl32_pointer },
21892+ { (cmd), do_ioctl32_pointer, NULL },
21893
21894 /* argument is an unsigned long integer, not a pointer */
21895 #define ULONG_IOCTL(cmd) \
21896- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
21897+ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
21898
21899 /* ioctl should not be warned about even if it's not implemented.
21900 Valid reasons to use this:
017d2877
AM
21901diff -urNp linux-2.6.30.4/fs/debugfs/inode.c linux-2.6.30.4/fs/debugfs/inode.c
21902--- linux-2.6.30.4/fs/debugfs/inode.c 2009-07-24 17:47:51.000000000 -0400
21903+++ linux-2.6.30.4/fs/debugfs/inode.c 2009-07-30 09:48:10.080909461 -0400
21904@@ -118,7 +118,7 @@ static inline int debugfs_positive(struc
2380c486
JR
21905
21906 static int debug_fill_super(struct super_block *sb, void *data, int silent)
21907 {
21908- static struct tree_descr debug_files[] = {{""}};
21909+ static struct tree_descr debug_files[] = {{"", NULL, 0}};
21910
21911 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
21912 }
017d2877
AM
21913diff -urNp linux-2.6.30.4/fs/dlm/debug_fs.c linux-2.6.30.4/fs/dlm/debug_fs.c
21914--- linux-2.6.30.4/fs/dlm/debug_fs.c 2009-07-24 17:47:51.000000000 -0400
21915+++ linux-2.6.30.4/fs/dlm/debug_fs.c 2009-07-30 09:48:10.080909461 -0400
21916@@ -386,9 +386,9 @@ static int table_seq_show(struct seq_fil
21917 return rv;
21918 }
21919
21920-static struct seq_operations format1_seq_ops;
21921-static struct seq_operations format2_seq_ops;
21922-static struct seq_operations format3_seq_ops;
21923+static const struct seq_operations format1_seq_ops;
21924+static const struct seq_operations format2_seq_ops;
21925+static const struct seq_operations format3_seq_ops;
21926
21927 static void *table_seq_start(struct seq_file *seq, loff_t *pos)
21928 {
21929@@ -534,21 +534,21 @@ static void table_seq_stop(struct seq_fi
21930 }
21931 }
21932
21933-static struct seq_operations format1_seq_ops = {
21934+static const struct seq_operations format1_seq_ops = {
21935 .start = table_seq_start,
21936 .next = table_seq_next,
21937 .stop = table_seq_stop,
21938 .show = table_seq_show,
21939 };
21940
21941-static struct seq_operations format2_seq_ops = {
21942+static const struct seq_operations format2_seq_ops = {
21943 .start = table_seq_start,
21944 .next = table_seq_next,
21945 .stop = table_seq_stop,
21946 .show = table_seq_show,
21947 };
21948
21949-static struct seq_operations format3_seq_ops = {
21950+static const struct seq_operations format3_seq_ops = {
21951 .start = table_seq_start,
21952 .next = table_seq_next,
21953 .stop = table_seq_stop,
21954diff -urNp linux-2.6.30.4/fs/ecryptfs/ecryptfs_kernel.h linux-2.6.30.4/fs/ecryptfs/ecryptfs_kernel.h
21955--- linux-2.6.30.4/fs/ecryptfs/ecryptfs_kernel.h 2009-07-24 17:47:51.000000000 -0400
21956+++ linux-2.6.30.4/fs/ecryptfs/ecryptfs_kernel.h 2009-07-30 12:43:20.416601232 -0400
21957@@ -582,7 +582,7 @@ extern const struct inode_operations ecr
21958 extern const struct inode_operations ecryptfs_symlink_iops;
21959 extern const struct super_operations ecryptfs_sops;
21960 extern const struct dentry_operations ecryptfs_dops;
21961-extern struct address_space_operations ecryptfs_aops;
21962+extern const struct address_space_operations ecryptfs_aops;
21963 extern int ecryptfs_verbosity;
21964 extern unsigned int ecryptfs_message_buf_len;
21965 extern signed long ecryptfs_message_wait_timeout;
21966diff -urNp linux-2.6.30.4/fs/ecryptfs/mmap.c linux-2.6.30.4/fs/ecryptfs/mmap.c
21967--- linux-2.6.30.4/fs/ecryptfs/mmap.c 2009-07-24 17:47:51.000000000 -0400
21968+++ linux-2.6.30.4/fs/ecryptfs/mmap.c 2009-07-30 09:48:10.080909461 -0400
21969@@ -545,7 +545,7 @@ static sector_t ecryptfs_bmap(struct add
21970 return rc;
21971 }
21972
21973-struct address_space_operations ecryptfs_aops = {
21974+const struct address_space_operations ecryptfs_aops = {
21975 .writepage = ecryptfs_writepage,
21976 .readpage = ecryptfs_readpage,
21977 .write_begin = ecryptfs_write_begin,
21978diff -urNp linux-2.6.30.4/fs/exec.c linux-2.6.30.4/fs/exec.c
21979--- linux-2.6.30.4/fs/exec.c 2009-07-24 17:47:51.000000000 -0400
21980+++ linux-2.6.30.4/fs/exec.c 2009-07-30 11:10:49.146300194 -0400
21981@@ -54,12 +54,24 @@
2380c486
JR
21982 #include <linux/kmod.h>
21983 #include <linux/fsnotify.h>
017d2877 21984 #include <linux/fs_struct.h>
2380c486
JR
21985+#include <linux/random.h>
21986+#include <linux/seq_file.h>
21987+
21988+#ifdef CONFIG_PAX_REFCOUNT
21989+#include <linux/kallsyms.h>
21990+#include <linux/kdebug.h>
21991+#endif
21992
21993 #include <asm/uaccess.h>
21994 #include <asm/mmu_context.h>
21995 #include <asm/tlb.h>
21996 #include "internal.h"
21997
21998+#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
21999+void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
22000+EXPORT_SYMBOL(pax_set_initial_flags_func);
22001+#endif
22002+
22003 int core_uses_pid;
22004 char core_pattern[CORENAME_MAX_SIZE] = "core";
22005 int suid_dumpable = 0;
017d2877 22006@@ -160,18 +172,10 @@ static struct page *get_arg_page(struct
2380c486
JR
22007 int write)
22008 {
22009 struct page *page;
22010- int ret;
22011
22012-#ifdef CONFIG_STACK_GROWSUP
22013- if (write) {
22014- ret = expand_stack_downwards(bprm->vma, pos);
22015- if (ret < 0)
22016- return NULL;
22017- }
22018-#endif
22019- ret = get_user_pages(current, bprm->mm, pos,
22020- 1, write, 1, &page, NULL);
22021- if (ret <= 0)
22022+ if (0 > expand_stack_downwards(bprm->vma, pos))
22023+ return NULL;
22024+ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
22025 return NULL;
22026
22027 if (write) {
017d2877 22028@@ -243,6 +247,11 @@ static int __bprm_mm_init(struct linux_b
2380c486
JR
22029 vma->vm_end = STACK_TOP_MAX;
22030 vma->vm_start = vma->vm_end - PAGE_SIZE;
22031 vma->vm_flags = VM_STACK_FLAGS;
22032+
22033+#ifdef CONFIG_PAX_SEGMEXEC
22034+ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
22035+#endif
22036+
22037 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
22038 err = insert_vm_struct(mm, vma);
22039 if (err)
017d2877 22040@@ -251,6 +260,12 @@ static int __bprm_mm_init(struct linux_b
2380c486
JR
22041 mm->stack_vm = mm->total_vm = 1;
22042 up_write(&mm->mmap_sem);
22043 bprm->p = vma->vm_end - sizeof(void *);
22044+
22045+#ifdef CONFIG_PAX_RANDUSTACK
22046+ if (randomize_va_space)
22047+ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
22048+#endif
22049+
22050 return 0;
22051 err:
22052 up_write(&mm->mmap_sem);
017d2877 22053@@ -511,6 +526,10 @@ static int shift_arg_pages(struct vm_are
2380c486
JR
22054 if (vma != find_vma(mm, new_start))
22055 return -EFAULT;
22056
22057+#ifdef CONFIG_PAX_SEGMEXEC
22058+ BUG_ON(pax_find_mirror_vma(vma));
22059+#endif
22060+
22061 /*
22062 * cover the whole range: [new_start, old_end)
22063 */
017d2877 22064@@ -599,6 +618,14 @@ int setup_arg_pages(struct linux_binprm
2380c486
JR
22065 bprm->exec -= stack_shift;
22066
22067 down_write(&mm->mmap_sem);
22068+
22069+ /* Move stack pages down in memory. */
22070+ if (stack_shift) {
22071+ ret = shift_arg_pages(vma, stack_shift);
22072+ if (ret)
22073+ goto out_unlock;
22074+ }
22075+
22076 vm_flags = VM_STACK_FLAGS;
22077
22078 /*
017d2877 22079@@ -612,21 +639,24 @@ int setup_arg_pages(struct linux_binprm
2380c486
JR
22080 vm_flags &= ~VM_EXEC;
22081 vm_flags |= mm->def_flags;
22082
22083+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22084+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22085+ vm_flags &= ~VM_EXEC;
22086+
22087+#ifdef CONFIG_PAX_MPROTECT
22088+ if (mm->pax_flags & MF_PAX_MPROTECT)
22089+ vm_flags &= ~VM_MAYEXEC;
22090+#endif
22091+
22092+ }
22093+#endif
22094+
22095 ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
22096 vm_flags);
22097 if (ret)
22098 goto out_unlock;
22099 BUG_ON(prev != vma);
22100
22101- /* Move stack pages down in memory. */
22102- if (stack_shift) {
22103- ret = shift_arg_pages(vma, stack_shift);
22104- if (ret) {
22105- up_write(&mm->mmap_sem);
22106- return ret;
22107- }
22108- }
22109-
22110 #ifdef CONFIG_STACK_GROWSUP
22111 stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
22112 #else
017d2877 22113@@ -638,7 +668,7 @@ int setup_arg_pages(struct linux_binprm
2380c486
JR
22114
22115 out_unlock:
22116 up_write(&mm->mmap_sem);
22117- return 0;
22118+ return ret;
22119 }
22120 EXPORT_SYMBOL(setup_arg_pages);
22121
017d2877 22122@@ -1046,7 +1076,7 @@ int check_unsafe_exec(struct linux_binpr
de855c5d
AM
22123 }
22124 rcu_read_unlock();
22125
22126- if (p->fs->users > n_fs) {
22127+ if (atomic_read(&p->fs->users) > n_fs) {
22128 bprm->unsafe |= LSM_UNSAFE_SHARE;
22129 } else {
22130 res = -EAGAIN;
017d2877 22131@@ -1253,6 +1283,11 @@ int do_execve(char * filename,
2380c486
JR
22132 char __user *__user *envp,
22133 struct pt_regs * regs)
22134 {
22135+#ifdef CONFIG_GRKERNSEC
22136+ struct file *old_exec_file;
22137+ struct acl_subject_label *old_acl;
22138+ struct rlimit old_rlim[RLIM_NLIMITS];
22139+#endif
22140 struct linux_binprm *bprm;
22141 struct file *file;
22142 struct files_struct *displaced;
017d2877 22143@@ -1294,6 +1329,18 @@ int do_execve(char * filename,
de855c5d
AM
22144 bprm->filename = filename;
22145 bprm->interp = filename;
2380c486
JR
22146
22147+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->cred->user->processes), 1);
22148+
22149+ if (gr_handle_nproc()) {
de855c5d
AM
22150+ retval = -EAGAIN;
22151+ goto out_file;
2380c486
JR
22152+ }
22153+
22154+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
de855c5d
AM
22155+ retval = -EACCES;
22156+ goto out_file;
2380c486
JR
22157+ }
22158+
de855c5d
AM
22159 retval = bprm_mm_init(bprm);
22160 if (retval)
22161 goto out_file;
017d2877 22162@@ -1323,10 +1370,41 @@ int do_execve(char * filename,
2380c486
JR
22163 if (retval < 0)
22164 goto out;
22165
22166+ if (!gr_tpe_allow(file)) {
22167+ retval = -EACCES;
22168+ goto out;
22169+ }
22170+
22171+ if (gr_check_crash_exec(file)) {
22172+ retval = -EACCES;
22173+ goto out;
22174+ }
22175+
22176+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
22177+
22178+ gr_handle_exec_args(bprm, argv);
22179+
22180+#ifdef CONFIG_GRKERNSEC
22181+ old_acl = current->acl;
22182+ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
22183+ old_exec_file = current->exec_file;
22184+ get_file(file);
22185+ current->exec_file = file;
22186+#endif
22187+
de855c5d
AM
22188+ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
22189+ bprm->unsafe & LSM_UNSAFE_SHARE);
2380c486
JR
22190+ if (retval < 0)
22191+ goto out_fail;
22192+
22193 current->flags &= ~PF_KTHREAD;
22194 retval = search_binary_handler(bprm,regs);
22195 if (retval < 0)
22196- goto out;
22197+ goto out_fail;
22198+#ifdef CONFIG_GRKERNSEC
22199+ if (old_exec_file)
22200+ fput(old_exec_file);
22201+#endif
22202
22203 /* execve succeeded */
de855c5d 22204 current->fs->in_exec = 0;
017d2877 22205@@ -1338,6 +1416,14 @@ int do_execve(char * filename,
2380c486
JR
22206 put_files_struct(displaced);
22207 return retval;
22208
22209+out_fail:
22210+#ifdef CONFIG_GRKERNSEC
22211+ current->acl = old_acl;
22212+ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
22213+ fput(current->exec_file);
22214+ current->exec_file = old_exec_file;
22215+#endif
22216+
22217 out:
22218 if (bprm->mm)
22219 mmput (bprm->mm);
017d2877 22220@@ -1506,6 +1592,164 @@ out:
2380c486
JR
22221 return ispipe;
22222 }
22223
22224+int pax_check_flags(unsigned long *flags)
22225+{
22226+ int retval = 0;
22227+
22228+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
22229+ if (*flags & MF_PAX_SEGMEXEC)
22230+ {
22231+ *flags &= ~MF_PAX_SEGMEXEC;
22232+ retval = -EINVAL;
22233+ }
22234+#endif
22235+
22236+ if ((*flags & MF_PAX_PAGEEXEC)
22237+
22238+#ifdef CONFIG_PAX_PAGEEXEC
22239+ && (*flags & MF_PAX_SEGMEXEC)
22240+#endif
22241+
22242+ )
22243+ {
22244+ *flags &= ~MF_PAX_PAGEEXEC;
22245+ retval = -EINVAL;
22246+ }
22247+
22248+ if ((*flags & MF_PAX_MPROTECT)
22249+
22250+#ifdef CONFIG_PAX_MPROTECT
22251+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
22252+#endif
22253+
22254+ )
22255+ {
22256+ *flags &= ~MF_PAX_MPROTECT;
22257+ retval = -EINVAL;
22258+ }
22259+
22260+ if ((*flags & MF_PAX_EMUTRAMP)
22261+
22262+#ifdef CONFIG_PAX_EMUTRAMP
22263+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
22264+#endif
22265+
22266+ )
22267+ {
22268+ *flags &= ~MF_PAX_EMUTRAMP;
22269+ retval = -EINVAL;
22270+ }
22271+
22272+ return retval;
22273+}
22274+
22275+EXPORT_SYMBOL(pax_check_flags);
22276+
22277+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22278+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
22279+{
22280+ struct task_struct *tsk = current;
22281+ struct mm_struct *mm = current->mm;
22282+ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
22283+ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
22284+ char *path_exec = NULL;
22285+ char *path_fault = NULL;
22286+ unsigned long start = 0UL, end = 0UL, offset = 0UL;
22287+
22288+ if (buffer_exec && buffer_fault) {
22289+ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
22290+
22291+ down_read(&mm->mmap_sem);
22292+ vma = mm->mmap;
22293+ while (vma && (!vma_exec || !vma_fault)) {
22294+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
22295+ vma_exec = vma;
22296+ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
22297+ vma_fault = vma;
22298+ vma = vma->vm_next;
22299+ }
22300+ if (vma_exec) {
22301+ path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
22302+ if (IS_ERR(path_exec))
22303+ path_exec = "<path too long>";
22304+ else {
de855c5d
AM
22305+ path_exec = mangle_path(buffer_exec, path_exec, "\t\n\\");
22306+ if (path_exec) {
22307+ *path_exec = 0;
22308+ path_exec = buffer_exec;
22309+ } else
22310+ path_exec = "<path too long>";
2380c486
JR
22311+ }
22312+ }
22313+ if (vma_fault) {
22314+ start = vma_fault->vm_start;
22315+ end = vma_fault->vm_end;
22316+ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
22317+ if (vma_fault->vm_file) {
22318+ path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
22319+ if (IS_ERR(path_fault))
22320+ path_fault = "<path too long>";
22321+ else {
de855c5d
AM
22322+ path_fault = mangle_path(buffer_fault, path_fault, "\t\n\\");
22323+ if (path_fault) {
22324+ *path_fault = 0;
22325+ path_fault = buffer_fault;
22326+ } else
22327+ path_fault = "<path too long>";
2380c486
JR
22328+ }
22329+ } else
22330+ path_fault = "<anonymous mapping>";
22331+ }
22332+ up_read(&mm->mmap_sem);
22333+ }
22334+ if (tsk->signal->curr_ip)
22335+ 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);
22336+ else
22337+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
22338+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
22339+ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
22340+ task_uid(tsk), task_euid(tsk), pc, sp);
22341+ free_page((unsigned long)buffer_exec);
22342+ free_page((unsigned long)buffer_fault);
22343+ pax_report_insns(pc, sp);
22344+ do_coredump(SIGKILL, SIGKILL, regs);
22345+}
22346+#endif
22347+
22348+#ifdef CONFIG_PAX_REFCOUNT
22349+void pax_report_refcount_overflow(struct pt_regs *regs)
22350+{
22351+ if (current->signal->curr_ip)
22352+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
22353+ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current_uid(), current_euid());
22354+ else
22355+ printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
22356+ current->comm, task_pid_nr(current), current_uid(), current_euid());
22357+ print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
22358+ show_registers(regs);
22359+ force_sig_specific(SIGKILL, current);
22360+}
22361+#endif
de855c5d
AM
22362+
22363+#ifdef CONFIG_PAX_USERCOPY
22364+void pax_report_leak_to_user(const void *ptr, unsigned long len)
22365+{
22366+ if (current->signal->curr_ip)
22367+ 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);
22368+ else
22369+ printk(KERN_ERR "PAX: kernel memory leak attempt detected from %p (%lu bytes)\n", ptr, len);
22370+ dump_stack();
22371+ do_group_exit(SIGKILL);
22372+}
22373+
22374+void pax_report_overflow_from_user(const void *ptr, unsigned long len)
22375+{
22376+ printk(KERN_ERR "PAX: kernel memory overflow attempt detected to %p (%lu bytes)\n", ptr, len);
22377+ dump_stack();
22378+ do_group_exit(SIGKILL);
22379+}
22380+#endif
2380c486
JR
22381+
22382 static int zap_process(struct task_struct *start)
22383 {
22384 struct task_struct *t;
017d2877 22385@@ -1765,6 +2009,10 @@ void do_coredump(long signr, int exit_co
2380c486
JR
22386 */
22387 clear_thread_flag(TIF_SIGPENDING);
22388
22389+ if (signr == SIGKILL || signr == SIGILL)
22390+ gr_handle_brute_attach(current);
22391+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
22392+
22393 /*
22394 * lock_kernel() because format_corename() is controlled by sysctl, which
22395 * uses lock_kernel()
017d2877
AM
22396diff -urNp linux-2.6.30.4/fs/ext2/balloc.c linux-2.6.30.4/fs/ext2/balloc.c
22397--- linux-2.6.30.4/fs/ext2/balloc.c 2009-07-24 17:47:51.000000000 -0400
22398+++ linux-2.6.30.4/fs/ext2/balloc.c 2009-07-30 11:10:49.161377797 -0400
2380c486
JR
22399@@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
22400
22401 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
22402 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
22403- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
22404+ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
22405 sbi->s_resuid != current_fsuid() &&
22406 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
22407 return 0;
017d2877
AM
22408diff -urNp linux-2.6.30.4/fs/ext3/balloc.c linux-2.6.30.4/fs/ext3/balloc.c
22409--- linux-2.6.30.4/fs/ext3/balloc.c 2009-07-24 17:47:51.000000000 -0400
22410+++ linux-2.6.30.4/fs/ext3/balloc.c 2009-07-30 11:10:49.178426808 -0400
de855c5d 22411@@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e
2380c486 22412
de855c5d
AM
22413 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
22414 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
22415- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
22416+ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
22417 sbi->s_resuid != current_fsuid() &&
22418 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
22419 return 0;
017d2877
AM
22420diff -urNp linux-2.6.30.4/fs/ext3/namei.c linux-2.6.30.4/fs/ext3/namei.c
22421--- linux-2.6.30.4/fs/ext3/namei.c 2009-07-24 17:47:51.000000000 -0400
22422+++ linux-2.6.30.4/fs/ext3/namei.c 2009-07-30 09:48:10.082882469 -0400
22423@@ -1168,7 +1168,7 @@ static struct ext3_dir_entry_2 *do_split
2380c486
JR
22424 char *data1 = (*bh)->b_data, *data2;
22425 unsigned split, move, size;
22426 struct ext3_dir_entry_2 *de = NULL, *de2;
22427- int err = 0, i;
22428+ int i, err = 0;
22429
22430 bh2 = ext3_append (handle, dir, &newblock, &err);
22431 if (!(bh2)) {
017d2877
AM
22432diff -urNp linux-2.6.30.4/fs/ext3/xattr.c linux-2.6.30.4/fs/ext3/xattr.c
22433--- linux-2.6.30.4/fs/ext3/xattr.c 2009-07-24 17:47:51.000000000 -0400
22434+++ linux-2.6.30.4/fs/ext3/xattr.c 2009-07-30 09:48:10.082882469 -0400
2380c486
JR
22435@@ -89,8 +89,8 @@
22436 printk("\n"); \
22437 } while (0)
22438 #else
22439-# define ea_idebug(f...)
22440-# define ea_bdebug(f...)
22441+# define ea_idebug(f...) do {} while (0)
22442+# define ea_bdebug(f...) do {} while (0)
22443 #endif
22444
22445 static void ext3_xattr_cache_insert(struct buffer_head *);
017d2877
AM
22446diff -urNp linux-2.6.30.4/fs/ext4/balloc.c linux-2.6.30.4/fs/ext4/balloc.c
22447--- linux-2.6.30.4/fs/ext4/balloc.c 2009-07-24 17:47:51.000000000 -0400
22448+++ linux-2.6.30.4/fs/ext4/balloc.c 2009-07-30 11:10:49.209900020 -0400
22449@@ -573,7 +573,7 @@ int ext4_has_free_blocks(struct ext4_sb_
2380c486
JR
22450 /* Hm, nope. Are (enough) root reserved blocks available? */
22451 if (sbi->s_resuid == current_fsuid() ||
22452 ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) ||
22453- capable(CAP_SYS_RESOURCE)) {
22454+ capable_nolog(CAP_SYS_RESOURCE)) {
22455 if (free_blocks >= (nblocks + dirty_blocks))
22456 return 1;
22457 }
017d2877
AM
22458diff -urNp linux-2.6.30.4/fs/ext4/file.c linux-2.6.30.4/fs/ext4/file.c
22459--- linux-2.6.30.4/fs/ext4/file.c 2009-07-24 17:47:51.000000000 -0400
22460+++ linux-2.6.30.4/fs/ext4/file.c 2009-07-30 09:48:10.082882469 -0400
22461@@ -128,7 +128,7 @@ force_commit:
22462 return ret;
22463 }
22464
22465-static struct vm_operations_struct ext4_file_vm_ops = {
22466+static const struct vm_operations_struct ext4_file_vm_ops = {
22467 .fault = filemap_fault,
22468 .page_mkwrite = ext4_page_mkwrite,
22469 };
22470diff -urNp linux-2.6.30.4/fs/ext4/mballoc.c linux-2.6.30.4/fs/ext4/mballoc.c
22471--- linux-2.6.30.4/fs/ext4/mballoc.c 2009-07-24 17:47:51.000000000 -0400
22472+++ linux-2.6.30.4/fs/ext4/mballoc.c 2009-07-30 09:48:10.083824497 -0400
22473@@ -2221,7 +2221,7 @@ static void ext4_mb_seq_history_stop(str
22474 {
22475 }
22476
22477-static struct seq_operations ext4_mb_seq_history_ops = {
22478+static const struct seq_operations ext4_mb_seq_history_ops = {
22479 .start = ext4_mb_seq_history_start,
22480 .next = ext4_mb_seq_history_next,
22481 .stop = ext4_mb_seq_history_stop,
22482@@ -2303,7 +2303,7 @@ static ssize_t ext4_mb_seq_history_write
22483 return count;
22484 }
22485
22486-static struct file_operations ext4_mb_seq_history_fops = {
22487+static const struct file_operations ext4_mb_seq_history_fops = {
22488 .owner = THIS_MODULE,
22489 .open = ext4_mb_seq_history_open,
22490 .read = seq_read,
22491@@ -2385,7 +2385,7 @@ static void ext4_mb_seq_groups_stop(stru
22492 {
22493 }
22494
22495-static struct seq_operations ext4_mb_seq_groups_ops = {
22496+static const struct seq_operations ext4_mb_seq_groups_ops = {
22497 .start = ext4_mb_seq_groups_start,
22498 .next = ext4_mb_seq_groups_next,
22499 .stop = ext4_mb_seq_groups_stop,
22500@@ -2406,7 +2406,7 @@ static int ext4_mb_seq_groups_open(struc
22501
22502 }
22503
22504-static struct file_operations ext4_mb_seq_groups_fops = {
22505+static const struct file_operations ext4_mb_seq_groups_fops = {
22506 .owner = THIS_MODULE,
22507 .open = ext4_mb_seq_groups_open,
22508 .read = seq_read,
22509diff -urNp linux-2.6.30.4/fs/ext4/namei.c linux-2.6.30.4/fs/ext4/namei.c
22510--- linux-2.6.30.4/fs/ext4/namei.c 2009-07-24 17:47:51.000000000 -0400
22511+++ linux-2.6.30.4/fs/ext4/namei.c 2009-07-30 09:48:10.084769862 -0400
22512@@ -1203,7 +1203,7 @@ static struct ext4_dir_entry_2 *do_split
2380c486
JR
22513 char *data1 = (*bh)->b_data, *data2;
22514 unsigned split, move, size;
22515 struct ext4_dir_entry_2 *de = NULL, *de2;
22516- int err = 0, i;
22517+ int i, err = 0;
22518
22519 bh2 = ext4_append (handle, dir, &newblock, &err);
22520 if (!(bh2)) {
017d2877
AM
22521diff -urNp linux-2.6.30.4/fs/fcntl.c linux-2.6.30.4/fs/fcntl.c
22522--- linux-2.6.30.4/fs/fcntl.c 2009-07-24 17:47:51.000000000 -0400
22523+++ linux-2.6.30.4/fs/fcntl.c 2009-07-30 11:10:49.218051199 -0400
de855c5d 22524@@ -269,6 +269,7 @@ static long do_fcntl(int fd, unsigned in
2380c486
JR
22525 switch (cmd) {
22526 case F_DUPFD:
22527 case F_DUPFD_CLOEXEC:
22528+ gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
22529 if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
22530 break;
22531 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
de855c5d 22532@@ -419,7 +420,8 @@ static inline int sigio_perm(struct task
2380c486
JR
22533 ret = ((fown->euid == 0 ||
22534 fown->euid == cred->suid || fown->euid == cred->uid ||
22535 fown->uid == cred->suid || fown->uid == cred->uid) &&
22536- !security_file_send_sigiotask(p, fown, sig));
22537+ !security_file_send_sigiotask(p, fown, sig) &&
22538+ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
22539 rcu_read_unlock();
22540 return ret;
22541 }
017d2877
AM
22542diff -urNp linux-2.6.30.4/fs/file.c linux-2.6.30.4/fs/file.c
22543--- linux-2.6.30.4/fs/file.c 2009-07-24 17:47:51.000000000 -0400
22544+++ linux-2.6.30.4/fs/file.c 2009-07-30 11:10:49.226664348 -0400
2380c486
JR
22545@@ -13,6 +13,7 @@
22546 #include <linux/slab.h>
22547 #include <linux/vmalloc.h>
22548 #include <linux/file.h>
22549+#include <linux/security.h>
22550 #include <linux/fdtable.h>
22551 #include <linux/bitops.h>
22552 #include <linux/interrupt.h>
22553@@ -256,6 +257,8 @@ int expand_files(struct files_struct *fi
22554 * N.B. For clone tasks sharing a files structure, this test
22555 * will limit the total number of files that can be opened.
22556 */
22557+
22558+ gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
22559 if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
22560 return -EMFILE;
22561
017d2877
AM
22562diff -urNp linux-2.6.30.4/fs/fs_struct.c linux-2.6.30.4/fs/fs_struct.c
22563--- linux-2.6.30.4/fs/fs_struct.c 2009-07-24 17:47:51.000000000 -0400
22564+++ linux-2.6.30.4/fs/fs_struct.c 2009-07-30 09:48:10.084769862 -0400
22565@@ -89,7 +89,7 @@ void exit_fs(struct task_struct *tsk)
de855c5d
AM
22566 task_lock(tsk);
22567 write_lock(&fs->lock);
22568 tsk->fs = NULL;
22569- kill = !--fs->users;
22570+ kill = !atomic_dec_return(&fs->users);
22571 write_unlock(&fs->lock);
22572 task_unlock(tsk);
22573 if (kill)
017d2877 22574@@ -102,7 +102,7 @@ struct fs_struct *copy_fs_struct(struct
de855c5d
AM
22575 struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
22576 /* We don't need to lock fs - think why ;-) */
22577 if (fs) {
22578- fs->users = 1;
22579+ atomic_set(&fs->users, 1);
22580 fs->in_exec = 0;
22581 rwlock_init(&fs->lock);
22582 fs->umask = old->umask;
017d2877 22583@@ -127,7 +127,7 @@ int unshare_fs_struct(void)
de855c5d
AM
22584
22585 task_lock(current);
22586 write_lock(&fs->lock);
22587- kill = !--fs->users;
22588+ kill = !atomic_dec_return(&fs->users);
22589 current->fs = new_fs;
22590 write_unlock(&fs->lock);
22591 task_unlock(current);
017d2877 22592@@ -147,7 +147,7 @@ EXPORT_SYMBOL(current_umask);
de855c5d
AM
22593
22594 /* to be mentioned only in INIT_TASK */
22595 struct fs_struct init_fs = {
22596- .users = 1,
22597+ .users = ATOMIC_INIT(1),
22598 .lock = __RW_LOCK_UNLOCKED(init_fs.lock),
22599 .umask = 0022,
22600 };
017d2877 22601@@ -162,12 +162,12 @@ void daemonize_fs_struct(void)
de855c5d
AM
22602 task_lock(current);
22603
22604 write_lock(&init_fs.lock);
22605- init_fs.users++;
22606+ atomic_inc(&init_fs.users);
22607 write_unlock(&init_fs.lock);
22608
22609 write_lock(&fs->lock);
22610 current->fs = &init_fs;
22611- kill = !--fs->users;
22612+ kill = !atomic_dec_return(&fs->users);
22613 write_unlock(&fs->lock);
22614
22615 task_unlock(current);
017d2877
AM
22616diff -urNp linux-2.6.30.4/fs/fuse/control.c linux-2.6.30.4/fs/fuse/control.c
22617--- linux-2.6.30.4/fs/fuse/control.c 2009-07-24 17:47:51.000000000 -0400
22618+++ linux-2.6.30.4/fs/fuse/control.c 2009-07-30 09:48:10.084769862 -0400
2380c486
JR
22619@@ -161,7 +161,7 @@ void fuse_ctl_remove_conn(struct fuse_co
22620
22621 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
22622 {
22623- struct tree_descr empty_descr = {""};
22624+ struct tree_descr empty_descr = {"", NULL, 0};
22625 struct fuse_conn *fc;
22626 int err;
22627
017d2877
AM
22628diff -urNp linux-2.6.30.4/fs/fuse/dir.c linux-2.6.30.4/fs/fuse/dir.c
22629--- linux-2.6.30.4/fs/fuse/dir.c 2009-07-24 17:47:51.000000000 -0400
22630+++ linux-2.6.30.4/fs/fuse/dir.c 2009-07-30 09:48:10.085789827 -0400
22631@@ -1082,7 +1082,7 @@ static char *read_link(struct dentry *de
2380c486
JR
22632 return link;
22633 }
22634
22635-static void free_link(char *link)
22636+static void free_link(const char *link)
22637 {
22638 if (!IS_ERR(link))
22639 free_page((unsigned long) link);
017d2877
AM
22640diff -urNp linux-2.6.30.4/fs/fuse/file.c linux-2.6.30.4/fs/fuse/file.c
22641--- linux-2.6.30.4/fs/fuse/file.c 2009-07-24 17:47:51.000000000 -0400
22642+++ linux-2.6.30.4/fs/fuse/file.c 2009-07-30 09:48:10.085789827 -0400
22643@@ -1265,7 +1265,7 @@ static int fuse_page_mkwrite(struct vm_a
22644 return 0;
22645 }
22646
22647-static struct vm_operations_struct fuse_file_vm_ops = {
22648+static const struct vm_operations_struct fuse_file_vm_ops = {
22649 .close = fuse_vma_close,
22650 .fault = filemap_fault,
22651 .page_mkwrite = fuse_page_mkwrite,
22652diff -urNp linux-2.6.30.4/fs/gfs2/ops_file.c linux-2.6.30.4/fs/gfs2/ops_file.c
22653--- linux-2.6.30.4/fs/gfs2/ops_file.c 2009-07-24 17:47:51.000000000 -0400
22654+++ linux-2.6.30.4/fs/gfs2/ops_file.c 2009-07-30 09:48:10.086770196 -0400
22655@@ -420,7 +420,7 @@ out:
22656 return ret;
22657 }
22658
22659-static struct vm_operations_struct gfs2_vm_ops = {
22660+static const struct vm_operations_struct gfs2_vm_ops = {
22661 .fault = filemap_fault,
22662 .page_mkwrite = gfs2_page_mkwrite,
22663 };
22664diff -urNp linux-2.6.30.4/fs/hfs/inode.c linux-2.6.30.4/fs/hfs/inode.c
22665--- linux-2.6.30.4/fs/hfs/inode.c 2009-07-24 17:47:51.000000000 -0400
22666+++ linux-2.6.30.4/fs/hfs/inode.c 2009-07-30 09:48:10.086770196 -0400
22667@@ -423,7 +423,7 @@ int hfs_write_inode(struct inode *inode,
2380c486
JR
22668
22669 if (S_ISDIR(main_inode->i_mode)) {
22670 if (fd.entrylength < sizeof(struct hfs_cat_dir))
22671- /* panic? */;
22672+ {/* panic? */}
22673 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
22674 sizeof(struct hfs_cat_dir));
22675 if (rec.type != HFS_CDR_DIR ||
017d2877 22676@@ -444,7 +444,7 @@ int hfs_write_inode(struct inode *inode,
2380c486
JR
22677 sizeof(struct hfs_cat_file));
22678 } else {
22679 if (fd.entrylength < sizeof(struct hfs_cat_file))
22680- /* panic? */;
22681+ {/* panic? */}
22682 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
22683 sizeof(struct hfs_cat_file));
22684 if (rec.type != HFS_CDR_FIL ||
017d2877
AM
22685diff -urNp linux-2.6.30.4/fs/hfsplus/inode.c linux-2.6.30.4/fs/hfsplus/inode.c
22686--- linux-2.6.30.4/fs/hfsplus/inode.c 2009-07-24 17:47:51.000000000 -0400
22687+++ linux-2.6.30.4/fs/hfsplus/inode.c 2009-07-30 09:48:10.086770196 -0400
2380c486
JR
22688@@ -406,7 +406,7 @@ int hfsplus_cat_read_inode(struct inode
22689 struct hfsplus_cat_folder *folder = &entry.folder;
22690
22691 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
22692- /* panic? */;
22693+ {/* panic? */}
22694 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
22695 sizeof(struct hfsplus_cat_folder));
22696 hfsplus_get_perms(inode, &folder->permissions, 1);
22697@@ -423,7 +423,7 @@ int hfsplus_cat_read_inode(struct inode
22698 struct hfsplus_cat_file *file = &entry.file;
22699
22700 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
22701- /* panic? */;
22702+ {/* panic? */}
22703 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
22704 sizeof(struct hfsplus_cat_file));
22705
22706@@ -479,7 +479,7 @@ int hfsplus_cat_write_inode(struct inode
22707 struct hfsplus_cat_folder *folder = &entry.folder;
22708
22709 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
22710- /* panic? */;
22711+ {/* panic? */}
22712 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
22713 sizeof(struct hfsplus_cat_folder));
22714 /* simple node checks? */
22715@@ -501,7 +501,7 @@ int hfsplus_cat_write_inode(struct inode
22716 struct hfsplus_cat_file *file = &entry.file;
22717
22718 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
22719- /* panic? */;
22720+ {/* panic? */}
22721 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
22722 sizeof(struct hfsplus_cat_file));
22723 hfsplus_inode_write_fork(inode, &file->data_fork);
017d2877
AM
22724diff -urNp linux-2.6.30.4/fs/jbd2/journal.c linux-2.6.30.4/fs/jbd2/journal.c
22725--- linux-2.6.30.4/fs/jbd2/journal.c 2009-07-24 17:47:51.000000000 -0400
22726+++ linux-2.6.30.4/fs/jbd2/journal.c 2009-07-30 09:48:10.087743830 -0400
22727@@ -762,7 +762,7 @@ static void jbd2_seq_history_stop(struct
22728 {
22729 }
22730
22731-static struct seq_operations jbd2_seq_history_ops = {
22732+static const struct seq_operations jbd2_seq_history_ops = {
22733 .start = jbd2_seq_history_start,
22734 .next = jbd2_seq_history_next,
22735 .stop = jbd2_seq_history_stop,
22736@@ -812,7 +812,7 @@ static int jbd2_seq_history_release(stru
22737 return seq_release(inode, file);
22738 }
22739
22740-static struct file_operations jbd2_seq_history_fops = {
22741+static const struct file_operations jbd2_seq_history_fops = {
22742 .owner = THIS_MODULE,
22743 .open = jbd2_seq_history_open,
22744 .read = seq_read,
22745@@ -866,7 +866,7 @@ static void jbd2_seq_info_stop(struct se
22746 {
22747 }
22748
22749-static struct seq_operations jbd2_seq_info_ops = {
22750+static const struct seq_operations jbd2_seq_info_ops = {
22751 .start = jbd2_seq_info_start,
22752 .next = jbd2_seq_info_next,
22753 .stop = jbd2_seq_info_stop,
22754@@ -914,7 +914,7 @@ static int jbd2_seq_info_release(struct
22755 return seq_release(inode, file);
22756 }
22757
22758-static struct file_operations jbd2_seq_info_fops = {
22759+static const struct file_operations jbd2_seq_info_fops = {
22760 .owner = THIS_MODULE,
22761 .open = jbd2_seq_info_open,
22762 .read = seq_read,
22763diff -urNp linux-2.6.30.4/fs/jffs2/debug.h linux-2.6.30.4/fs/jffs2/debug.h
22764--- linux-2.6.30.4/fs/jffs2/debug.h 2009-07-24 17:47:51.000000000 -0400
22765+++ linux-2.6.30.4/fs/jffs2/debug.h 2009-07-30 09:48:10.087743830 -0400
2380c486
JR
22766@@ -52,13 +52,13 @@
22767 #if CONFIG_JFFS2_FS_DEBUG > 0
22768 #define D1(x) x
22769 #else
22770-#define D1(x)
22771+#define D1(x) do {} while (0);
22772 #endif
22773
22774 #if CONFIG_JFFS2_FS_DEBUG > 1
22775 #define D2(x) x
22776 #else
22777-#define D2(x)
22778+#define D2(x) do {} while (0);
22779 #endif
22780
22781 /* The prefixes of JFFS2 messages */
22782@@ -114,73 +114,73 @@
22783 #ifdef JFFS2_DBG_READINODE_MESSAGES
22784 #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22785 #else
22786-#define dbg_readinode(fmt, ...)
22787+#define dbg_readinode(fmt, ...) do {} while (0)
22788 #endif
22789 #ifdef JFFS2_DBG_READINODE2_MESSAGES
22790 #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22791 #else
22792-#define dbg_readinode2(fmt, ...)
22793+#define dbg_readinode2(fmt, ...) do {} while (0)
22794 #endif
22795
22796 /* Fragtree build debugging messages */
22797 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
22798 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22799 #else
22800-#define dbg_fragtree(fmt, ...)
22801+#define dbg_fragtree(fmt, ...) do {} while (0)
22802 #endif
22803 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
22804 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22805 #else
22806-#define dbg_fragtree2(fmt, ...)
22807+#define dbg_fragtree2(fmt, ...) do {} while (0)
22808 #endif
22809
22810 /* Directory entry list manilulation debugging messages */
22811 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
22812 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22813 #else
22814-#define dbg_dentlist(fmt, ...)
22815+#define dbg_dentlist(fmt, ...) do {} while (0)
22816 #endif
22817
22818 /* Print the messages about manipulating node_refs */
22819 #ifdef JFFS2_DBG_NODEREF_MESSAGES
22820 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22821 #else
22822-#define dbg_noderef(fmt, ...)
22823+#define dbg_noderef(fmt, ...) do {} while (0)
22824 #endif
22825
22826 /* Manipulations with the list of inodes (JFFS2 inocache) */
22827 #ifdef JFFS2_DBG_INOCACHE_MESSAGES
22828 #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22829 #else
22830-#define dbg_inocache(fmt, ...)
22831+#define dbg_inocache(fmt, ...) do {} while (0)
22832 #endif
22833
22834 /* Summary debugging messages */
22835 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
22836 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22837 #else
22838-#define dbg_summary(fmt, ...)
22839+#define dbg_summary(fmt, ...) do {} while (0)
22840 #endif
22841
22842 /* File system build messages */
22843 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
22844 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22845 #else
22846-#define dbg_fsbuild(fmt, ...)
22847+#define dbg_fsbuild(fmt, ...) do {} while (0)
22848 #endif
22849
22850 /* Watch the object allocations */
22851 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
22852 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22853 #else
22854-#define dbg_memalloc(fmt, ...)
22855+#define dbg_memalloc(fmt, ...) do {} while (0)
22856 #endif
22857
22858 /* Watch the XATTR subsystem */
22859 #ifdef JFFS2_DBG_XATTR_MESSAGES
22860 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
22861 #else
22862-#define dbg_xattr(fmt, ...)
22863+#define dbg_xattr(fmt, ...) do {} while (0)
22864 #endif
22865
22866 /* "Sanity" checks */
017d2877
AM
22867diff -urNp linux-2.6.30.4/fs/jffs2/erase.c linux-2.6.30.4/fs/jffs2/erase.c
22868--- linux-2.6.30.4/fs/jffs2/erase.c 2009-07-24 17:47:51.000000000 -0400
22869+++ linux-2.6.30.4/fs/jffs2/erase.c 2009-07-30 09:48:10.087743830 -0400
2380c486
JR
22870@@ -432,7 +432,8 @@ static void jffs2_mark_erased_block(stru
22871 struct jffs2_unknown_node marker = {
22872 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
22873 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
22874- .totlen = cpu_to_je32(c->cleanmarker_size)
22875+ .totlen = cpu_to_je32(c->cleanmarker_size),
22876+ .hdr_crc = cpu_to_je32(0)
22877 };
22878
22879 jffs2_prealloc_raw_node_refs(c, jeb, 1);
017d2877
AM
22880diff -urNp linux-2.6.30.4/fs/jffs2/summary.h linux-2.6.30.4/fs/jffs2/summary.h
22881--- linux-2.6.30.4/fs/jffs2/summary.h 2009-07-24 17:47:51.000000000 -0400
22882+++ linux-2.6.30.4/fs/jffs2/summary.h 2009-07-30 09:48:10.088709552 -0400
2380c486
JR
22883@@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
22884
22885 #define jffs2_sum_active() (0)
22886 #define jffs2_sum_init(a) (0)
22887-#define jffs2_sum_exit(a)
22888-#define jffs2_sum_disable_collecting(a)
22889+#define jffs2_sum_exit(a) do {} while (0)
22890+#define jffs2_sum_disable_collecting(a) do {} while (0)
22891 #define jffs2_sum_is_disabled(a) (0)
22892-#define jffs2_sum_reset_collected(a)
22893+#define jffs2_sum_reset_collected(a) do {} while (0)
22894 #define jffs2_sum_add_kvec(a,b,c,d) (0)
22895-#define jffs2_sum_move_collected(a,b)
22896+#define jffs2_sum_move_collected(a,b) do {} while (0)
22897 #define jffs2_sum_write_sumnode(a) (0)
22898-#define jffs2_sum_add_padding_mem(a,b)
22899-#define jffs2_sum_add_inode_mem(a,b,c)
22900-#define jffs2_sum_add_dirent_mem(a,b,c)
22901-#define jffs2_sum_add_xattr_mem(a,b,c)
22902-#define jffs2_sum_add_xref_mem(a,b,c)
22903+#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
22904+#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
22905+#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
22906+#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
22907+#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
22908 #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
22909
22910 #endif /* CONFIG_JFFS2_SUMMARY */
017d2877
AM
22911diff -urNp linux-2.6.30.4/fs/jffs2/wbuf.c linux-2.6.30.4/fs/jffs2/wbuf.c
22912--- linux-2.6.30.4/fs/jffs2/wbuf.c 2009-07-24 17:47:51.000000000 -0400
22913+++ linux-2.6.30.4/fs/jffs2/wbuf.c 2009-07-30 09:48:10.088709552 -0400
2380c486
JR
22914@@ -1012,7 +1012,8 @@ static const struct jffs2_unknown_node o
22915 {
22916 .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
22917 .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
22918- .totlen = constant_cpu_to_je32(8)
22919+ .totlen = constant_cpu_to_je32(8),
22920+ .hdr_crc = constant_cpu_to_je32(0)
22921 };
22922
22923 /*
017d2877
AM
22924diff -urNp linux-2.6.30.4/fs/locks.c linux-2.6.30.4/fs/locks.c
22925--- linux-2.6.30.4/fs/locks.c 2009-07-24 17:47:51.000000000 -0400
22926+++ linux-2.6.30.4/fs/locks.c 2009-07-30 09:48:10.089659107 -0400
2380c486
JR
22927@@ -2006,16 +2006,16 @@ void locks_remove_flock(struct file *fil
22928 return;
22929
22930 if (filp->f_op && filp->f_op->flock) {
22931- struct file_lock fl = {
22932+ struct file_lock flock = {
22933 .fl_pid = current->tgid,
22934 .fl_file = filp,
22935 .fl_flags = FL_FLOCK,
22936 .fl_type = F_UNLCK,
22937 .fl_end = OFFSET_MAX,
22938 };
22939- filp->f_op->flock(filp, F_SETLKW, &fl);
22940- if (fl.fl_ops && fl.fl_ops->fl_release_private)
22941- fl.fl_ops->fl_release_private(&fl);
22942+ filp->f_op->flock(filp, F_SETLKW, &flock);
22943+ if (flock.fl_ops && flock.fl_ops->fl_release_private)
22944+ flock.fl_ops->fl_release_private(&flock);
22945 }
22946
22947 lock_kernel();
017d2877
AM
22948diff -urNp linux-2.6.30.4/fs/namei.c linux-2.6.30.4/fs/namei.c
22949--- linux-2.6.30.4/fs/namei.c 2009-07-24 17:47:51.000000000 -0400
22950+++ linux-2.6.30.4/fs/namei.c 2009-07-30 11:33:24.872476011 -0400
22951@@ -624,7 +624,7 @@ static __always_inline int __do_follow_l
2380c486
JR
22952 cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
22953 error = PTR_ERR(cookie);
22954 if (!IS_ERR(cookie)) {
22955- char *s = nd_get_link(nd);
22956+ const char *s = nd_get_link(nd);
22957 error = 0;
22958 if (s)
22959 error = __vfs_follow_link(nd, s);
017d2877 22960@@ -655,6 +655,13 @@ static inline int do_follow_link(struct
2380c486
JR
22961 err = security_inode_follow_link(path->dentry, nd);
22962 if (err)
22963 goto loop;
22964+
22965+ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
22966+ path->dentry->d_inode, path->dentry, nd->path.mnt)) {
22967+ err = -EACCES;
22968+ goto loop;
22969+ }
22970+
22971 current->link_count++;
22972 current->total_link_count++;
22973 nd->depth++;
017d2877 22974@@ -1000,11 +1007,18 @@ return_reval:
2380c486
JR
22975 break;
22976 }
22977 return_base:
22978+ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
22979+ path_put(&nd->path);
22980+ return -ENOENT;
22981+ }
22982 return 0;
22983 out_dput:
22984 path_put_conditional(&next, nd);
22985 break;
22986 }
22987+ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
22988+ err = -ENOENT;
22989+
22990 path_put(&nd->path);
22991 return_err:
22992 return err;
017d2877 22993@@ -1580,12 +1594,19 @@ static int __open_namei_create(struct na
2380c486
JR
22994 int error;
22995 struct dentry *dir = nd->path.dentry;
22996
22997+ if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
22998+ error = -EACCES;
22999+ goto out_unlock;
23000+ }
23001+
23002 if (!IS_POSIXACL(dir->d_inode))
017d2877 23003 mode &= ~current_umask();
2380c486
JR
23004 error = security_path_mknod(&nd->path, path->dentry, mode, 0);
23005 if (error)
23006 goto out_unlock;
23007 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
23008+ if (!error)
23009+ gr_handle_create(path->dentry, nd->path.mnt);
23010 out_unlock:
23011 mutex_unlock(&dir->d_inode->i_mutex);
23012 dput(nd->path.dentry);
017d2877 23013@@ -1668,6 +1689,17 @@ struct file *do_filp_open(int dfd, const
2380c486
JR
23014 &nd, flag);
23015 if (error)
23016 return ERR_PTR(error);
23017+
23018+ if (gr_handle_rawio(nd.path.dentry->d_inode)) {
23019+ error = -EPERM;
23020+ goto exit;
23021+ }
23022+
23023+ if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
23024+ error = -EACCES;
23025+ goto exit;
23026+ }
23027+
23028 goto ok;
23029 }
23030
017d2877 23031@@ -1740,6 +1772,20 @@ do_last:
2380c486
JR
23032 /*
23033 * It already exists.
23034 */
23035+
23036+ if (gr_handle_rawio(path.dentry->d_inode)) {
23037+ error = -EPERM;
23038+ goto exit_mutex_unlock;
23039+ }
23040+ if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
23041+ error = -EACCES;
23042+ goto exit_mutex_unlock;
23043+ }
23044+ if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
23045+ error = -EACCES;
23046+ goto exit_mutex_unlock;
23047+ }
23048+
23049 mutex_unlock(&dir->d_inode->i_mutex);
23050 audit_inode(pathname, path.dentry);
23051
017d2877 23052@@ -1825,6 +1871,13 @@ do_link:
2380c486
JR
23053 error = security_inode_follow_link(path.dentry, &nd);
23054 if (error)
23055 goto exit_dput;
23056+
23057+ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
23058+ path.dentry, nd.path.mnt)) {
23059+ error = -EACCES;
23060+ goto exit_dput;
23061+ }
23062+
23063 error = __do_follow_link(&path, &nd);
23064 if (error) {
23065 /* Does someone understand code flow here? Or it is only
017d2877 23066@@ -1997,6 +2050,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
2380c486
JR
23067 error = may_mknod(mode);
23068 if (error)
23069 goto out_dput;
23070+
23071+ if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
23072+ error = -EPERM;
23073+ goto out_dput;
23074+ }
23075+
23076+ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
23077+ error = -EACCES;
23078+ goto out_dput;
23079+ }
23080+
23081 error = mnt_want_write(nd.path.mnt);
23082 if (error)
23083 goto out_dput;
017d2877 23084@@ -2017,6 +2081,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
2380c486
JR
23085 }
23086 out_drop_write:
23087 mnt_drop_write(nd.path.mnt);
23088+
23089+ if (!error)
23090+ gr_handle_create(dentry, nd.path.mnt);
23091 out_dput:
23092 dput(dentry);
23093 out_unlock:
017d2877 23094@@ -2070,6 +2137,11 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
2380c486
JR
23095 if (IS_ERR(dentry))
23096 goto out_unlock;
23097
23098+ if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
23099+ error = -EACCES;
23100+ goto out_dput;
23101+ }
23102+
23103 if (!IS_POSIXACL(nd.path.dentry->d_inode))
017d2877 23104 mode &= ~current_umask();
2380c486 23105 error = mnt_want_write(nd.path.mnt);
017d2877 23106@@ -2081,6 +2153,10 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
2380c486
JR
23107 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
23108 out_drop_write:
23109 mnt_drop_write(nd.path.mnt);
23110+
23111+ if (!error)
23112+ gr_handle_create(dentry, nd.path.mnt);
23113+
23114 out_dput:
23115 dput(dentry);
23116 out_unlock:
017d2877 23117@@ -2162,6 +2238,8 @@ static long do_rmdir(int dfd, const char
2380c486
JR
23118 char * name;
23119 struct dentry *dentry;
23120 struct nameidata nd;
23121+ ino_t saved_ino = 0;
23122+ dev_t saved_dev = 0;
23123
23124 error = user_path_parent(dfd, pathname, &nd, &name);
23125 if (error)
017d2877 23126@@ -2186,6 +2264,19 @@ static long do_rmdir(int dfd, const char
2380c486
JR
23127 error = PTR_ERR(dentry);
23128 if (IS_ERR(dentry))
23129 goto exit2;
23130+
23131+ if (dentry->d_inode != NULL) {
23132+ if (dentry->d_inode->i_nlink <= 1) {
23133+ saved_ino = dentry->d_inode->i_ino;
23134+ saved_dev = dentry->d_inode->i_sb->s_dev;
23135+ }
23136+
23137+ if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
23138+ error = -EACCES;
23139+ goto exit3;
23140+ }
23141+ }
23142+
23143 error = mnt_want_write(nd.path.mnt);
23144 if (error)
23145 goto exit3;
017d2877 23146@@ -2193,6 +2284,8 @@ static long do_rmdir(int dfd, const char
2380c486
JR
23147 if (error)
23148 goto exit4;
23149 error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
23150+ if (!error && (saved_dev || saved_ino))
23151+ gr_handle_delete(saved_ino, saved_dev);
23152 exit4:
23153 mnt_drop_write(nd.path.mnt);
23154 exit3:
017d2877 23155@@ -2254,6 +2347,8 @@ static long do_unlinkat(int dfd, const c
2380c486
JR
23156 struct dentry *dentry;
23157 struct nameidata nd;
23158 struct inode *inode = NULL;
23159+ ino_t saved_ino = 0;
23160+ dev_t saved_dev = 0;
23161
23162 error = user_path_parent(dfd, pathname, &nd, &name);
23163 if (error)
017d2877 23164@@ -2273,8 +2368,19 @@ static long do_unlinkat(int dfd, const c
2380c486
JR
23165 if (nd.last.name[nd.last.len])
23166 goto slashes;
23167 inode = dentry->d_inode;
23168- if (inode)
23169+ if (inode) {
23170+ if (inode->i_nlink <= 1) {
23171+ saved_ino = inode->i_ino;
23172+ saved_dev = inode->i_sb->s_dev;
23173+ }
23174+
23175 atomic_inc(&inode->i_count);
23176+
23177+ if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
23178+ error = -EACCES;
23179+ goto exit2;
23180+ }
23181+ }
23182 error = mnt_want_write(nd.path.mnt);
23183 if (error)
23184 goto exit2;
017d2877 23185@@ -2282,6 +2388,8 @@ static long do_unlinkat(int dfd, const c
2380c486
JR
23186 if (error)
23187 goto exit3;
23188 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
23189+ if (!error && (saved_ino || saved_dev))
23190+ gr_handle_delete(saved_ino, saved_dev);
23191 exit3:
23192 mnt_drop_write(nd.path.mnt);
23193 exit2:
017d2877 23194@@ -2360,6 +2468,11 @@ SYSCALL_DEFINE3(symlinkat, const char __
2380c486
JR
23195 if (IS_ERR(dentry))
23196 goto out_unlock;
23197
23198+ if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
23199+ error = -EACCES;
23200+ goto out_dput;
23201+ }
23202+
23203 error = mnt_want_write(nd.path.mnt);
23204 if (error)
23205 goto out_dput;
017d2877 23206@@ -2367,6 +2480,8 @@ SYSCALL_DEFINE3(symlinkat, const char __
2380c486
JR
23207 if (error)
23208 goto out_drop_write;
23209 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
23210+ if (!error)
23211+ gr_handle_create(dentry, nd.path.mnt);
23212 out_drop_write:
23213 mnt_drop_write(nd.path.mnt);
23214 out_dput:
017d2877 23215@@ -2460,6 +2575,20 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
2380c486
JR
23216 error = PTR_ERR(new_dentry);
23217 if (IS_ERR(new_dentry))
23218 goto out_unlock;
23219+
23220+ if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
23221+ old_path.dentry->d_inode,
23222+ old_path.dentry->d_inode->i_mode, to)) {
23223+ error = -EACCES;
23224+ goto out_dput;
23225+ }
23226+
23227+ if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
23228+ old_path.dentry, old_path.mnt, to)) {
23229+ error = -EACCES;
23230+ goto out_dput;
23231+ }
23232+
23233 error = mnt_want_write(nd.path.mnt);
23234 if (error)
23235 goto out_dput;
017d2877 23236@@ -2467,6 +2596,8 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
2380c486
JR
23237 if (error)
23238 goto out_drop_write;
23239 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
23240+ if (!error)
23241+ gr_handle_create(new_dentry, nd.path.mnt);
23242 out_drop_write:
23243 mnt_drop_write(nd.path.mnt);
23244 out_dput:
017d2877 23245@@ -2700,6 +2831,12 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
2380c486
JR
23246 if (new_dentry == trap)
23247 goto exit5;
23248
23249+ error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt,
23250+ old_dentry, old_dir->d_inode, oldnd.path.mnt,
23251+ to);
23252+ if (error)
23253+ goto exit5;
23254+
23255 error = mnt_want_write(oldnd.path.mnt);
23256 if (error)
23257 goto exit5;
017d2877 23258@@ -2709,6 +2846,9 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
2380c486
JR
23259 goto exit6;
23260 error = vfs_rename(old_dir->d_inode, old_dentry,
23261 new_dir->d_inode, new_dentry);
23262+ if (!error)
23263+ gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
23264+ new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
23265 exit6:
23266 mnt_drop_write(oldnd.path.mnt);
23267 exit5:
017d2877
AM
23268diff -urNp linux-2.6.30.4/fs/namespace.c linux-2.6.30.4/fs/namespace.c
23269--- linux-2.6.30.4/fs/namespace.c 2009-07-24 17:47:51.000000000 -0400
23270+++ linux-2.6.30.4/fs/namespace.c 2009-07-30 11:10:49.247492786 -0400
23271@@ -1110,6 +1110,8 @@ static int do_umount(struct vfsmount *mn
2380c486
JR
23272 lock_kernel();
23273 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
23274 unlock_kernel();
23275+
23276+ gr_log_remount(mnt->mnt_devname, retval);
23277 }
23278 up_write(&sb->s_umount);
23279 return retval;
017d2877 23280@@ -1133,6 +1135,9 @@ static int do_umount(struct vfsmount *mn
2380c486
JR
23281 security_sb_umount_busy(mnt);
23282 up_write(&namespace_sem);
23283 release_mounts(&umount_list);
23284+
23285+ gr_log_unmount(mnt->mnt_devname, retval);
23286+
23287 return retval;
23288 }
23289
017d2877 23290@@ -1967,6 +1972,11 @@ long do_mount(char *dev_name, char *dir_
2380c486
JR
23291 if (retval)
23292 goto dput_out;
23293
23294+ if (gr_handle_chroot_mount(path.dentry, path.mnt, dev_name)) {
23295+ retval = -EPERM;
23296+ goto dput_out;
23297+ }
23298+
23299 if (flags & MS_REMOUNT)
23300 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
23301 data_page);
017d2877 23302@@ -1981,6 +1991,9 @@ long do_mount(char *dev_name, char *dir_
2380c486
JR
23303 dev_name, data_page);
23304 dput_out:
23305 path_put(&path);
23306+
23307+ gr_log_mount(dev_name, dir_name, retval);
23308+
23309 return retval;
23310 }
23311
017d2877 23312@@ -2092,6 +2105,9 @@ SYSCALL_DEFINE5(mount, char __user *, de
2380c486
JR
23313 if (retval < 0)
23314 goto out3;
23315
23316+ if (gr_handle_chroot_pivot())
23317+ return -EPERM;
23318+
23319 lock_kernel();
23320 retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
23321 flags, (void *)data_page);
017d2877
AM
23322diff -urNp linux-2.6.30.4/fs/nfs/client.c linux-2.6.30.4/fs/nfs/client.c
23323--- linux-2.6.30.4/fs/nfs/client.c 2009-07-24 17:47:51.000000000 -0400
23324+++ linux-2.6.30.4/fs/nfs/client.c 2009-07-30 09:48:10.090670547 -0400
23325@@ -1404,7 +1404,7 @@ static void *nfs_server_list_next(struct
23326 static void nfs_server_list_stop(struct seq_file *p, void *v);
23327 static int nfs_server_list_show(struct seq_file *m, void *v);
23328
23329-static struct seq_operations nfs_server_list_ops = {
23330+static const struct seq_operations nfs_server_list_ops = {
23331 .start = nfs_server_list_start,
23332 .next = nfs_server_list_next,
23333 .stop = nfs_server_list_stop,
23334@@ -1425,7 +1425,7 @@ static void *nfs_volume_list_next(struct
23335 static void nfs_volume_list_stop(struct seq_file *p, void *v);
23336 static int nfs_volume_list_show(struct seq_file *m, void *v);
23337
23338-static struct seq_operations nfs_volume_list_ops = {
23339+static const struct seq_operations nfs_volume_list_ops = {
23340 .start = nfs_volume_list_start,
23341 .next = nfs_volume_list_next,
23342 .stop = nfs_volume_list_stop,
23343diff -urNp linux-2.6.30.4/fs/nfs/file.c linux-2.6.30.4/fs/nfs/file.c
23344--- linux-2.6.30.4/fs/nfs/file.c 2009-07-24 17:47:51.000000000 -0400
23345+++ linux-2.6.30.4/fs/nfs/file.c 2009-07-30 09:48:10.090670547 -0400
23346@@ -57,7 +57,7 @@ static int nfs_lock(struct file *filp, i
23347 static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
23348 static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
23349
23350-static struct vm_operations_struct nfs_file_vm_ops;
23351+static const struct vm_operations_struct nfs_file_vm_ops;
23352
23353 const struct file_operations nfs_file_operations = {
23354 .llseek = nfs_file_llseek,
23355@@ -523,7 +523,7 @@ out_unlock:
23356 return VM_FAULT_SIGBUS;
23357 }
23358
23359-static struct vm_operations_struct nfs_file_vm_ops = {
23360+static const struct vm_operations_struct nfs_file_vm_ops = {
23361 .fault = filemap_fault,
23362 .page_mkwrite = nfs_vm_page_mkwrite,
23363 };
23364diff -urNp linux-2.6.30.4/fs/nfs/nfs4proc.c linux-2.6.30.4/fs/nfs/nfs4proc.c
23365--- linux-2.6.30.4/fs/nfs/nfs4proc.c 2009-07-24 17:47:51.000000000 -0400
23366+++ linux-2.6.30.4/fs/nfs/nfs4proc.c 2009-07-30 09:48:10.091839047 -0400
23367@@ -755,7 +755,7 @@ static int _nfs4_do_open_reclaim(struct
2380c486
JR
23368 static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
23369 {
23370 struct nfs_server *server = NFS_SERVER(state->inode);
23371- struct nfs4_exception exception = { };
23372+ struct nfs4_exception exception = {0, 0};
23373 int err;
23374 do {
23375 err = _nfs4_do_open_reclaim(ctx, state);
017d2877 23376@@ -797,7 +797,7 @@ static int _nfs4_open_delegation_recall(
2380c486
JR
23377
23378 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
23379 {
23380- struct nfs4_exception exception = { };
23381+ struct nfs4_exception exception = {0, 0};
23382 struct nfs_server *server = NFS_SERVER(state->inode);
23383 int err;
23384 do {
017d2877 23385@@ -1091,7 +1091,7 @@ static int _nfs4_open_expired(struct nfs
2380c486
JR
23386 static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
23387 {
23388 struct nfs_server *server = NFS_SERVER(state->inode);
23389- struct nfs4_exception exception = { };
23390+ struct nfs4_exception exception = {0, 0};
23391 int err;
23392
23393 do {
017d2877 23394@@ -1189,7 +1189,7 @@ out_err:
2380c486
JR
23395
23396 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)
23397 {
23398- struct nfs4_exception exception = { };
23399+ struct nfs4_exception exception = {0, 0};
23400 struct nfs4_state *res;
23401 int status;
23402
017d2877 23403@@ -1280,7 +1280,7 @@ static int nfs4_do_setattr(struct inode
2380c486
JR
23404 struct nfs4_state *state)
23405 {
23406 struct nfs_server *server = NFS_SERVER(inode);
23407- struct nfs4_exception exception = { };
23408+ struct nfs4_exception exception = {0, 0};
23409 int err;
23410 do {
23411 err = nfs4_handle_exception(server,
017d2877 23412@@ -1611,7 +1611,7 @@ static int _nfs4_server_capabilities(str
2380c486
JR
23413
23414 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
23415 {
23416- struct nfs4_exception exception = { };
23417+ struct nfs4_exception exception = {0, 0};
23418 int err;
23419 do {
23420 err = nfs4_handle_exception(server,
017d2877 23421@@ -1644,7 +1644,7 @@ static int _nfs4_lookup_root(struct nfs_
2380c486
JR
23422 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
23423 struct nfs_fsinfo *info)
23424 {
23425- struct nfs4_exception exception = { };
23426+ struct nfs4_exception exception = {0, 0};
23427 int err;
23428 do {
23429 err = nfs4_handle_exception(server,
017d2877 23430@@ -1733,7 +1733,7 @@ static int _nfs4_proc_getattr(struct nfs
2380c486
JR
23431
23432 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
23433 {
23434- struct nfs4_exception exception = { };
23435+ struct nfs4_exception exception = {0, 0};
23436 int err;
23437 do {
23438 err = nfs4_handle_exception(server,
017d2877 23439@@ -1821,7 +1821,7 @@ static int nfs4_proc_lookupfh(struct nfs
2380c486
JR
23440 struct qstr *name, struct nfs_fh *fhandle,
23441 struct nfs_fattr *fattr)
23442 {
23443- struct nfs4_exception exception = { };
23444+ struct nfs4_exception exception = {0, 0};
23445 int err;
23446 do {
23447 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
017d2877 23448@@ -1850,7 +1850,7 @@ static int _nfs4_proc_lookup(struct inod
2380c486
JR
23449
23450 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
23451 {
23452- struct nfs4_exception exception = { };
23453+ struct nfs4_exception exception = {0, 0};
23454 int err;
23455 do {
23456 err = nfs4_handle_exception(NFS_SERVER(dir),
017d2877 23457@@ -1914,7 +1914,7 @@ static int _nfs4_proc_access(struct inod
2380c486
JR
23458
23459 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
23460 {
23461- struct nfs4_exception exception = { };
23462+ struct nfs4_exception exception = {0, 0};
23463 int err;
23464 do {
23465 err = nfs4_handle_exception(NFS_SERVER(inode),
017d2877 23466@@ -1969,7 +1969,7 @@ static int _nfs4_proc_readlink(struct in
2380c486
JR
23467 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
23468 unsigned int pgbase, unsigned int pglen)
23469 {
23470- struct nfs4_exception exception = { };
23471+ struct nfs4_exception exception = {0, 0};
23472 int err;
23473 do {
23474 err = nfs4_handle_exception(NFS_SERVER(inode),
017d2877 23475@@ -2067,7 +2067,7 @@ static int _nfs4_proc_remove(struct inod
2380c486
JR
23476
23477 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
23478 {
23479- struct nfs4_exception exception = { };
23480+ struct nfs4_exception exception = {0, 0};
23481 int err;
23482 do {
23483 err = nfs4_handle_exception(NFS_SERVER(dir),
017d2877 23484@@ -2139,7 +2139,7 @@ static int _nfs4_proc_rename(struct inod
2380c486
JR
23485 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
23486 struct inode *new_dir, struct qstr *new_name)
23487 {
23488- struct nfs4_exception exception = { };
23489+ struct nfs4_exception exception = {0, 0};
23490 int err;
23491 do {
23492 err = nfs4_handle_exception(NFS_SERVER(old_dir),
017d2877 23493@@ -2186,7 +2186,7 @@ static int _nfs4_proc_link(struct inode
2380c486
JR
23494
23495 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
23496 {
23497- struct nfs4_exception exception = { };
23498+ struct nfs4_exception exception = {0, 0};
23499 int err;
23500 do {
23501 err = nfs4_handle_exception(NFS_SERVER(inode),
017d2877 23502@@ -2277,7 +2277,7 @@ out:
2380c486
JR
23503 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
23504 struct page *page, unsigned int len, struct iattr *sattr)
23505 {
23506- struct nfs4_exception exception = { };
23507+ struct nfs4_exception exception = {0, 0};
23508 int err;
23509 do {
23510 err = nfs4_handle_exception(NFS_SERVER(dir),
017d2877 23511@@ -2308,7 +2308,7 @@ out:
2380c486
JR
23512 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
23513 struct iattr *sattr)
23514 {
23515- struct nfs4_exception exception = { };
23516+ struct nfs4_exception exception = {0, 0};
23517 int err;
23518 do {
23519 err = nfs4_handle_exception(NFS_SERVER(dir),
017d2877 23520@@ -2357,7 +2357,7 @@ static int _nfs4_proc_readdir(struct den
2380c486
JR
23521 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
23522 u64 cookie, struct page *page, unsigned int count, int plus)
23523 {
23524- struct nfs4_exception exception = { };
23525+ struct nfs4_exception exception = {0, 0};
23526 int err;
23527 do {
23528 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
017d2877 23529@@ -2405,7 +2405,7 @@ out:
2380c486
JR
23530 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
23531 struct iattr *sattr, dev_t rdev)
23532 {
23533- struct nfs4_exception exception = { };
23534+ struct nfs4_exception exception = {0, 0};
23535 int err;
23536 do {
23537 err = nfs4_handle_exception(NFS_SERVER(dir),
017d2877 23538@@ -2434,7 +2434,7 @@ static int _nfs4_proc_statfs(struct nfs_
2380c486
JR
23539
23540 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
23541 {
23542- struct nfs4_exception exception = { };
23543+ struct nfs4_exception exception = {0, 0};
23544 int err;
23545 do {
23546 err = nfs4_handle_exception(server,
017d2877 23547@@ -2462,7 +2462,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
2380c486
JR
23548
23549 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
23550 {
23551- struct nfs4_exception exception = { };
23552+ struct nfs4_exception exception = {0, 0};
23553 int err;
23554
23555 do {
017d2877 23556@@ -2505,7 +2505,7 @@ static int _nfs4_proc_pathconf(struct nf
2380c486
JR
23557 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
23558 struct nfs_pathconf *pathconf)
23559 {
23560- struct nfs4_exception exception = { };
23561+ struct nfs4_exception exception = {0, 0};
23562 int err;
23563
23564 do {
017d2877 23565@@ -2789,7 +2789,7 @@ out_free:
2380c486
JR
23566
23567 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
23568 {
23569- struct nfs4_exception exception = { };
23570+ struct nfs4_exception exception = {0, 0};
23571 ssize_t ret;
23572 do {
23573 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
017d2877 23574@@ -2846,7 +2846,7 @@ static int __nfs4_proc_set_acl(struct in
2380c486
JR
23575
23576 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
23577 {
23578- struct nfs4_exception exception = { };
23579+ struct nfs4_exception exception = {0, 0};
23580 int err;
23581 do {
23582 err = nfs4_handle_exception(NFS_SERVER(inode),
017d2877 23583@@ -3069,7 +3069,7 @@ out:
2380c486
JR
23584 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
23585 {
23586 struct nfs_server *server = NFS_SERVER(inode);
23587- struct nfs4_exception exception = { };
23588+ struct nfs4_exception exception = {0, 0};
23589 int err;
23590 do {
23591 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
017d2877 23592@@ -3142,7 +3142,7 @@ out:
2380c486
JR
23593
23594 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
23595 {
23596- struct nfs4_exception exception = { };
23597+ struct nfs4_exception exception = {0, 0};
23598 int err;
23599
23600 do {
017d2877 23601@@ -3499,7 +3499,7 @@ static int _nfs4_do_setlk(struct nfs4_st
2380c486
JR
23602 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
23603 {
23604 struct nfs_server *server = NFS_SERVER(state->inode);
23605- struct nfs4_exception exception = { };
23606+ struct nfs4_exception exception = {0, 0};
23607 int err;
23608
23609 do {
017d2877 23610@@ -3517,7 +3517,7 @@ static int nfs4_lock_reclaim(struct nfs4
2380c486
JR
23611 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
23612 {
23613 struct nfs_server *server = NFS_SERVER(state->inode);
23614- struct nfs4_exception exception = { };
23615+ struct nfs4_exception exception = {0, 0};
23616 int err;
23617
23618 err = nfs4_set_lock_state(state, request);
017d2877 23619@@ -3572,7 +3572,7 @@ out:
2380c486
JR
23620
23621 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
23622 {
23623- struct nfs4_exception exception = { };
23624+ struct nfs4_exception exception = {0, 0};
23625 int err;
23626
23627 do {
017d2877 23628@@ -3622,7 +3622,7 @@ nfs4_proc_lock(struct file *filp, int cm
2380c486
JR
23629 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
23630 {
23631 struct nfs_server *server = NFS_SERVER(state->inode);
23632- struct nfs4_exception exception = { };
23633+ struct nfs4_exception exception = {0, 0};
23634 int err;
23635
23636 err = nfs4_set_lock_state(state, fl);
017d2877
AM
23637diff -urNp linux-2.6.30.4/fs/nfsd/export.c linux-2.6.30.4/fs/nfsd/export.c
23638--- linux-2.6.30.4/fs/nfsd/export.c 2009-07-24 17:47:51.000000000 -0400
23639+++ linux-2.6.30.4/fs/nfsd/export.c 2009-07-30 09:48:10.092682326 -0400
2380c486
JR
23640@@ -472,7 +472,7 @@ static int secinfo_parse(char **mesg, ch
23641 * probably discover the problem when someone fails to
23642 * authenticate.
23643 */
23644- if (f->pseudoflavor < 0)
23645+ if ((s32)f->pseudoflavor < 0)
23646 return -EINVAL;
23647 err = get_int(mesg, &f->flags);
23648 if (err)
017d2877
AM
23649@@ -1524,7 +1524,7 @@ static int e_show(struct seq_file *m, vo
23650 return svc_export_show(m, &svc_export_cache, cp);
23651 }
23652
23653-struct seq_operations nfs_exports_op = {
23654+const struct seq_operations nfs_exports_op = {
23655 .start = e_start,
23656 .next = e_next,
23657 .stop = e_stop,
23658diff -urNp linux-2.6.30.4/fs/nfsd/nfsctl.c linux-2.6.30.4/fs/nfsd/nfsctl.c
23659--- linux-2.6.30.4/fs/nfsd/nfsctl.c 2009-07-24 17:47:51.000000000 -0400
23660+++ linux-2.6.30.4/fs/nfsd/nfsctl.c 2009-07-30 12:06:52.128724203 -0400
23661@@ -175,7 +175,7 @@ static const struct file_operations expo
23662
23663 extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
23664
23665-static struct file_operations pool_stats_operations = {
23666+static const struct file_operations pool_stats_operations = {
23667 .open = nfsd_pool_stats_open,
23668 .read = seq_read,
23669 .llseek = seq_lseek,
23670diff -urNp linux-2.6.30.4/fs/nilfs2/dir.c linux-2.6.30.4/fs/nilfs2/dir.c
23671--- linux-2.6.30.4/fs/nilfs2/dir.c 2009-07-24 17:47:51.000000000 -0400
23672+++ linux-2.6.30.4/fs/nilfs2/dir.c 2009-07-30 12:06:52.132720832 -0400
23673@@ -698,7 +698,7 @@ not_empty:
23674 return 0;
23675 }
23676
23677-struct file_operations nilfs_dir_operations = {
23678+const struct file_operations nilfs_dir_operations = {
23679 .llseek = generic_file_llseek,
23680 .read = generic_read_dir,
23681 .readdir = nilfs_readdir,
23682diff -urNp linux-2.6.30.4/fs/nilfs2/file.c linux-2.6.30.4/fs/nilfs2/file.c
23683--- linux-2.6.30.4/fs/nilfs2/file.c 2009-07-24 17:47:51.000000000 -0400
23684+++ linux-2.6.30.4/fs/nilfs2/file.c 2009-07-30 12:07:09.623977752 -0400
23685@@ -117,7 +117,7 @@ static int nilfs_page_mkwrite(struct vm_
23686 return 0;
23687 }
23688
23689-struct vm_operations_struct nilfs_file_vm_ops = {
23690+const struct vm_operations_struct nilfs_file_vm_ops = {
23691 .fault = filemap_fault,
23692 .page_mkwrite = nilfs_page_mkwrite,
23693 };
23694@@ -134,7 +134,7 @@ static int nilfs_file_mmap(struct file *
23695 * We have mostly NULL's here: the current defaults are ok for
23696 * the nilfs filesystem.
23697 */
23698-struct file_operations nilfs_file_operations = {
23699+const struct file_operations nilfs_file_operations = {
23700 .llseek = generic_file_llseek,
23701 .read = do_sync_read,
23702 .write = do_sync_write,
23703@@ -151,7 +151,7 @@ struct file_operations nilfs_file_operat
23704 .splice_read = generic_file_splice_read,
23705 };
23706
23707-struct inode_operations nilfs_file_inode_operations = {
23708+const struct inode_operations nilfs_file_inode_operations = {
23709 .truncate = nilfs_truncate,
23710 .setattr = nilfs_setattr,
23711 .permission = nilfs_permission,
23712diff -urNp linux-2.6.30.4/fs/nilfs2/gcinode.c linux-2.6.30.4/fs/nilfs2/gcinode.c
23713--- linux-2.6.30.4/fs/nilfs2/gcinode.c 2009-07-24 17:47:51.000000000 -0400
23714+++ linux-2.6.30.4/fs/nilfs2/gcinode.c 2009-07-30 12:07:28.369023156 -0400
23715@@ -52,7 +52,7 @@
23716 #include "dat.h"
23717 #include "ifile.h"
23718
23719-static struct address_space_operations def_gcinode_aops = {};
23720+static const struct address_space_operations def_gcinode_aops = {};
23721 /* XXX need def_gcinode_iops/fops? */
23722
23723 /*
23724diff -urNp linux-2.6.30.4/fs/nilfs2/inode.c linux-2.6.30.4/fs/nilfs2/inode.c
23725--- linux-2.6.30.4/fs/nilfs2/inode.c 2009-07-24 17:47:51.000000000 -0400
23726+++ linux-2.6.30.4/fs/nilfs2/inode.c 2009-07-30 12:07:28.374397645 -0400
23727@@ -237,7 +237,7 @@ nilfs_direct_IO(int rw, struct kiocb *io
23728 return size;
23729 }
23730
23731-struct address_space_operations nilfs_aops = {
23732+const struct address_space_operations nilfs_aops = {
23733 .writepage = nilfs_writepage,
23734 .readpage = nilfs_readpage,
23735 /* .sync_page = nilfs_sync_page, */
23736diff -urNp linux-2.6.30.4/fs/nilfs2/mdt.c linux-2.6.30.4/fs/nilfs2/mdt.c
23737--- linux-2.6.30.4/fs/nilfs2/mdt.c 2009-07-24 17:47:51.000000000 -0400
23738+++ linux-2.6.30.4/fs/nilfs2/mdt.c 2009-07-30 12:07:28.379284534 -0400
23739@@ -428,7 +428,7 @@ nilfs_mdt_write_page(struct page *page,
23740 }
23741
23742
23743-static struct address_space_operations def_mdt_aops = {
23744+static const struct address_space_operations def_mdt_aops = {
23745 .writepage = nilfs_mdt_write_page,
23746 };
23747
23748diff -urNp linux-2.6.30.4/fs/nilfs2/namei.c linux-2.6.30.4/fs/nilfs2/namei.c
23749--- linux-2.6.30.4/fs/nilfs2/namei.c 2009-07-24 17:47:51.000000000 -0400
23750+++ linux-2.6.30.4/fs/nilfs2/namei.c 2009-07-30 12:07:02.764163011 -0400
23751@@ -448,7 +448,7 @@ out:
23752 return err;
23753 }
23754
23755-struct inode_operations nilfs_dir_inode_operations = {
23756+const struct inode_operations nilfs_dir_inode_operations = {
23757 .create = nilfs_create,
23758 .lookup = nilfs_lookup,
23759 .link = nilfs_link,
23760@@ -462,12 +462,12 @@ struct inode_operations nilfs_dir_inode_
23761 .permission = nilfs_permission,
23762 };
23763
23764-struct inode_operations nilfs_special_inode_operations = {
23765+const struct inode_operations nilfs_special_inode_operations = {
23766 .setattr = nilfs_setattr,
23767 .permission = nilfs_permission,
23768 };
23769
23770-struct inode_operations nilfs_symlink_inode_operations = {
23771+const struct inode_operations nilfs_symlink_inode_operations = {
23772 .readlink = generic_readlink,
23773 .follow_link = page_follow_link_light,
23774 .put_link = page_put_link,
23775diff -urNp linux-2.6.30.4/fs/nilfs2/nilfs.h linux-2.6.30.4/fs/nilfs2/nilfs.h
23776--- linux-2.6.30.4/fs/nilfs2/nilfs.h 2009-07-24 17:47:51.000000000 -0400
23777+++ linux-2.6.30.4/fs/nilfs2/nilfs.h 2009-07-30 12:47:17.035918280 -0400
23778@@ -297,13 +297,13 @@ void nilfs_clear_gcdat_inode(struct the_
23779 /*
23780 * Inodes and files operations
23781 */
23782-extern struct file_operations nilfs_dir_operations;
23783-extern struct inode_operations nilfs_file_inode_operations;
23784-extern struct file_operations nilfs_file_operations;
23785-extern struct address_space_operations nilfs_aops;
23786-extern struct inode_operations nilfs_dir_inode_operations;
23787-extern struct inode_operations nilfs_special_inode_operations;
23788-extern struct inode_operations nilfs_symlink_inode_operations;
23789+extern const struct file_operations nilfs_dir_operations;
23790+extern const struct inode_operations nilfs_file_inode_operations;
23791+extern const struct file_operations nilfs_file_operations;
23792+extern const struct address_space_operations nilfs_aops;
23793+extern const struct inode_operations nilfs_dir_inode_operations;
23794+extern const struct inode_operations nilfs_special_inode_operations;
23795+extern const struct inode_operations nilfs_symlink_inode_operations;
23796
23797 /*
23798 * filesystem type
23799diff -urNp linux-2.6.30.4/fs/nilfs2/super.c linux-2.6.30.4/fs/nilfs2/super.c
23800--- linux-2.6.30.4/fs/nilfs2/super.c 2009-07-24 17:47:51.000000000 -0400
23801+++ linux-2.6.30.4/fs/nilfs2/super.c 2009-07-30 12:07:21.041339808 -0400
23802@@ -520,7 +520,7 @@ static int nilfs_statfs(struct dentry *d
23803 return 0;
23804 }
23805
23806-static struct super_operations nilfs_sops = {
23807+static const struct super_operations nilfs_sops = {
23808 .alloc_inode = nilfs_alloc_inode,
23809 .destroy_inode = nilfs_destroy_inode,
23810 .dirty_inode = nilfs_dirty_inode,
23811diff -urNp linux-2.6.30.4/fs/nls/nls_base.c linux-2.6.30.4/fs/nls/nls_base.c
23812--- linux-2.6.30.4/fs/nls/nls_base.c 2009-07-24 17:47:51.000000000 -0400
23813+++ linux-2.6.30.4/fs/nls/nls_base.c 2009-07-30 09:48:10.092682326 -0400
2380c486
JR
23814@@ -40,7 +40,7 @@ static const struct utf8_table utf8_tabl
23815 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
23816 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
23817 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
23818- {0, /* end of table */}
23819+ {0, 0, 0, 0, 0, /* end of table */}
23820 };
23821
23822 int
017d2877
AM
23823diff -urNp linux-2.6.30.4/fs/ntfs/file.c linux-2.6.30.4/fs/ntfs/file.c
23824--- linux-2.6.30.4/fs/ntfs/file.c 2009-07-24 17:47:51.000000000 -0400
23825+++ linux-2.6.30.4/fs/ntfs/file.c 2009-07-30 09:48:10.092682326 -0400
2380c486
JR
23826@@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
23827 #endif /* NTFS_RW */
23828 };
23829
23830-const struct file_operations ntfs_empty_file_ops = {};
23831+const struct file_operations ntfs_empty_file_ops;
23832
23833-const struct inode_operations ntfs_empty_inode_ops = {};
23834+const struct inode_operations ntfs_empty_inode_ops;
017d2877
AM
23835diff -urNp linux-2.6.30.4/fs/ocfs2/cluster/heartbeat.c linux-2.6.30.4/fs/ocfs2/cluster/heartbeat.c
23836--- linux-2.6.30.4/fs/ocfs2/cluster/heartbeat.c 2009-07-24 17:47:51.000000000 -0400
23837+++ linux-2.6.30.4/fs/ocfs2/cluster/heartbeat.c 2009-07-30 12:06:52.144842473 -0400
23838@@ -966,7 +966,7 @@ static ssize_t o2hb_debug_read(struct fi
23839 }
23840 #endif /* CONFIG_DEBUG_FS */
23841
23842-static struct file_operations o2hb_debug_fops = {
23843+static const struct file_operations o2hb_debug_fops = {
23844 .open = o2hb_debug_open,
23845 .release = o2hb_debug_release,
23846 .read = o2hb_debug_read,
23847diff -urNp linux-2.6.30.4/fs/ocfs2/cluster/netdebug.c linux-2.6.30.4/fs/ocfs2/cluster/netdebug.c
23848--- linux-2.6.30.4/fs/ocfs2/cluster/netdebug.c 2009-07-24 17:47:51.000000000 -0400
23849+++ linux-2.6.30.4/fs/ocfs2/cluster/netdebug.c 2009-07-30 09:48:10.092682326 -0400
23850@@ -163,7 +163,7 @@ static void nst_seq_stop(struct seq_file
23851 {
23852 }
23853
23854-static struct seq_operations nst_seq_ops = {
23855+static const struct seq_operations nst_seq_ops = {
23856 .start = nst_seq_start,
23857 .next = nst_seq_next,
23858 .stop = nst_seq_stop,
23859@@ -207,7 +207,7 @@ static int nst_fop_release(struct inode
23860 return seq_release_private(inode, file);
23861 }
23862
23863-static struct file_operations nst_seq_fops = {
23864+static const struct file_operations nst_seq_fops = {
23865 .open = nst_fop_open,
23866 .read = seq_read,
23867 .llseek = seq_lseek,
23868@@ -344,7 +344,7 @@ static void sc_seq_stop(struct seq_file
23869 {
23870 }
23871
23872-static struct seq_operations sc_seq_ops = {
23873+static const struct seq_operations sc_seq_ops = {
23874 .start = sc_seq_start,
23875 .next = sc_seq_next,
23876 .stop = sc_seq_stop,
23877@@ -388,7 +388,7 @@ static int sc_fop_release(struct inode *
23878 return seq_release_private(inode, file);
23879 }
23880
23881-static struct file_operations sc_seq_fops = {
23882+static const struct file_operations sc_seq_fops = {
23883 .open = sc_fop_open,
23884 .read = seq_read,
23885 .llseek = seq_lseek,
23886diff -urNp linux-2.6.30.4/fs/ocfs2/dlm/dlmdebug.c linux-2.6.30.4/fs/ocfs2/dlm/dlmdebug.c
23887--- linux-2.6.30.4/fs/ocfs2/dlm/dlmdebug.c 2009-07-24 17:47:51.000000000 -0400
23888+++ linux-2.6.30.4/fs/ocfs2/dlm/dlmdebug.c 2009-07-30 09:48:10.092682326 -0400
23889@@ -479,7 +479,7 @@ bail:
23890 return -ENOMEM;
23891 }
23892
23893-static struct file_operations debug_purgelist_fops = {
23894+static const struct file_operations debug_purgelist_fops = {
23895 .open = debug_purgelist_open,
23896 .release = debug_buffer_release,
23897 .read = debug_buffer_read,
23898@@ -539,7 +539,7 @@ bail:
23899 return -ENOMEM;
23900 }
23901
23902-static struct file_operations debug_mle_fops = {
23903+static const struct file_operations debug_mle_fops = {
23904 .open = debug_mle_open,
23905 .release = debug_buffer_release,
23906 .read = debug_buffer_read,
23907@@ -683,7 +683,7 @@ static int lockres_seq_show(struct seq_f
23908 return 0;
23909 }
23910
23911-static struct seq_operations debug_lockres_ops = {
23912+static const struct seq_operations debug_lockres_ops = {
23913 .start = lockres_seq_start,
23914 .stop = lockres_seq_stop,
23915 .next = lockres_seq_next,
23916@@ -742,7 +742,7 @@ static int debug_lockres_release(struct
23917 return seq_release_private(inode, file);
23918 }
23919
23920-static struct file_operations debug_lockres_fops = {
23921+static const struct file_operations debug_lockres_fops = {
23922 .open = debug_lockres_open,
23923 .release = debug_lockres_release,
23924 .read = seq_read,
23925@@ -926,7 +926,7 @@ bail:
23926 return -ENOMEM;
23927 }
23928
23929-static struct file_operations debug_state_fops = {
23930+static const struct file_operations debug_state_fops = {
23931 .open = debug_state_open,
23932 .release = debug_buffer_release,
23933 .read = debug_buffer_read,
23934diff -urNp linux-2.6.30.4/fs/ocfs2/localalloc.c linux-2.6.30.4/fs/ocfs2/localalloc.c
23935--- linux-2.6.30.4/fs/ocfs2/localalloc.c 2009-07-24 17:47:51.000000000 -0400
23936+++ linux-2.6.30.4/fs/ocfs2/localalloc.c 2009-07-30 09:48:10.094563975 -0400
23937@@ -1186,7 +1186,7 @@ static int ocfs2_local_alloc_slide_windo
de855c5d
AM
23938 goto bail;
23939 }
23940
23941- atomic_inc(&osb->alloc_stats.moves);
23942+ atomic_inc_unchecked(&osb->alloc_stats.moves);
23943
23944 status = 0;
23945 bail:
017d2877
AM
23946diff -urNp linux-2.6.30.4/fs/ocfs2/mmap.c linux-2.6.30.4/fs/ocfs2/mmap.c
23947--- linux-2.6.30.4/fs/ocfs2/mmap.c 2009-07-24 17:47:51.000000000 -0400
23948+++ linux-2.6.30.4/fs/ocfs2/mmap.c 2009-07-30 09:48:10.094563975 -0400
23949@@ -202,7 +202,7 @@ out:
23950 return ret;
23951 }
23952
23953-static struct vm_operations_struct ocfs2_file_vm_ops = {
23954+static const struct vm_operations_struct ocfs2_file_vm_ops = {
23955 .fault = ocfs2_fault,
23956 .page_mkwrite = ocfs2_page_mkwrite,
23957 };
23958diff -urNp linux-2.6.30.4/fs/ocfs2/ocfs2.h linux-2.6.30.4/fs/ocfs2/ocfs2.h
23959--- linux-2.6.30.4/fs/ocfs2/ocfs2.h 2009-07-24 17:47:51.000000000 -0400
23960+++ linux-2.6.30.4/fs/ocfs2/ocfs2.h 2009-07-30 09:48:10.094563975 -0400
de855c5d
AM
23961@@ -168,11 +168,11 @@ enum ocfs2_vol_state
23962
23963 struct ocfs2_alloc_stats
23964 {
23965- atomic_t moves;
23966- atomic_t local_data;
23967- atomic_t bitmap_data;
23968- atomic_t bg_allocs;
23969- atomic_t bg_extends;
23970+ atomic_unchecked_t moves;
23971+ atomic_unchecked_t local_data;
23972+ atomic_unchecked_t bitmap_data;
23973+ atomic_unchecked_t bg_allocs;
23974+ atomic_unchecked_t bg_extends;
23975 };
23976
23977 enum ocfs2_local_alloc_state
017d2877
AM
23978diff -urNp linux-2.6.30.4/fs/ocfs2/suballoc.c linux-2.6.30.4/fs/ocfs2/suballoc.c
23979--- linux-2.6.30.4/fs/ocfs2/suballoc.c 2009-07-24 17:47:51.000000000 -0400
23980+++ linux-2.6.30.4/fs/ocfs2/suballoc.c 2009-07-30 09:48:10.094563975 -0400
23981@@ -620,7 +620,7 @@ static int ocfs2_reserve_suballoc_bits(s
de855c5d
AM
23982 mlog_errno(status);
23983 goto bail;
23984 }
23985- atomic_inc(&osb->alloc_stats.bg_extends);
23986+ atomic_inc_unchecked(&osb->alloc_stats.bg_extends);
23987
23988 /* You should never ask for this much metadata */
23989 BUG_ON(bits_wanted >
017d2877 23990@@ -1641,7 +1641,7 @@ int ocfs2_claim_metadata(struct ocfs2_su
de855c5d
AM
23991 mlog_errno(status);
23992 goto bail;
23993 }
23994- atomic_inc(&osb->alloc_stats.bg_allocs);
23995+ atomic_inc_unchecked(&osb->alloc_stats.bg_allocs);
23996
23997 *blkno_start = bg_blkno + (u64) *suballoc_bit_start;
23998 ac->ac_bits_given += (*num_bits);
017d2877 23999@@ -1715,7 +1715,7 @@ int ocfs2_claim_new_inode(struct ocfs2_s
de855c5d
AM
24000 mlog_errno(status);
24001 goto bail;
24002 }
24003- atomic_inc(&osb->alloc_stats.bg_allocs);
24004+ atomic_inc_unchecked(&osb->alloc_stats.bg_allocs);
24005
24006 BUG_ON(num_bits != 1);
24007
017d2877 24008@@ -1817,7 +1817,7 @@ int __ocfs2_claim_clusters(struct ocfs2_
de855c5d
AM
24009 cluster_start,
24010 num_clusters);
24011 if (!status)
24012- atomic_inc(&osb->alloc_stats.local_data);
24013+ atomic_inc_unchecked(&osb->alloc_stats.local_data);
24014 } else {
24015 if (min_clusters > (osb->bitmap_cpg - 1)) {
24016 /* The only paths asking for contiguousness
017d2877 24017@@ -1845,7 +1845,7 @@ int __ocfs2_claim_clusters(struct ocfs2_
de855c5d
AM
24018 ocfs2_desc_bitmap_to_cluster_off(ac->ac_inode,
24019 bg_blkno,
24020 bg_bit_off);
24021- atomic_inc(&osb->alloc_stats.bitmap_data);
24022+ atomic_inc_unchecked(&osb->alloc_stats.bitmap_data);
24023 }
24024 }
24025 if (status < 0) {
017d2877
AM
24026diff -urNp linux-2.6.30.4/fs/ocfs2/super.c linux-2.6.30.4/fs/ocfs2/super.c
24027--- linux-2.6.30.4/fs/ocfs2/super.c 2009-07-24 17:47:51.000000000 -0400
24028+++ linux-2.6.30.4/fs/ocfs2/super.c 2009-07-30 12:06:52.187885986 -0400
24029@@ -362,7 +362,7 @@ static ssize_t ocfs2_debug_read(struct f
24030 }
24031 #endif /* CONFIG_DEBUG_FS */
24032
24033-static struct file_operations ocfs2_osb_debug_fops = {
24034+static const struct file_operations ocfs2_osb_debug_fops = {
24035 .open = ocfs2_osb_debug_open,
24036 .release = ocfs2_debug_release,
24037 .read = ocfs2_debug_read,
24038diff -urNp linux-2.6.30.4/fs/omfs/dir.c linux-2.6.30.4/fs/omfs/dir.c
24039--- linux-2.6.30.4/fs/omfs/dir.c 2009-07-24 17:47:51.000000000 -0400
24040+++ linux-2.6.30.4/fs/omfs/dir.c 2009-07-30 09:48:10.094563975 -0400
24041@@ -489,7 +489,7 @@ out:
24042 return ret;
24043 }
24044
24045-struct inode_operations omfs_dir_inops = {
24046+const struct inode_operations omfs_dir_inops = {
24047 .lookup = omfs_lookup,
24048 .mkdir = omfs_mkdir,
24049 .rename = omfs_rename,
24050@@ -498,7 +498,7 @@ struct inode_operations omfs_dir_inops =
24051 .rmdir = omfs_rmdir,
24052 };
24053
24054-struct file_operations omfs_dir_operations = {
24055+const struct file_operations omfs_dir_operations = {
24056 .read = generic_read_dir,
24057 .readdir = omfs_readdir,
24058 .llseek = generic_file_llseek,
24059diff -urNp linux-2.6.30.4/fs/omfs/file.c linux-2.6.30.4/fs/omfs/file.c
24060--- linux-2.6.30.4/fs/omfs/file.c 2009-07-24 17:47:51.000000000 -0400
24061+++ linux-2.6.30.4/fs/omfs/file.c 2009-07-30 09:48:10.094563975 -0400
24062@@ -337,7 +337,7 @@ static sector_t omfs_bmap(struct address
24063 return generic_block_bmap(mapping, block, omfs_get_block);
24064 }
24065
24066-struct file_operations omfs_file_operations = {
24067+const struct file_operations omfs_file_operations = {
24068 .llseek = generic_file_llseek,
24069 .read = do_sync_read,
24070 .write = do_sync_write,
24071@@ -348,11 +348,11 @@ struct file_operations omfs_file_operati
24072 .splice_read = generic_file_splice_read,
24073 };
24074
24075-struct inode_operations omfs_file_inops = {
24076+const struct inode_operations omfs_file_inops = {
24077 .truncate = omfs_truncate
24078 };
24079
24080-struct address_space_operations omfs_aops = {
24081+const struct address_space_operations omfs_aops = {
24082 .readpage = omfs_readpage,
24083 .readpages = omfs_readpages,
24084 .writepage = omfs_writepage,
24085diff -urNp linux-2.6.30.4/fs/omfs/inode.c linux-2.6.30.4/fs/omfs/inode.c
24086--- linux-2.6.30.4/fs/omfs/inode.c 2009-07-24 17:47:51.000000000 -0400
24087+++ linux-2.6.30.4/fs/omfs/inode.c 2009-07-30 09:48:10.096509014 -0400
24088@@ -278,7 +278,7 @@ static int omfs_statfs(struct dentry *de
24089 return 0;
24090 }
24091
24092-static struct super_operations omfs_sops = {
24093+static const struct super_operations omfs_sops = {
24094 .write_inode = omfs_write_inode,
24095 .delete_inode = omfs_delete_inode,
24096 .put_super = omfs_put_super,
24097diff -urNp linux-2.6.30.4/fs/omfs/omfs.h linux-2.6.30.4/fs/omfs/omfs.h
24098--- linux-2.6.30.4/fs/omfs/omfs.h 2009-07-24 17:47:51.000000000 -0400
24099+++ linux-2.6.30.4/fs/omfs/omfs.h 2009-07-30 09:48:10.096509014 -0400
24100@@ -44,16 +44,16 @@ extern int omfs_allocate_range(struct su
24101 extern int omfs_clear_range(struct super_block *sb, u64 block, int count);
24102
24103 /* dir.c */
24104-extern struct file_operations omfs_dir_operations;
24105-extern struct inode_operations omfs_dir_inops;
24106+extern const struct file_operations omfs_dir_operations;
24107+extern const struct inode_operations omfs_dir_inops;
24108 extern int omfs_make_empty(struct inode *inode, struct super_block *sb);
24109 extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header,
24110 u64 fsblock);
24111
24112 /* file.c */
24113-extern struct file_operations omfs_file_operations;
24114-extern struct inode_operations omfs_file_inops;
24115-extern struct address_space_operations omfs_aops;
24116+extern const struct file_operations omfs_file_operations;
24117+extern const struct inode_operations omfs_file_inops;
24118+extern const struct address_space_operations omfs_aops;
24119 extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
24120 extern int omfs_shrink_inode(struct inode *inode);
24121
24122diff -urNp linux-2.6.30.4/fs/open.c linux-2.6.30.4/fs/open.c
24123--- linux-2.6.30.4/fs/open.c 2009-07-24 17:47:51.000000000 -0400
24124+++ linux-2.6.30.4/fs/open.c 2009-07-30 11:10:49.258897345 -0400
24125@@ -215,6 +215,9 @@
2380c486
JR
24126 if (length < 0)
24127 return -EINVAL;
24128
24129+ if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
24130+ return -EACCES;
24131+
24132 newattrs.ia_size = length;
24133 newattrs.ia_valid = ATTR_SIZE | time_attrs;
24134 if (filp) {
017d2877 24135@@ -519,6 +522,9 @@
2380c486
JR
24136 if (__mnt_is_readonly(path.mnt))
24137 res = -EROFS;
24138
24139+ if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
24140+ res = -EACCES;
24141+
24142 out_path_release:
24143 path_put(&path);
24144 out:
017d2877 24145@@ -545,6 +551,8 @@
2380c486
JR
24146 if (error)
24147 goto dput_and_out;
24148
24149+ gr_log_chdir(path.dentry, path.mnt);
24150+
24151 set_fs_pwd(current->fs, &path);
24152
24153 dput_and_out:
017d2877 24154@@ -571,6 +579,13 @@
2380c486
JR
24155 goto out_putf;
24156
24157 error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
24158+
24159+ if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
24160+ error = -EPERM;
24161+
24162+ if (!error)
24163+ gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
24164+
24165 if (!error)
24166 set_fs_pwd(current->fs, &file->f_path);
24167 out_putf:
017d2877 24168@@ -596,7 +611,18 @@
2380c486
JR
24169 if (!capable(CAP_SYS_CHROOT))
24170 goto dput_and_out;
24171
24172+ if (gr_handle_chroot_chroot(path.dentry, path.mnt))
24173+ goto dput_and_out;
24174+
24175+ if (gr_handle_chroot_caps(&path)) {
24176+ error = -ENOMEM;
24177+ goto dput_and_out;
24178+ }
24179+
24180 set_fs_root(current->fs, &path);
24181+
24182+ gr_handle_chroot_chdir(&path);
24183+
24184 error = 0;
24185 dput_and_out:
24186 path_put(&path);
017d2877 24187@@ -624,13 +650,28 @@
2380c486
JR
24188 err = mnt_want_write(file->f_path.mnt);
24189 if (err)
24190 goto out_putf;
24191+
24192+ if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
24193+ err = -EACCES;
24194+ goto out_drop_write;
24195+ }
24196+
24197 mutex_lock(&inode->i_mutex);
24198 if (mode == (mode_t) -1)
24199 mode = inode->i_mode;
24200+
24201+ if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
24202+ err = -EPERM;
24203+ mutex_unlock(&inode->i_mutex);
24204+ goto out_drop_write;
24205+ }
24206+
24207 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
24208 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
24209 err = notify_change(dentry, &newattrs);
24210 mutex_unlock(&inode->i_mutex);
24211+
24212+out_drop_write:
24213 mnt_drop_write(file->f_path.mnt);
24214 out_putf:
24215 fput(file);
017d2877 24216@@ -657,13 +698,28 @@
2380c486
JR
24217 error = mnt_want_write(path.mnt);
24218 if (error)
24219 goto dput_and_out;
24220+
24221+ if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
24222+ error = -EACCES;
24223+ goto out_drop_write;
24224+ }
24225+
24226 mutex_lock(&inode->i_mutex);
24227 if (mode == (mode_t) -1)
24228 mode = inode->i_mode;
24229+
24230+ if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
24231+ error = -EACCES;
24232+ mutex_unlock(&inode->i_mutex);
24233+ goto out_drop_write;
24234+ }
24235+
24236 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
24237 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
24238 error = notify_change(path.dentry, &newattrs);
24239 mutex_unlock(&inode->i_mutex);
24240+
24241+out_drop_write:
24242 mnt_drop_write(path.mnt);
24243 dput_and_out:
24244 path_put(&path);
017d2877 24245@@ -676,12 +732,15 @@
2380c486
JR
24246 return sys_fchmodat(AT_FDCWD, filename, mode);
24247 }
24248
24249-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
24250+static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
24251 {
24252 struct inode *inode = dentry->d_inode;
24253 int error;
24254 struct iattr newattrs;
24255
24256+ if (!gr_acl_handle_chown(dentry, mnt))
24257+ return -EACCES;
24258+
24259 newattrs.ia_valid = ATTR_CTIME;
24260 if (user != (uid_t) -1) {
24261 newattrs.ia_valid |= ATTR_UID;
017d2877
AM
24262@@ -716,7 +775,7 @@
24263 error = cow_check_and_break(&path);
24264 if (!error)
24265 #endif
24266- error = chown_common(path.dentry, user, group);
24267+ error = chown_common(path.dentry, user, group, path.mnt);
2380c486
JR
24268 mnt_drop_write(path.mnt);
24269 out_release:
24270 path_put(&path);
017d2877
AM
24271@@ -745,7 +804,7 @@
24272 error = cow_check_and_break(&path);
24273 if (!error)
24274 #endif
24275- error = chown_common(path.dentry, user, group);
24276+ error = chown_common(path.dentry, user, group, path.mnt);
2380c486
JR
24277 mnt_drop_write(path.mnt);
24278 out_release:
24279 path_put(&path);
017d2877
AM
24280@@ -768,7 +827,7 @@
24281 error = cow_check_and_break(&path);
24282 if (!error)
24283 #endif
24284- error = chown_common(path.dentry, user, group);
24285+ error = chown_common(path.dentry, user, group, path.mnt);
2380c486
JR
24286 mnt_drop_write(path.mnt);
24287 out_release:
24288 path_put(&path);
017d2877 24289@@ -791,7 +850,7 @@
2380c486
JR
24290 goto out_fput;
24291 dentry = file->f_path.dentry;
24292 audit_inode(NULL, dentry);
24293- error = chown_common(dentry, user, group);
24294+ error = chown_common(dentry, user, group, file->f_path.mnt);
24295 mnt_drop_write(file->f_path.mnt);
24296 out_fput:
24297 fput(file);
017d2877
AM
24298diff -urNp linux-2.6.30.4/fs/pipe.c linux-2.6.30.4/fs/pipe.c
24299--- linux-2.6.30.4/fs/pipe.c 2009-07-24 17:47:51.000000000 -0400
24300+++ linux-2.6.30.4/fs/pipe.c 2009-07-30 11:10:49.268433019 -0400
24301@@ -872,7 +872,7 @@ void free_pipe_info(struct inode *inode)
2380c486
JR
24302 inode->i_pipe = NULL;
24303 }
24304
24305-static struct vfsmount *pipe_mnt __read_mostly;
24306+struct vfsmount *pipe_mnt __read_mostly;
24307 static int pipefs_delete_dentry(struct dentry *dentry)
24308 {
24309 /*
017d2877
AM
24310diff -urNp linux-2.6.30.4/fs/proc/array.c linux-2.6.30.4/fs/proc/array.c
24311--- linux-2.6.30.4/fs/proc/array.c 2009-07-24 17:47:51.000000000 -0400
24312+++ linux-2.6.30.4/fs/proc/array.c 2009-07-30 11:10:49.279288424 -0400
de855c5d 24313@@ -321,6 +321,21 @@ static inline void task_context_switch_c
2380c486
JR
24314 p->nivcsw);
24315 }
24316
24317+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
24318+static inline void task_pax(struct seq_file *m, struct task_struct *p)
24319+{
24320+ if (p->mm)
24321+ seq_printf(m, "PaX:\t%c%c%c%c%c\n",
24322+ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
24323+ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
24324+ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
24325+ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
24326+ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
24327+ else
24328+ seq_printf(m, "PaX:\t-----\n");
24329+}
24330+#endif
24331+
24332 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
24333 struct pid *pid, struct task_struct *task)
24334 {
de855c5d 24335@@ -340,9 +355,20 @@ int proc_pid_status(struct seq_file *m,
2380c486
JR
24336 task_show_regs(m, task);
24337 #endif
24338 task_context_switch_counts(m, task);
24339+
24340+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
24341+ task_pax(m, task);
24342+#endif
24343+
24344 return 0;
24345 }
24346
24347+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
24348+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
24349+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
24350+ _mm->pax_flags & MF_PAX_SEGMEXEC))
24351+#endif
24352+
24353 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
24354 struct pid *pid, struct task_struct *task, int whole)
24355 {
de855c5d 24356@@ -439,6 +465,19 @@ static int do_task_stat(struct seq_file
2380c486
JR
24357 gtime = task_gtime(task);
24358 }
24359
24360+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
24361+ if (PAX_RAND_FLAGS(mm)) {
24362+ eip = 0;
24363+ esp = 0;
24364+ wchan = 0;
24365+ }
24366+#endif
24367+#ifdef CONFIG_GRKERNSEC_HIDESYM
24368+ wchan = 0;
24369+ eip =0;
24370+ esp =0;
24371+#endif
24372+
24373 /* scale priority and nice values from timeslices to -20..20 */
24374 /* to make it look like a "normal" Unix priority/nice value */
24375 priority = task_prio(task);
de855c5d 24376@@ -479,9 +518,15 @@ static int do_task_stat(struct seq_file
2380c486
JR
24377 vsize,
24378 mm ? get_mm_rss(mm) : 0,
24379 rsslim,
24380+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
24381+ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
24382+ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
de855c5d 24383+ PAX_RAND_FLAGS(mm) ? 0 : ((permitted && mm) ? mm->start_stack : 0),
2380c486
JR
24384+#else
24385 mm ? mm->start_code : 0,
24386 mm ? mm->end_code : 0,
de855c5d 24387 (permitted && mm) ? mm->start_stack : 0,
2380c486
JR
24388+#endif
24389 esp,
24390 eip,
24391 /* The signal information here is obsolete.
de855c5d 24392@@ -534,3 +579,10 @@ int proc_pid_statm(struct seq_file *m, s
2380c486
JR
24393
24394 return 0;
24395 }
24396+
24397+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
24398+int proc_pid_ipaddr(struct task_struct *task, char *buffer)
24399+{
24400+ return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
24401+}
24402+#endif
017d2877
AM
24403diff -urNp linux-2.6.30.4/fs/proc/base.c linux-2.6.30.4/fs/proc/base.c
24404--- linux-2.6.30.4/fs/proc/base.c 2009-07-24 17:47:51.000000000 -0400
24405+++ linux-2.6.30.4/fs/proc/base.c 2009-07-30 11:10:49.291551908 -0400
24406@@ -2887,6 +2887,10 @@ int proc_pid_readdir(struct file * filp,
2380c486
JR
24407 {
24408 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
017d2877 24409 struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
2380c486
JR
24410+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
24411+ const struct cred *tmpcred = current_cred();
24412+ const struct cred *itercred;
24413+#endif
24414 struct tgid_iter iter;
24415 struct pid_namespace *ns;
24416
017d2877 24417@@ -2905,6 +2909,19 @@ int proc_pid_readdir(struct file * filp,
2380c486
JR
24418 for (iter = next_tgid(ns, iter);
24419 iter.task;
24420 iter.tgid += 1, iter = next_tgid(ns, iter)) {
24421+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
24422+ itercred = __task_cred(iter.task);
24423+#endif
24424+ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
24425+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
017d2877 24426+ || (tmpcred->uid && (itercred->uid != tmpcred->uid)
2380c486 24427+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
de855c5d 24428+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
2380c486 24429+#endif
de855c5d 24430+ )
2380c486 24431+#endif
017d2877 24432+ )
2380c486 24433+ continue;
2380c486 24434 filp->f_pos = iter.tgid + TGID_OFFSET;
017d2877
AM
24435 if (!vx_proc_task_visible(iter.task))
24436 continue;
24437@@ -2934,7 +2951,7 @@ static const struct pid_entry tid_base_s
de855c5d
AM
24438 #ifdef CONFIG_SCHED_DEBUG
24439 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2380c486 24440 #endif
de855c5d
AM
24441-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
24442+#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
24443 INF("syscall", S_IRUSR, proc_pid_syscall),
24444 #endif
24445 INF("cmdline", S_IRUGO, proc_pid_cmdline),
017d2877 24446@@ -2961,7 +2978,7 @@ static const struct pid_entry tid_base_s
de855c5d
AM
24447 #ifdef CONFIG_KALLSYMS
24448 INF("wchan", S_IRUGO, proc_pid_wchan),
24449 #endif
24450-#ifdef CONFIG_STACKTRACE
24451+#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM)
24452 ONE("stack", S_IRUSR, proc_pid_stack),
24453 #endif
24454 #ifdef CONFIG_SCHEDSTATS
017d2877
AM
24455diff -urNp linux-2.6.30.4/fs/proc/cmdline.c linux-2.6.30.4/fs/proc/cmdline.c
24456--- linux-2.6.30.4/fs/proc/cmdline.c 2009-07-24 17:47:51.000000000 -0400
24457+++ linux-2.6.30.4/fs/proc/cmdline.c 2009-07-30 11:10:49.303499047 -0400
2380c486
JR
24458@@ -23,7 +23,11 @@ static const struct file_operations cmdl
24459
24460 static int __init proc_cmdline_init(void)
24461 {
24462+#ifdef CONFIG_GRKERNSEC_PROC_ADD
24463+ proc_create_grsec("cmdline", 0, NULL, &cmdline_proc_fops);
24464+#else
24465 proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
24466+#endif
24467 return 0;
24468 }
24469 module_init(proc_cmdline_init);
017d2877
AM
24470diff -urNp linux-2.6.30.4/fs/proc/devices.c linux-2.6.30.4/fs/proc/devices.c
24471--- linux-2.6.30.4/fs/proc/devices.c 2009-07-24 17:47:51.000000000 -0400
24472+++ linux-2.6.30.4/fs/proc/devices.c 2009-07-30 11:10:49.304300221 -0400
2380c486
JR
24473@@ -64,7 +64,11 @@ static const struct file_operations proc
24474
24475 static int __init proc_devices_init(void)
24476 {
24477+#ifdef CONFIG_GRKERNSEC_PROC_ADD
24478+ proc_create_grsec("devices", 0, NULL, &proc_devinfo_operations);
24479+#else
24480 proc_create("devices", 0, NULL, &proc_devinfo_operations);
24481+#endif
24482 return 0;
24483 }
24484 module_init(proc_devices_init);
017d2877
AM
24485diff -urNp linux-2.6.30.4/fs/proc/inode.c linux-2.6.30.4/fs/proc/inode.c
24486--- linux-2.6.30.4/fs/proc/inode.c 2009-07-24 17:47:51.000000000 -0400
24487+++ linux-2.6.30.4/fs/proc/inode.c 2009-07-30 11:10:49.304300221 -0400
24488@@ -457,7 +457,11 @@ struct inode *proc_get_inode(struct supe
2380c486
JR
24489 if (de->mode) {
24490 inode->i_mode = de->mode;
24491 inode->i_uid = de->uid;
24492+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
24493+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
24494+#else
24495 inode->i_gid = de->gid;
24496+#endif
24497 }
24498 if (de->size)
24499 inode->i_size = de->size;
017d2877
AM
24500diff -urNp linux-2.6.30.4/fs/proc/internal.h linux-2.6.30.4/fs/proc/internal.h
24501--- linux-2.6.30.4/fs/proc/internal.h 2009-07-24 17:47:51.000000000 -0400
24502+++ linux-2.6.30.4/fs/proc/internal.h 2009-07-30 11:10:49.305386482 -0400
24503@@ -54,7 +54,9 @@
2380c486 24504 struct pid *pid, struct task_struct *task);
017d2877 24505 extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
2380c486 24506 struct pid *pid, struct task_struct *task);
017d2877 24507-
2380c486
JR
24508+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
24509+extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
24510+#endif
2380c486
JR
24511 extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
24512
de855c5d 24513 extern const struct file_operations proc_maps_operations;
017d2877
AM
24514diff -urNp linux-2.6.30.4/fs/proc/Kconfig linux-2.6.30.4/fs/proc/Kconfig
24515--- linux-2.6.30.4/fs/proc/Kconfig 2009-07-24 17:47:51.000000000 -0400
24516+++ linux-2.6.30.4/fs/proc/Kconfig 2009-07-30 11:10:49.305386482 -0400
2380c486
JR
24517@@ -30,12 +30,12 @@ config PROC_FS
24518
24519 config PROC_KCORE
24520 bool "/proc/kcore support" if !ARM
24521- depends on PROC_FS && MMU
24522+ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
24523
24524 config PROC_VMCORE
24525 bool "/proc/vmcore support (EXPERIMENTAL)"
24526- depends on PROC_FS && CRASH_DUMP
24527- default y
24528+ depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
24529+ default n
24530 help
24531 Exports the dump image of crashed kernel in ELF format.
24532
24533@@ -59,8 +59,8 @@ config PROC_SYSCTL
24534 limited in memory.
24535
24536 config PROC_PAGE_MONITOR
24537- default y
24538- depends on PROC_FS && MMU
24539+ default n
24540+ depends on PROC_FS && MMU && !GRKERNSEC
24541 bool "Enable /proc page monitoring" if EMBEDDED
24542 help
24543 Various /proc files exist to monitor process memory utilization:
017d2877
AM
24544diff -urNp linux-2.6.30.4/fs/proc/kcore.c linux-2.6.30.4/fs/proc/kcore.c
24545--- linux-2.6.30.4/fs/proc/kcore.c 2009-07-24 17:47:51.000000000 -0400
24546+++ linux-2.6.30.4/fs/proc/kcore.c 2009-07-30 11:10:49.306366172 -0400
2380c486
JR
24547@@ -404,10 +404,12 @@ read_kcore(struct file *file, char __use
24548
24549 static int __init proc_kcore_init(void)
24550 {
24551+#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
24552 proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
24553 if (proc_root_kcore)
24554 proc_root_kcore->size =
24555 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
24556+#endif
24557 return 0;
24558 }
24559 module_init(proc_kcore_init);
017d2877
AM
24560diff -urNp linux-2.6.30.4/fs/proc/nommu.c linux-2.6.30.4/fs/proc/nommu.c
24561--- linux-2.6.30.4/fs/proc/nommu.c 2009-07-24 17:47:51.000000000 -0400
24562+++ linux-2.6.30.4/fs/proc/nommu.c 2009-07-30 09:48:10.096509014 -0400
2380c486
JR
24563@@ -67,7 +67,7 @@ static int nommu_region_show(struct seq_
24564 if (len < 1)
24565 len = 1;
24566 seq_printf(m, "%*c", len, ' ');
24567- seq_path(m, &file->f_path, "");
24568+ seq_path(m, &file->f_path, "\n\\");
24569 }
24570
24571 seq_putc(m, '\n');
017d2877
AM
24572@@ -109,7 +109,7 @@ static void *nommu_region_list_next(stru
24573 return rb_next((struct rb_node *) v);
24574 }
24575
24576-static struct seq_operations proc_nommu_region_list_seqop = {
24577+static const struct seq_operations proc_nommu_region_list_seqop = {
24578 .start = nommu_region_list_start,
24579 .next = nommu_region_list_next,
24580 .stop = nommu_region_list_stop,
24581diff -urNp linux-2.6.30.4/fs/proc/proc_net.c linux-2.6.30.4/fs/proc/proc_net.c
24582--- linux-2.6.30.4/fs/proc/proc_net.c 2009-07-24 17:47:51.000000000 -0400
24583+++ linux-2.6.30.4/fs/proc/proc_net.c 2009-07-30 11:10:49.306366172 -0400
2380c486
JR
24584@@ -104,6 +104,17 @@ static struct net *get_proc_task_net(str
24585 struct task_struct *task;
24586 struct nsproxy *ns;
24587 struct net *net = NULL;
24588+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
24589+ const struct cred *cred = current_cred();
24590+#endif
24591+
24592+#ifdef CONFIG_GRKERNSEC_PROC_USER
24593+ if (cred->fsuid)
24594+ return net;
24595+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
24596+ if (cred->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
24597+ return net;
24598+#endif
24599
24600 rcu_read_lock();
24601 task = pid_task(proc_pid(dir), PIDTYPE_PID);
017d2877
AM
24602diff -urNp linux-2.6.30.4/fs/proc/proc_sysctl.c linux-2.6.30.4/fs/proc/proc_sysctl.c
24603--- linux-2.6.30.4/fs/proc/proc_sysctl.c 2009-07-24 17:47:51.000000000 -0400
24604+++ linux-2.6.30.4/fs/proc/proc_sysctl.c 2009-07-30 11:10:49.307381327 -0400
2380c486
JR
24605@@ -7,6 +7,8 @@
24606 #include <linux/security.h>
24607 #include "internal.h"
24608
24609+extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
24610+
017d2877 24611 static const struct dentry_operations proc_sys_dentry_operations;
2380c486
JR
24612 static const struct file_operations proc_sys_file_operations;
24613 static const struct inode_operations proc_sys_inode_operations;
24614@@ -109,6 +111,9 @@ static struct dentry *proc_sys_lookup(st
24615 if (!p)
24616 goto out;
24617
24618+ if (gr_handle_sysctl(p, MAY_EXEC))
24619+ goto out;
24620+
24621 err = ERR_PTR(-ENOMEM);
24622 inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
24623 if (h)
24624@@ -228,6 +233,9 @@ static int scan(struct ctl_table_header
24625 if (*pos < file->f_pos)
24626 continue;
24627
24628+ if (gr_handle_sysctl(table, 0))
24629+ continue;
24630+
24631 res = proc_sys_fill_cache(file, dirent, filldir, head, table);
24632 if (res)
24633 return res;
24634@@ -344,6 +352,9 @@ static int proc_sys_getattr(struct vfsmo
24635 if (IS_ERR(head))
24636 return PTR_ERR(head);
24637
24638+ if (table && gr_handle_sysctl(table, MAY_EXEC))
24639+ return -ENOENT;
24640+
24641 generic_fillattr(inode, stat);
24642 if (table)
24643 stat->mode = (stat->mode & S_IFMT) | table->mode;
017d2877
AM
24644diff -urNp linux-2.6.30.4/fs/proc/root.c linux-2.6.30.4/fs/proc/root.c
24645--- linux-2.6.30.4/fs/proc/root.c 2009-07-24 17:47:51.000000000 -0400
24646+++ linux-2.6.30.4/fs/proc/root.c 2009-07-30 11:10:49.307381327 -0400
de855c5d
AM
24647@@ -101,6 +101,11 @@ static struct file_system_type proc_fs_t
24648 .kill_sb = proc_kill_sb,
24649 };
24650
24651+#ifdef CONFIG_GRKERNSEC_HIDESYM
24652+static const struct file_operations __kallsyms_operations = {
24653+};
24654+#endif
24655+
24656 void __init proc_root_init(void)
24657 {
24658 int err;
24659@@ -134,8 +139,21 @@ void __init proc_root_init(void)
2380c486
JR
24660 #ifdef CONFIG_PROC_DEVICETREE
24661 proc_device_tree_init();
24662 #endif
24663+#ifdef CONFIG_GRKERNSEC_PROC_ADD
24664+#ifdef CONFIG_GRKERNSEC_PROC_USER
24665+ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
24666+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
24667+ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
24668+#endif
24669+#else
24670 proc_mkdir("bus", NULL);
24671+#endif
24672 proc_sys_init();
017d2877 24673 proc_vx_init();
de855c5d
AM
24674+
24675+#ifdef CONFIG_GRKERNSEC_HIDESYM
24676+ /* fake kallsyms to workaround klogd bug */
24677+ proc_create("kallsyms", 0444, NULL, &__kallsyms_operations);
24678+#endif
2380c486
JR
24679 }
24680
017d2877
AM
24681diff -urNp linux-2.6.30.4/fs/proc/task_mmu.c linux-2.6.30.4/fs/proc/task_mmu.c
24682--- linux-2.6.30.4/fs/proc/task_mmu.c 2009-07-24 17:47:51.000000000 -0400
24683+++ linux-2.6.30.4/fs/proc/task_mmu.c 2009-07-30 11:27:12.967439752 -0400
2380c486
JR
24684@@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
24685 "VmStk:\t%8lu kB\n"
24686 "VmExe:\t%8lu kB\n"
24687 "VmLib:\t%8lu kB\n"
24688- "VmPTE:\t%8lu kB\n",
24689- hiwater_vm << (PAGE_SHIFT-10),
24690+ "VmPTE:\t%8lu kB\n"
24691+
24692+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
24693+ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
24694+#endif
24695+
24696+ ,hiwater_vm << (PAGE_SHIFT-10),
24697 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
24698 mm->locked_vm << (PAGE_SHIFT-10),
24699 hiwater_rss << (PAGE_SHIFT-10),
24700 total_rss << (PAGE_SHIFT-10),
24701 data << (PAGE_SHIFT-10),
24702 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
24703- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
24704+ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
24705+
24706+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
24707+ , mm->context.user_cs_base, mm->context.user_cs_limit
24708+#endif
24709+
24710+ );
24711 }
24712
24713 unsigned long task_vsize(struct mm_struct *mm)
24714@@ -198,6 +209,12 @@ static int do_maps_open(struct inode *in
24715 return ret;
24716 }
24717
24718+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
24719+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
24720+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
24721+ _mm->pax_flags & MF_PAX_SEGMEXEC))
24722+#endif
24723+
24724 static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
24725 {
24726 struct mm_struct *mm = vma->vm_mm;
017d2877 24727@@ -216,13 +233,22 @@ static void show_map_vma(struct seq_file
2380c486
JR
24728 }
24729
24730 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
24731+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
24732+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
24733+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
24734+#else
24735 vma->vm_start,
24736 vma->vm_end,
24737+#endif
24738 flags & VM_READ ? 'r' : '-',
24739 flags & VM_WRITE ? 'w' : '-',
24740 flags & VM_EXEC ? 'x' : '-',
24741 flags & VM_MAYSHARE ? 's' : 'p',
24742+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
017d2877 24743+ PAX_RAND_FLAGS(mm) ? 0UL : pgoff,
2380c486 24744+#else
017d2877 24745 pgoff,
2380c486
JR
24746+#endif
24747 MAJOR(dev), MINOR(dev), ino, &len);
24748
24749 /*
017d2877 24750@@ -231,16 +257,16 @@ static void show_map_vma(struct seq_file
2380c486
JR
24751 */
24752 if (file) {
24753 pad_len_spaces(m, len);
24754- seq_path(m, &file->f_path, "\n");
24755+ seq_path(m, &file->f_path, "\n\\");
24756 } else {
24757 const char *name = arch_vma_name(vma);
24758 if (!name) {
24759 if (mm) {
24760- if (vma->vm_start <= mm->start_brk &&
24761- vma->vm_end >= mm->brk) {
24762+ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
24763 name = "[heap]";
24764- } else if (vma->vm_start <= mm->start_stack &&
24765- vma->vm_end >= mm->start_stack) {
24766+ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
24767+ (vma->vm_start <= mm->start_stack &&
24768+ vma->vm_end >= mm->start_stack)) {
24769 name = "[stack]";
24770 }
24771 } else {
017d2877 24772@@ -383,9 +409,16 @@ static int show_smap(struct seq_file *m,
2380c486
JR
24773 };
24774
24775 memset(&mss, 0, sizeof mss);
24776- mss.vma = vma;
24777- if (vma->vm_mm && !is_vm_hugetlb_page(vma))
24778- walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
24779+
24780+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
24781+ if (!PAX_RAND_FLAGS(vma->vm_mm)) {
24782+#endif
24783+ mss.vma = vma;
24784+ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
24785+ walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
24786+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
24787+ }
24788+#endif
24789
24790 show_map_vma(m, vma);
24791
017d2877 24792@@ -401,7 +434,11 @@ static int show_smap(struct seq_file *m,
2380c486
JR
24793 "Swap: %8lu kB\n"
24794 "KernelPageSize: %8lu kB\n"
24795 "MMUPageSize: %8lu kB\n",
24796+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
24797+ PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
24798+#else
24799 (vma->vm_end - vma->vm_start) >> 10,
24800+#endif
24801 mss.resident >> 10,
24802 (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
24803 mss.shared_clean >> 10,
017d2877
AM
24804diff -urNp linux-2.6.30.4/fs/proc/task_nommu.c linux-2.6.30.4/fs/proc/task_nommu.c
24805--- linux-2.6.30.4/fs/proc/task_nommu.c 2009-07-24 17:47:51.000000000 -0400
24806+++ linux-2.6.30.4/fs/proc/task_nommu.c 2009-07-30 09:48:10.096509014 -0400
24807@@ -50,7 +50,7 @@ void task_mem(struct seq_file *m, struct
de855c5d
AM
24808 else
24809 bytes += kobjsize(mm);
24810
24811- if (current->fs && current->fs->users > 1)
24812+ if (current->fs && atomic_read(&current->fs->users) > 1)
24813 sbytes += kobjsize(current->fs);
24814 else
24815 bytes += kobjsize(current->fs);
017d2877 24816@@ -154,7 +154,7 @@ static int nommu_vma_show(struct seq_fil
2380c486
JR
24817 if (len < 1)
24818 len = 1;
24819 seq_printf(m, "%*c", len, ' ');
24820- seq_path(m, &file->f_path, "");
24821+ seq_path(m, &file->f_path, "\n\\");
24822 }
24823
24824 seq_putc(m, '\n');
017d2877
AM
24825diff -urNp linux-2.6.30.4/fs/readdir.c linux-2.6.30.4/fs/readdir.c
24826--- linux-2.6.30.4/fs/readdir.c 2009-07-24 17:47:51.000000000 -0400
24827+++ linux-2.6.30.4/fs/readdir.c 2009-07-30 11:10:49.318449083 -0400
2380c486
JR
24828@@ -16,6 +16,7 @@
24829 #include <linux/security.h>
24830 #include <linux/syscalls.h>
24831 #include <linux/unistd.h>
24832+#include <linux/namei.h>
24833
24834 #include <asm/uaccess.h>
24835
24836@@ -67,6 +68,7 @@ struct old_linux_dirent {
24837
24838 struct readdir_callback {
24839 struct old_linux_dirent __user * dirent;
24840+ struct file * file;
24841 int result;
24842 };
24843
24844@@ -84,6 +86,10 @@ static int fillonedir(void * __buf, cons
24845 buf->result = -EOVERFLOW;
24846 return -EOVERFLOW;
24847 }
24848+
24849+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
24850+ return 0;
24851+
24852 buf->result++;
24853 dirent = buf->dirent;
24854 if (!access_ok(VERIFY_WRITE, dirent,
24855@@ -116,6 +122,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned in
24856
24857 buf.result = 0;
24858 buf.dirent = dirent;
24859+ buf.file = file;
24860
24861 error = vfs_readdir(file, fillonedir, &buf);
24862 if (buf.result)
24863@@ -142,6 +149,7 @@ struct linux_dirent {
24864 struct getdents_callback {
24865 struct linux_dirent __user * current_dir;
24866 struct linux_dirent __user * previous;
24867+ struct file * file;
24868 int count;
24869 int error;
24870 };
24871@@ -162,6 +170,10 @@ static int filldir(void * __buf, const c
24872 buf->error = -EOVERFLOW;
24873 return -EOVERFLOW;
24874 }
24875+
24876+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
24877+ return 0;
24878+
24879 dirent = buf->previous;
24880 if (dirent) {
24881 if (__put_user(offset, &dirent->d_off))
24882@@ -209,6 +221,7 @@ SYSCALL_DEFINE3(getdents, unsigned int,
24883 buf.previous = NULL;
24884 buf.count = count;
24885 buf.error = 0;
24886+ buf.file = file;
24887
24888 error = vfs_readdir(file, filldir, &buf);
24889 if (error >= 0)
24890@@ -228,6 +241,7 @@ out:
24891 struct getdents_callback64 {
24892 struct linux_dirent64 __user * current_dir;
24893 struct linux_dirent64 __user * previous;
24894+ struct file *file;
24895 int count;
24896 int error;
24897 };
24898@@ -242,6 +256,10 @@ static int filldir64(void * __buf, const
24899 buf->error = -EINVAL; /* only used if we fail.. */
24900 if (reclen > buf->count)
24901 return -EINVAL;
24902+
24903+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
24904+ return 0;
24905+
24906 dirent = buf->previous;
24907 if (dirent) {
24908 if (__put_user(offset, &dirent->d_off))
24909@@ -289,6 +307,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int
24910
24911 buf.current_dir = dirent;
24912 buf.previous = NULL;
24913+ buf.file = file;
24914 buf.count = count;
24915 buf.error = 0;
24916
017d2877
AM
24917diff -urNp linux-2.6.30.4/fs/reiserfs/do_balan.c linux-2.6.30.4/fs/reiserfs/do_balan.c
24918--- linux-2.6.30.4/fs/reiserfs/do_balan.c 2009-07-24 17:47:51.000000000 -0400
24919+++ linux-2.6.30.4/fs/reiserfs/do_balan.c 2009-07-30 09:48:10.096509014 -0400
24920@@ -2059,7 +2059,7 @@ void do_balance(struct tree_balance *tb,
de855c5d
AM
24921 return;
24922 }
24923
24924- atomic_inc(&(fs_generation(tb->tb_sb)));
24925+ atomic_inc_unchecked(&(fs_generation(tb->tb_sb)));
24926 do_balance_starts(tb);
24927
24928 /* balance leaf returns 0 except if combining L R and S into
017d2877
AM
24929diff -urNp linux-2.6.30.4/fs/romfs/super.c linux-2.6.30.4/fs/romfs/super.c
24930--- linux-2.6.30.4/fs/romfs/super.c 2009-07-24 17:47:51.000000000 -0400
24931+++ linux-2.6.30.4/fs/romfs/super.c 2009-07-30 12:07:02.769214712 -0400
24932@@ -284,7 +284,7 @@ static const struct file_operations romf
24933 .readdir = romfs_readdir,
24934 };
24935
24936-static struct inode_operations romfs_dir_inode_operations = {
24937+static const struct inode_operations romfs_dir_inode_operations = {
24938 .lookup = romfs_lookup,
24939 };
24940
24941diff -urNp linux-2.6.30.4/fs/select.c linux-2.6.30.4/fs/select.c
24942--- linux-2.6.30.4/fs/select.c 2009-07-24 17:47:51.000000000 -0400
24943+++ linux-2.6.30.4/fs/select.c 2009-07-30 11:10:49.324080336 -0400
2380c486
JR
24944@@ -19,6 +19,7 @@
24945 #include <linux/module.h>
24946 #include <linux/slab.h>
24947 #include <linux/poll.h>
24948+#include <linux/security.h>
24949 #include <linux/personality.h> /* for STICKY_TIMEOUTS */
24950 #include <linux/file.h>
24951 #include <linux/fdtable.h>
24952@@ -781,6 +782,7 @@ int do_sys_poll(struct pollfd __user *uf
24953 struct poll_list *walk = head;
24954 unsigned long todo = nfds;
24955
24956+ gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
24957 if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
24958 return -EINVAL;
24959
017d2877
AM
24960diff -urNp linux-2.6.30.4/fs/seq_file.c linux-2.6.30.4/fs/seq_file.c
24961--- linux-2.6.30.4/fs/seq_file.c 2009-07-24 17:47:51.000000000 -0400
24962+++ linux-2.6.30.4/fs/seq_file.c 2009-07-30 11:10:49.336155631 -0400
de855c5d
AM
24963@@ -76,7 +76,8 @@ static int traverse(struct seq_file *m,
24964 return 0;
24965 }
24966 if (!m->buf) {
24967- m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
24968+ m->size = PAGE_SIZE;
24969+ m->buf = kmalloc(m->size, GFP_KERNEL);
24970 if (!m->buf)
24971 return -ENOMEM;
24972 }
24973@@ -116,7 +117,8 @@ static int traverse(struct seq_file *m,
24974 Eoverflow:
24975 m->op->stop(m, p);
24976 kfree(m->buf);
24977- m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
24978+ m->size <<= 1;
24979+ m->buf = kmalloc(m->size, GFP_KERNEL);
24980 return !m->buf ? -ENOMEM : -EAGAIN;
24981 }
24982
24983@@ -169,7 +171,8 @@ ssize_t seq_read(struct file *file, char
24984 m->version = file->f_version;
24985 /* grab buffer if we didn't have one */
24986 if (!m->buf) {
24987- m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
24988+ m->size = PAGE_SIZE;
24989+ m->buf = kmalloc(m->size, GFP_KERNEL);
24990 if (!m->buf)
24991 goto Enomem;
24992 }
24993@@ -210,7 +213,8 @@ ssize_t seq_read(struct file *file, char
24994 goto Fill;
24995 m->op->stop(m, p);
24996 kfree(m->buf);
24997- m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
24998+ m->size <<= 1;
24999+ m->buf = kmalloc(m->size, GFP_KERNEL);
25000 if (!m->buf)
25001 goto Enomem;
25002 m->count = 0;
017d2877
AM
25003diff -urNp linux-2.6.30.4/fs/smbfs/symlink.c linux-2.6.30.4/fs/smbfs/symlink.c
25004--- linux-2.6.30.4/fs/smbfs/symlink.c 2009-07-24 17:47:51.000000000 -0400
25005+++ linux-2.6.30.4/fs/smbfs/symlink.c 2009-07-30 09:48:10.098443569 -0400
2380c486
JR
25006@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
25007
25008 static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
25009 {
25010- char *s = nd_get_link(nd);
25011+ const char *s = nd_get_link(nd);
25012 if (!IS_ERR(s))
25013 __putname(s);
25014 }
017d2877
AM
25015diff -urNp linux-2.6.30.4/fs/squashfs/super.c linux-2.6.30.4/fs/squashfs/super.c
25016--- linux-2.6.30.4/fs/squashfs/super.c 2009-07-24 17:47:51.000000000 -0400
25017+++ linux-2.6.30.4/fs/squashfs/super.c 2009-07-30 09:48:10.098443569 -0400
25018@@ -43,7 +43,7 @@
25019 #include "squashfs.h"
25020
25021 static struct file_system_type squashfs_fs_type;
25022-static struct super_operations squashfs_super_ops;
25023+static const struct super_operations squashfs_super_ops;
25024
25025 static int supported_squashfs_filesystem(short major, short minor, short comp)
25026 {
25027@@ -439,7 +439,7 @@ static struct file_system_type squashfs_
25028 .fs_flags = FS_REQUIRES_DEV
25029 };
25030
25031-static struct super_operations squashfs_super_ops = {
25032+static const struct super_operations squashfs_super_ops = {
25033 .alloc_inode = squashfs_alloc_inode,
25034 .destroy_inode = squashfs_destroy_inode,
25035 .statfs = squashfs_statfs,
25036diff -urNp linux-2.6.30.4/fs/sysfs/bin.c linux-2.6.30.4/fs/sysfs/bin.c
25037--- linux-2.6.30.4/fs/sysfs/bin.c 2009-07-24 17:47:51.000000000 -0400
25038+++ linux-2.6.30.4/fs/sysfs/bin.c 2009-07-30 12:02:44.278047822 -0400
25039@@ -40,7 +40,7 @@ struct bin_buffer {
25040 struct mutex mutex;
25041 void *buffer;
25042 int mmapped;
25043- struct vm_operations_struct *vm_ops;
25044+ const struct vm_operations_struct *vm_ops;
25045 struct file *file;
25046 struct hlist_node list;
25047 };
25048@@ -330,7 +330,7 @@ static int bin_migrate(struct vm_area_st
25049 }
25050 #endif
25051
25052-static struct vm_operations_struct bin_vm_ops = {
25053+static const struct vm_operations_struct bin_vm_ops = {
25054 .open = bin_vma_open,
25055 .close = bin_vma_close,
25056 .fault = bin_fault,
25057diff -urNp linux-2.6.30.4/fs/sysfs/symlink.c linux-2.6.30.4/fs/sysfs/symlink.c
25058--- linux-2.6.30.4/fs/sysfs/symlink.c 2009-07-24 17:47:51.000000000 -0400
25059+++ linux-2.6.30.4/fs/sysfs/symlink.c 2009-07-30 09:48:10.098443569 -0400
2380c486
JR
25060@@ -200,7 +200,7 @@ static void *sysfs_follow_link(struct de
25061
25062 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
25063 {
25064- char *page = nd_get_link(nd);
25065+ const char *page = nd_get_link(nd);
25066 if (!IS_ERR(page))
25067 free_page((unsigned long)page);
25068 }
017d2877
AM
25069diff -urNp linux-2.6.30.4/fs/ubifs/file.c linux-2.6.30.4/fs/ubifs/file.c
25070--- linux-2.6.30.4/fs/ubifs/file.c 2009-07-24 17:47:51.000000000 -0400
25071+++ linux-2.6.30.4/fs/ubifs/file.c 2009-07-30 09:48:10.100960655 -0400
25072@@ -1536,7 +1536,7 @@ out_unlock:
25073 return err;
25074 }
25075
25076-static struct vm_operations_struct ubifs_file_vm_ops = {
25077+static const struct vm_operations_struct ubifs_file_vm_ops = {
25078 .fault = filemap_fault,
25079 .page_mkwrite = ubifs_vm_page_mkwrite,
25080 };
25081diff -urNp linux-2.6.30.4/fs/udf/balloc.c linux-2.6.30.4/fs/udf/balloc.c
25082--- linux-2.6.30.4/fs/udf/balloc.c 2009-07-24 17:47:51.000000000 -0400
25083+++ linux-2.6.30.4/fs/udf/balloc.c 2009-07-30 09:48:10.100960655 -0400
25084@@ -172,9 +172,7 @@ static void udf_bitmap_free_blocks(struc
2380c486
JR
25085
25086 mutex_lock(&sbi->s_alloc_mutex);
017d2877
AM
25087 partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
25088- if (bloc->logicalBlockNum < 0 ||
25089- (bloc->logicalBlockNum + count) >
25090- partmap->s_partition_len) {
25091+ if ((bloc->logicalBlockNum + count) > partmap->s_partition_len) {
2380c486 25092 udf_debug("%d < %d || %d + %d > %d\n",
017d2877
AM
25093 bloc->logicalBlockNum, 0, bloc->logicalBlockNum,
25094 count, partmap->s_partition_len);
25095@@ -238,7 +236,7 @@ static int udf_bitmap_prealloc_blocks(st
2380c486
JR
25096
25097 mutex_lock(&sbi->s_alloc_mutex);
25098 part_len = sbi->s_partmaps[partition].s_partition_len;
25099- if (first_block < 0 || first_block >= part_len)
25100+ if (first_block >= part_len)
25101 goto out;
25102
25103 if (first_block + block_count > part_len)
017d2877 25104@@ -297,7 +295,7 @@ static int udf_bitmap_new_block(struct s
2380c486
JR
25105 mutex_lock(&sbi->s_alloc_mutex);
25106
25107 repeat:
25108- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
25109+ if (goal >= sbi->s_partmaps[partition].s_partition_len)
25110 goal = 0;
25111
25112 nr_groups = bitmap->s_nr_groups;
017d2877 25113@@ -436,9 +434,7 @@ static void udf_table_free_blocks(struct
2380c486
JR
25114
25115 mutex_lock(&sbi->s_alloc_mutex);
017d2877
AM
25116 partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
25117- if (bloc->logicalBlockNum < 0 ||
25118- (bloc->logicalBlockNum + count) >
25119- partmap->s_partition_len) {
25120+ if ((bloc->logicalBlockNum + count) > partmap->s_partition_len) {
2380c486
JR
25121 udf_debug("%d < %d || %d + %d > %d\n",
25122 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
017d2877
AM
25123 partmap->s_partition_len);
25124@@ -666,8 +662,7 @@ static int udf_table_prealloc_blocks(str
2380c486
JR
25125 int8_t etype = -1;
25126 struct udf_inode_info *iinfo;
25127
25128- if (first_block < 0 ||
25129- first_block >= sbi->s_partmaps[partition].s_partition_len)
25130+ if (first_block >= sbi->s_partmaps[partition].s_partition_len)
25131 return 0;
25132
25133 iinfo = UDF_I(table);
017d2877 25134@@ -743,7 +738,7 @@ static int udf_table_new_block(struct su
2380c486
JR
25135 return newblock;
25136
25137 mutex_lock(&sbi->s_alloc_mutex);
25138- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
25139+ if (goal >= sbi->s_partmaps[partition].s_partition_len)
25140 goal = 0;
25141
25142 /* We search for the closest matching block to goal. If we find
017d2877
AM
25143diff -urNp linux-2.6.30.4/fs/ufs/inode.c linux-2.6.30.4/fs/ufs/inode.c
25144--- linux-2.6.30.4/fs/ufs/inode.c 2009-07-24 17:47:51.000000000 -0400
25145+++ linux-2.6.30.4/fs/ufs/inode.c 2009-07-30 09:48:10.101729491 -0400
2380c486
JR
25146@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
25147
25148
25149 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
25150- if (i_block < 0) {
25151- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
25152- } else if (i_block < direct_blocks) {
25153+ if (i_block < direct_blocks) {
25154 offsets[n++] = i_block;
25155 } else if ((i_block -= direct_blocks) < indirect_blocks) {
25156 offsets[n++] = UFS_IND_BLOCK;
25157@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
25158 lock_kernel();
25159
25160 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
25161- if (fragment < 0)
25162- goto abort_negative;
25163 if (fragment >
25164 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
25165 << uspi->s_fpbshift))
25166@@ -504,10 +500,6 @@ abort:
25167 unlock_kernel();
25168 return err;
25169
25170-abort_negative:
25171- ufs_warning(sb, "ufs_get_block", "block < 0");
25172- goto abort;
25173-
25174 abort_too_big:
25175 ufs_warning(sb, "ufs_get_block", "block > big");
25176 goto abort;
017d2877
AM
25177diff -urNp linux-2.6.30.4/fs/utimes.c linux-2.6.30.4/fs/utimes.c
25178--- linux-2.6.30.4/fs/utimes.c 2009-07-24 17:47:51.000000000 -0400
25179+++ linux-2.6.30.4/fs/utimes.c 2009-07-30 11:10:49.345424878 -0400
2380c486
JR
25180@@ -1,6 +1,7 @@
25181 #include <linux/compiler.h>
25182 #include <linux/file.h>
25183 #include <linux/fs.h>
25184+#include <linux/security.h>
25185 #include <linux/linkage.h>
25186 #include <linux/mount.h>
25187 #include <linux/namei.h>
25188@@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
25189 goto mnt_drop_write_and_out;
25190 }
25191 }
25192+
25193+ if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
25194+ error = -EACCES;
25195+ goto mnt_drop_write_and_out;
25196+ }
25197+
25198 mutex_lock(&inode->i_mutex);
25199 error = notify_change(path->dentry, &newattrs);
25200 mutex_unlock(&inode->i_mutex);
017d2877
AM
25201diff -urNp linux-2.6.30.4/fs/xfs/linux-2.6/xfs_file.c linux-2.6.30.4/fs/xfs/linux-2.6/xfs_file.c
25202--- linux-2.6.30.4/fs/xfs/linux-2.6/xfs_file.c 2009-07-24 17:47:51.000000000 -0400
25203+++ linux-2.6.30.4/fs/xfs/linux-2.6/xfs_file.c 2009-07-30 09:48:10.102932228 -0400
25204@@ -43,7 +43,7 @@
25205 #include <linux/dcache.h>
25206 #include <linux/smp_lock.h>
25207
25208-static struct vm_operations_struct xfs_file_vm_ops;
25209+static const struct vm_operations_struct xfs_file_vm_ops;
25210
25211 STATIC ssize_t
25212 xfs_file_aio_read(
25213@@ -272,7 +272,7 @@ const struct file_operations xfs_dir_fil
25214 .fsync = xfs_file_fsync,
25215 };
25216
25217-static struct vm_operations_struct xfs_file_vm_ops = {
25218+static const struct vm_operations_struct xfs_file_vm_ops = {
25219 .fault = filemap_fault,
25220 .page_mkwrite = xfs_vm_page_mkwrite,
25221 };
25222diff -urNp linux-2.6.30.4/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.30.4/fs/xfs/linux-2.6/xfs_iops.c
25223--- linux-2.6.30.4/fs/xfs/linux-2.6/xfs_iops.c 2009-07-24 17:47:51.000000000 -0400
25224+++ linux-2.6.30.4/fs/xfs/linux-2.6/xfs_iops.c 2009-07-30 09:48:10.102932228 -0400
25225@@ -482,7 +482,7 @@ xfs_vn_put_link(
2380c486
JR
25226 struct nameidata *nd,
25227 void *p)
25228 {
25229- char *s = nd_get_link(nd);
25230+ const char *s = nd_get_link(nd);
25231
25232 if (!IS_ERR(s))
25233 kfree(s);
017d2877
AM
25234diff -urNp linux-2.6.30.4/fs/xfs/linux-2.6/xfs_super.c linux-2.6.30.4/fs/xfs/linux-2.6/xfs_super.c
25235--- linux-2.6.30.4/fs/xfs/linux-2.6/xfs_super.c 2009-07-24 17:47:51.000000000 -0400
25236+++ linux-2.6.30.4/fs/xfs/linux-2.6/xfs_super.c 2009-07-30 13:03:07.229966859 -0400
25237@@ -68,7 +68,7 @@
25238 #include <linux/freezer.h>
25239 #include <linux/parser.h>
25240
25241-static struct super_operations xfs_super_operations;
25242+static const struct super_operations xfs_super_operations;
25243 static kmem_zone_t *xfs_ioend_zone;
25244 mempool_t *xfs_ioend_pool;
25245
25246@@ -1527,7 +1527,7 @@ xfs_fs_get_sb(
25247 mnt);
25248 }
25249
25250-static struct super_operations xfs_super_operations = {
25251+static const struct super_operations xfs_super_operations = {
25252 .alloc_inode = xfs_fs_alloc_inode,
25253 .destroy_inode = xfs_fs_destroy_inode,
25254 .write_inode = xfs_fs_write_inode,
25255diff -urNp linux-2.6.30.4/fs/xfs/xfs_bmap.c linux-2.6.30.4/fs/xfs/xfs_bmap.c
25256--- linux-2.6.30.4/fs/xfs/xfs_bmap.c 2009-07-24 17:47:51.000000000 -0400
25257+++ linux-2.6.30.4/fs/xfs/xfs_bmap.c 2009-07-30 09:48:10.103749934 -0400
2380c486
JR
25258@@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
25259 int nmap,
25260 int ret_nmap);
25261 #else
25262-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
25263+#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
25264 #endif /* DEBUG */
25265
25266 #if defined(XFS_RW_TRACE)
017d2877
AM
25267diff -urNp linux-2.6.30.4/grsecurity/gracl_alloc.c linux-2.6.30.4/grsecurity/gracl_alloc.c
25268--- linux-2.6.30.4/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
25269+++ linux-2.6.30.4/grsecurity/gracl_alloc.c 2009-07-30 11:10:49.345424878 -0400
de855c5d 25270@@ -0,0 +1,105 @@
2380c486
JR
25271+#include <linux/kernel.h>
25272+#include <linux/mm.h>
25273+#include <linux/slab.h>
25274+#include <linux/vmalloc.h>
25275+#include <linux/gracl.h>
25276+#include <linux/grsecurity.h>
25277+
25278+static unsigned long alloc_stack_next = 1;
25279+static unsigned long alloc_stack_size = 1;
25280+static void **alloc_stack;
25281+
25282+static __inline__ int
25283+alloc_pop(void)
25284+{
25285+ if (alloc_stack_next == 1)
25286+ return 0;
25287+
25288+ kfree(alloc_stack[alloc_stack_next - 2]);
25289+
25290+ alloc_stack_next--;
25291+
25292+ return 1;
25293+}
25294+
de855c5d 25295+static __inline__ int
2380c486
JR
25296+alloc_push(void *buf)
25297+{
25298+ if (alloc_stack_next >= alloc_stack_size)
de855c5d 25299+ return 1;
2380c486
JR
25300+
25301+ alloc_stack[alloc_stack_next - 1] = buf;
25302+
25303+ alloc_stack_next++;
25304+
de855c5d 25305+ return 0;
2380c486
JR
25306+}
25307+
25308+void *
25309+acl_alloc(unsigned long len)
25310+{
de855c5d 25311+ void *ret = NULL;
2380c486 25312+
de855c5d
AM
25313+ if (!len || len > PAGE_SIZE)
25314+ goto out;
2380c486
JR
25315+
25316+ ret = kmalloc(len, GFP_KERNEL);
25317+
de855c5d
AM
25318+ if (ret) {
25319+ if (alloc_push(ret)) {
25320+ kfree(ret);
25321+ ret = NULL;
25322+ }
25323+ }
2380c486 25324+
de855c5d 25325+out:
2380c486
JR
25326+ return ret;
25327+}
25328+
de855c5d
AM
25329+void *
25330+acl_alloc_num(unsigned long num, unsigned long len)
25331+{
25332+ if (!len || (num > (PAGE_SIZE / len)))
25333+ return NULL;
25334+
25335+ return acl_alloc(num * len);
25336+}
25337+
2380c486
JR
25338+void
25339+acl_free_all(void)
25340+{
25341+ if (gr_acl_is_enabled() || !alloc_stack)
25342+ return;
25343+
25344+ while (alloc_pop()) ;
25345+
25346+ if (alloc_stack) {
25347+ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
25348+ kfree(alloc_stack);
25349+ else
25350+ vfree(alloc_stack);
25351+ }
25352+
25353+ alloc_stack = NULL;
25354+ alloc_stack_size = 1;
25355+ alloc_stack_next = 1;
25356+
25357+ return;
25358+}
25359+
25360+int
25361+acl_alloc_stack_init(unsigned long size)
25362+{
25363+ if ((size * sizeof (void *)) <= PAGE_SIZE)
25364+ alloc_stack =
25365+ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
25366+ else
25367+ alloc_stack = (void **) vmalloc(size * sizeof (void *));
25368+
25369+ alloc_stack_size = size;
25370+
25371+ if (!alloc_stack)
25372+ return 0;
25373+ else
25374+ return 1;
25375+}
017d2877
AM
25376diff -urNp linux-2.6.30.4/grsecurity/gracl.c linux-2.6.30.4/grsecurity/gracl.c
25377--- linux-2.6.30.4/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
25378+++ linux-2.6.30.4/grsecurity/gracl.c 2009-07-30 11:10:49.345424878 -0400
25379@@ -0,0 +1,3892 @@
2380c486
JR
25380+#include <linux/kernel.h>
25381+#include <linux/module.h>
25382+#include <linux/sched.h>
25383+#include <linux/mm.h>
25384+#include <linux/file.h>
25385+#include <linux/fs.h>
25386+#include <linux/namei.h>
25387+#include <linux/mount.h>
25388+#include <linux/tty.h>
25389+#include <linux/proc_fs.h>
25390+#include <linux/smp_lock.h>
25391+#include <linux/slab.h>
25392+#include <linux/vmalloc.h>
25393+#include <linux/types.h>
25394+#include <linux/sysctl.h>
25395+#include <linux/netdevice.h>
25396+#include <linux/ptrace.h>
25397+#include <linux/gracl.h>
25398+#include <linux/gralloc.h>
25399+#include <linux/grsecurity.h>
25400+#include <linux/grinternal.h>
25401+#include <linux/pid_namespace.h>
25402+#include <linux/fdtable.h>
25403+#include <linux/percpu.h>
25404+
25405+#include <asm/uaccess.h>
25406+#include <asm/errno.h>
25407+#include <asm/mman.h>
25408+
25409+static struct acl_role_db acl_role_set;
25410+static struct name_db name_set;
25411+static struct inodev_db inodev_set;
25412+
25413+/* for keeping track of userspace pointers used for subjects, so we
25414+ can share references in the kernel as well
25415+*/
25416+
25417+static struct dentry *real_root;
25418+static struct vfsmount *real_root_mnt;
25419+
25420+static struct acl_subj_map_db subj_map_set;
25421+
25422+static struct acl_role_label *default_role;
25423+
25424+static u16 acl_sp_role_value;
25425+
25426+extern char *gr_shared_page[4];
25427+static DECLARE_MUTEX(gr_dev_sem);
25428+DEFINE_RWLOCK(gr_inode_lock);
25429+
25430+struct gr_arg *gr_usermode;
25431+
017d2877
AM
25432+#ifdef CONFIG_PAX_KERNEXEC
25433+static unsigned int gr_status __read_only = GR_STATUS_INIT;
25434+#else
2380c486 25435+static unsigned int gr_status = GR_STATUS_INIT;
017d2877 25436+#endif
2380c486
JR
25437+
25438+extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
25439+extern void gr_clear_learn_entries(void);
25440+
25441+#ifdef CONFIG_GRKERNSEC_RESLOG
25442+extern void gr_log_resource(const struct task_struct *task,
25443+ const int res, const unsigned long wanted, const int gt);
25444+#endif
25445+
25446+unsigned char *gr_system_salt;
25447+unsigned char *gr_system_sum;
25448+
25449+static struct sprole_pw **acl_special_roles = NULL;
25450+static __u16 num_sprole_pws = 0;
25451+
25452+static struct acl_role_label *kernel_role = NULL;
25453+
25454+static unsigned int gr_auth_attempts = 0;
25455+static unsigned long gr_auth_expires = 0UL;
25456+
25457+extern struct vfsmount *sock_mnt;
25458+extern struct vfsmount *pipe_mnt;
25459+extern struct vfsmount *shm_mnt;
25460+static struct acl_object_label *fakefs_obj;
25461+
25462+extern int gr_init_uidset(void);
25463+extern void gr_free_uidset(void);
25464+extern void gr_remove_uid(uid_t uid);
25465+extern int gr_find_uid(uid_t uid);
25466+
25467+__inline__ int
25468+gr_acl_is_enabled(void)
25469+{
25470+ return (gr_status & GR_READY);
25471+}
25472+
25473+char gr_roletype_to_char(void)
25474+{
25475+ switch (current->role->roletype &
25476+ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
25477+ GR_ROLE_SPECIAL)) {
25478+ case GR_ROLE_DEFAULT:
25479+ return 'D';
25480+ case GR_ROLE_USER:
25481+ return 'U';
25482+ case GR_ROLE_GROUP:
25483+ return 'G';
25484+ case GR_ROLE_SPECIAL:
25485+ return 'S';
25486+ }
25487+
25488+ return 'X';
25489+}
25490+
25491+__inline__ int
25492+gr_acl_tpe_check(void)
25493+{
25494+ if (unlikely(!(gr_status & GR_READY)))
25495+ return 0;
25496+ if (current->role->roletype & GR_ROLE_TPE)
25497+ return 1;
25498+ else
25499+ return 0;
25500+}
25501+
25502+int
25503+gr_handle_rawio(const struct inode *inode)
25504+{
25505+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25506+ if (inode && S_ISBLK(inode->i_mode) &&
25507+ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
25508+ !capable(CAP_SYS_RAWIO))
25509+ return 1;
25510+#endif
25511+ return 0;
25512+}
25513+
25514+static int
25515+gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
25516+{
25517+ int i;
25518+ unsigned long *l1;
25519+ unsigned long *l2;
25520+ unsigned char *c1;
25521+ unsigned char *c2;
25522+ int num_longs;
25523+
25524+ if (likely(lena != lenb))
25525+ return 0;
25526+
25527+ l1 = (unsigned long *)a;
25528+ l2 = (unsigned long *)b;
25529+
25530+ num_longs = lena / sizeof(unsigned long);
25531+
25532+ for (i = num_longs; i--; l1++, l2++) {
25533+ if (unlikely(*l1 != *l2))
25534+ return 0;
25535+ }
25536+
25537+ c1 = (unsigned char *) l1;
25538+ c2 = (unsigned char *) l2;
25539+
25540+ i = lena - (num_longs * sizeof(unsigned long));
25541+
25542+ for (; i--; c1++, c2++) {
25543+ if (unlikely(*c1 != *c2))
25544+ return 0;
25545+ }
25546+
25547+ return 1;
25548+}
25549+
25550+static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
25551+ struct dentry *root, struct vfsmount *rootmnt,
25552+ char *buffer, int buflen)
25553+{
25554+ char * end = buffer+buflen;
25555+ char * retval;
25556+ int namelen;
25557+
25558+ *--end = '\0';
25559+ buflen--;
25560+
25561+ if (buflen < 1)
25562+ goto Elong;
25563+ /* Get '/' right */
25564+ retval = end-1;
25565+ *retval = '/';
25566+
25567+ for (;;) {
25568+ struct dentry * parent;
25569+
25570+ if (dentry == root && vfsmnt == rootmnt)
25571+ break;
25572+ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
25573+ /* Global root? */
25574+ spin_lock(&vfsmount_lock);
25575+ if (vfsmnt->mnt_parent == vfsmnt) {
25576+ spin_unlock(&vfsmount_lock);
25577+ goto global_root;
25578+ }
25579+ dentry = vfsmnt->mnt_mountpoint;
25580+ vfsmnt = vfsmnt->mnt_parent;
25581+ spin_unlock(&vfsmount_lock);
25582+ continue;
25583+ }
25584+ parent = dentry->d_parent;
25585+ prefetch(parent);
25586+ namelen = dentry->d_name.len;
25587+ buflen -= namelen + 1;
25588+ if (buflen < 0)
25589+ goto Elong;
25590+ end -= namelen;
25591+ memcpy(end, dentry->d_name.name, namelen);
25592+ *--end = '/';
25593+ retval = end;
25594+ dentry = parent;
25595+ }
25596+
25597+ return retval;
25598+
25599+global_root:
25600+ namelen = dentry->d_name.len;
25601+ buflen -= namelen;
25602+ if (buflen < 0)
25603+ goto Elong;
25604+ retval -= namelen-1; /* hit the slash */
25605+ memcpy(retval, dentry->d_name.name, namelen);
25606+ return retval;
25607+Elong:
25608+ return ERR_PTR(-ENAMETOOLONG);
25609+}
25610+
25611+static char *
25612+gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
25613+ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
25614+{
25615+ char *retval;
25616+
25617+ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
25618+ if (unlikely(IS_ERR(retval)))
25619+ retval = strcpy(buf, "<path too long>");
25620+ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
25621+ retval[1] = '\0';
25622+
25623+ return retval;
25624+}
25625+
25626+static char *
25627+__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
25628+ char *buf, int buflen)
25629+{
25630+ char *res;
25631+
25632+ /* we can use real_root, real_root_mnt, because this is only called
25633+ by the RBAC system */
25634+ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
25635+
25636+ return res;
25637+}
25638+
25639+static char *
25640+d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
25641+ char *buf, int buflen)
25642+{
25643+ char *res;
25644+ struct dentry *root;
25645+ struct vfsmount *rootmnt;
25646+ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
25647+
25648+ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
25649+ read_lock(&reaper->fs->lock);
25650+ root = dget(reaper->fs->root.dentry);
25651+ rootmnt = mntget(reaper->fs->root.mnt);
25652+ read_unlock(&reaper->fs->lock);
25653+
25654+ spin_lock(&dcache_lock);
25655+ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
25656+ spin_unlock(&dcache_lock);
25657+
25658+ dput(root);
25659+ mntput(rootmnt);
25660+ return res;
25661+}
25662+
25663+static char *
25664+gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
25665+{
25666+ char *ret;
25667+ spin_lock(&dcache_lock);
25668+ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
25669+ PAGE_SIZE);
25670+ spin_unlock(&dcache_lock);
25671+ return ret;
25672+}
25673+
25674+char *
25675+gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
25676+{
25677+ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
25678+ PAGE_SIZE);
25679+}
25680+
25681+char *
25682+gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
25683+{
25684+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
25685+ PAGE_SIZE);
25686+}
25687+
25688+char *
25689+gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
25690+{
25691+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
25692+ PAGE_SIZE);
25693+}
25694+
25695+char *
25696+gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
25697+{
25698+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
25699+ PAGE_SIZE);
25700+}
25701+
25702+char *
25703+gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
25704+{
25705+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
25706+ PAGE_SIZE);
25707+}
25708+
25709+__inline__ __u32
25710+to_gr_audit(const __u32 reqmode)
25711+{
25712+ /* masks off auditable permission flags, then shifts them to create
25713+ auditing flags, and adds the special case of append auditing if
25714+ we're requesting write */
25715+ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
25716+}
25717+
25718+struct acl_subject_label *
25719+lookup_subject_map(const struct acl_subject_label *userp)
25720+{
25721+ unsigned int index = shash(userp, subj_map_set.s_size);
25722+ struct subject_map *match;
25723+
25724+ match = subj_map_set.s_hash[index];
25725+
25726+ while (match && match->user != userp)
25727+ match = match->next;
25728+
25729+ if (match != NULL)
25730+ return match->kernel;
25731+ else
25732+ return NULL;
25733+}
25734+
25735+static void
25736+insert_subj_map_entry(struct subject_map *subjmap)
25737+{
25738+ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
25739+ struct subject_map **curr;
25740+
25741+ subjmap->prev = NULL;
25742+
25743+ curr = &subj_map_set.s_hash[index];
25744+ if (*curr != NULL)
25745+ (*curr)->prev = subjmap;
25746+
25747+ subjmap->next = *curr;
25748+ *curr = subjmap;
25749+
25750+ return;
25751+}
25752+
25753+static struct acl_role_label *
25754+lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
25755+ const gid_t gid)
25756+{
25757+ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
25758+ struct acl_role_label *match;
25759+ struct role_allowed_ip *ipp;
25760+ unsigned int x;
25761+
25762+ match = acl_role_set.r_hash[index];
25763+
25764+ while (match) {
25765+ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
25766+ for (x = 0; x < match->domain_child_num; x++) {
25767+ if (match->domain_children[x] == uid)
25768+ goto found;
25769+ }
25770+ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
25771+ break;
25772+ match = match->next;
25773+ }
25774+found:
25775+ if (match == NULL) {
25776+ try_group:
25777+ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
25778+ match = acl_role_set.r_hash[index];
25779+
25780+ while (match) {
25781+ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
25782+ for (x = 0; x < match->domain_child_num; x++) {
25783+ if (match->domain_children[x] == gid)
25784+ goto found2;
25785+ }
25786+ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
25787+ break;
25788+ match = match->next;
25789+ }
25790+found2:
25791+ if (match == NULL)
25792+ match = default_role;
25793+ if (match->allowed_ips == NULL)
25794+ return match;
25795+ else {
25796+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
25797+ if (likely
25798+ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
25799+ (ntohl(ipp->addr) & ipp->netmask)))
25800+ return match;
25801+ }
25802+ match = default_role;
25803+ }
25804+ } else if (match->allowed_ips == NULL) {
25805+ return match;
25806+ } else {
25807+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
25808+ if (likely
25809+ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
25810+ (ntohl(ipp->addr) & ipp->netmask)))
25811+ return match;
25812+ }
25813+ goto try_group;
25814+ }
25815+
25816+ return match;
25817+}
25818+
25819+struct acl_subject_label *
25820+lookup_acl_subj_label(const ino_t ino, const dev_t dev,
25821+ const struct acl_role_label *role)
25822+{
25823+ unsigned int index = fhash(ino, dev, role->subj_hash_size);
25824+ struct acl_subject_label *match;
25825+
25826+ match = role->subj_hash[index];
25827+
25828+ while (match && (match->inode != ino || match->device != dev ||
25829+ (match->mode & GR_DELETED))) {
25830+ match = match->next;
25831+ }
25832+
25833+ if (match && !(match->mode & GR_DELETED))
25834+ return match;
25835+ else
25836+ return NULL;
25837+}
25838+
de855c5d
AM
25839+struct acl_subject_label *
25840+lookup_acl_subj_label_deleted(const ino_t ino, const dev_t dev,
25841+ const struct acl_role_label *role)
25842+{
25843+ unsigned int index = fhash(ino, dev, role->subj_hash_size);
25844+ struct acl_subject_label *match;
25845+
25846+ match = role->subj_hash[index];
25847+
25848+ while (match && (match->inode != ino || match->device != dev ||
25849+ !(match->mode & GR_DELETED))) {
25850+ match = match->next;
25851+ }
25852+
25853+ if (match && (match->mode & GR_DELETED))
25854+ return match;
25855+ else
25856+ return NULL;
25857+}
25858+
2380c486
JR
25859+static struct acl_object_label *
25860+lookup_acl_obj_label(const ino_t ino, const dev_t dev,
25861+ const struct acl_subject_label *subj)
25862+{
25863+ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
25864+ struct acl_object_label *match;
25865+
25866+ match = subj->obj_hash[index];
25867+
25868+ while (match && (match->inode != ino || match->device != dev ||
25869+ (match->mode & GR_DELETED))) {
25870+ match = match->next;
25871+ }
25872+
25873+ if (match && !(match->mode & GR_DELETED))
25874+ return match;
25875+ else
25876+ return NULL;
25877+}
25878+
25879+static struct acl_object_label *
25880+lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
25881+ const struct acl_subject_label *subj)
25882+{
25883+ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
25884+ struct acl_object_label *match;
25885+
25886+ match = subj->obj_hash[index];
25887+
25888+ while (match && (match->inode != ino || match->device != dev ||
25889+ !(match->mode & GR_DELETED))) {
25890+ match = match->next;
25891+ }
25892+
25893+ if (match && (match->mode & GR_DELETED))
25894+ return match;
25895+
25896+ match = subj->obj_hash[index];
25897+
25898+ while (match && (match->inode != ino || match->device != dev ||
25899+ (match->mode & GR_DELETED))) {
25900+ match = match->next;
25901+ }
25902+
25903+ if (match && !(match->mode & GR_DELETED))
25904+ return match;
25905+ else
25906+ return NULL;
25907+}
25908+
25909+static struct name_entry *
25910+lookup_name_entry(const char *name)
25911+{
25912+ unsigned int len = strlen(name);
25913+ unsigned int key = full_name_hash(name, len);
25914+ unsigned int index = key % name_set.n_size;
25915+ struct name_entry *match;
25916+
25917+ match = name_set.n_hash[index];
25918+
25919+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
25920+ match = match->next;
25921+
25922+ return match;
25923+}
25924+
25925+static struct name_entry *
25926+lookup_name_entry_create(const char *name)
25927+{
25928+ unsigned int len = strlen(name);
25929+ unsigned int key = full_name_hash(name, len);
25930+ unsigned int index = key % name_set.n_size;
25931+ struct name_entry *match;
25932+
25933+ match = name_set.n_hash[index];
25934+
25935+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
25936+ !match->deleted))
25937+ match = match->next;
25938+
25939+ if (match && match->deleted)
25940+ return match;
25941+
25942+ match = name_set.n_hash[index];
25943+
25944+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
25945+ match->deleted))
25946+ match = match->next;
25947+
25948+ if (match && !match->deleted)
25949+ return match;
25950+ else
25951+ return NULL;
25952+}
25953+
25954+static struct inodev_entry *
25955+lookup_inodev_entry(const ino_t ino, const dev_t dev)
25956+{
25957+ unsigned int index = fhash(ino, dev, inodev_set.i_size);
25958+ struct inodev_entry *match;
25959+
25960+ match = inodev_set.i_hash[index];
25961+
25962+ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
25963+ match = match->next;
25964+
25965+ return match;
25966+}
25967+
25968+static void
25969+insert_inodev_entry(struct inodev_entry *entry)
25970+{
25971+ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
25972+ inodev_set.i_size);
25973+ struct inodev_entry **curr;
25974+
25975+ entry->prev = NULL;
25976+
25977+ curr = &inodev_set.i_hash[index];
25978+ if (*curr != NULL)
25979+ (*curr)->prev = entry;
25980+
25981+ entry->next = *curr;
25982+ *curr = entry;
25983+
25984+ return;
25985+}
25986+
25987+static void
25988+__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
25989+{
25990+ unsigned int index =
25991+ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
25992+ struct acl_role_label **curr;
25993+
25994+ role->prev = NULL;
25995+
25996+ curr = &acl_role_set.r_hash[index];
25997+ if (*curr != NULL)
25998+ (*curr)->prev = role;
25999+
26000+ role->next = *curr;
26001+ *curr = role;
26002+
26003+ return;
26004+}
26005+
26006+static void
26007+insert_acl_role_label(struct acl_role_label *role)
26008+{
26009+ int i;
26010+
26011+ if (role->roletype & GR_ROLE_DOMAIN) {
26012+ for (i = 0; i < role->domain_child_num; i++)
26013+ __insert_acl_role_label(role, role->domain_children[i]);
26014+ } else
26015+ __insert_acl_role_label(role, role->uidgid);
26016+}
26017+
26018+static int
26019+insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
26020+{
26021+ struct name_entry **curr, *nentry;
26022+ struct inodev_entry *ientry;
26023+ unsigned int len = strlen(name);
26024+ unsigned int key = full_name_hash(name, len);
26025+ unsigned int index = key % name_set.n_size;
26026+
26027+ curr = &name_set.n_hash[index];
26028+
26029+ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
26030+ curr = &((*curr)->next);
26031+
26032+ if (*curr != NULL)
26033+ return 1;
26034+
26035+ nentry = acl_alloc(sizeof (struct name_entry));
26036+ if (nentry == NULL)
26037+ return 0;
26038+ ientry = acl_alloc(sizeof (struct inodev_entry));
26039+ if (ientry == NULL)
26040+ return 0;
26041+ ientry->nentry = nentry;
26042+
26043+ nentry->key = key;
26044+ nentry->name = name;
26045+ nentry->inode = inode;
26046+ nentry->device = device;
26047+ nentry->len = len;
26048+ nentry->deleted = deleted;
26049+
26050+ nentry->prev = NULL;
26051+ curr = &name_set.n_hash[index];
26052+ if (*curr != NULL)
26053+ (*curr)->prev = nentry;
26054+ nentry->next = *curr;
26055+ *curr = nentry;
26056+
26057+ /* insert us into the table searchable by inode/dev */
26058+ insert_inodev_entry(ientry);
26059+
26060+ return 1;
26061+}
26062+
26063+static void
26064+insert_acl_obj_label(struct acl_object_label *obj,
26065+ struct acl_subject_label *subj)
26066+{
26067+ unsigned int index =
26068+ fhash(obj->inode, obj->device, subj->obj_hash_size);
26069+ struct acl_object_label **curr;
26070+
26071+
26072+ obj->prev = NULL;
26073+
26074+ curr = &subj->obj_hash[index];
26075+ if (*curr != NULL)
26076+ (*curr)->prev = obj;
26077+
26078+ obj->next = *curr;
26079+ *curr = obj;
26080+
26081+ return;
26082+}
26083+
26084+static void
26085+insert_acl_subj_label(struct acl_subject_label *obj,
26086+ struct acl_role_label *role)
26087+{
26088+ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
26089+ struct acl_subject_label **curr;
26090+
26091+ obj->prev = NULL;
26092+
26093+ curr = &role->subj_hash[index];
26094+ if (*curr != NULL)
26095+ (*curr)->prev = obj;
26096+
26097+ obj->next = *curr;
26098+ *curr = obj;
26099+
26100+ return;
26101+}
26102+
26103+/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
26104+
26105+static void *
26106+create_table(__u32 * len, int elementsize)
26107+{
26108+ unsigned int table_sizes[] = {
26109+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
26110+ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
de855c5d 26111+ 4194301, 8388593, 16777213, 33554393, 67108859
2380c486
JR
26112+ };
26113+ void *newtable = NULL;
26114+ unsigned int pwr = 0;
26115+
26116+ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
26117+ table_sizes[pwr] <= *len)
26118+ pwr++;
26119+
de855c5d 26120+ if (table_sizes[pwr] <= *len || (table_sizes[pwr] > ULONG_MAX / elementsize))
2380c486
JR
26121+ return newtable;
26122+
26123+ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
26124+ newtable =
26125+ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
26126+ else
26127+ newtable = vmalloc(table_sizes[pwr] * elementsize);
26128+
26129+ *len = table_sizes[pwr];
26130+
26131+ return newtable;
26132+}
26133+
26134+static int
26135+init_variables(const struct gr_arg *arg)
26136+{
26137+ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
26138+ unsigned int stacksize;
26139+
26140+ subj_map_set.s_size = arg->role_db.num_subjects;
26141+ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
26142+ name_set.n_size = arg->role_db.num_objects;
26143+ inodev_set.i_size = arg->role_db.num_objects;
26144+
26145+ if (!subj_map_set.s_size || !acl_role_set.r_size ||
26146+ !name_set.n_size || !inodev_set.i_size)
26147+ return 1;
26148+
26149+ if (!gr_init_uidset())
26150+ return 1;
26151+
26152+ /* set up the stack that holds allocation info */
26153+
26154+ stacksize = arg->role_db.num_pointers + 5;
26155+
26156+ if (!acl_alloc_stack_init(stacksize))
26157+ return 1;
26158+
26159+ /* grab reference for the real root dentry and vfsmount */
26160+ read_lock(&reaper->fs->lock);
26161+ real_root_mnt = mntget(reaper->fs->root.mnt);
26162+ real_root = dget(reaper->fs->root.dentry);
26163+ read_unlock(&reaper->fs->lock);
26164+
26165+ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
26166+ if (fakefs_obj == NULL)
26167+ return 1;
26168+ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
26169+
26170+ subj_map_set.s_hash =
26171+ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
26172+ acl_role_set.r_hash =
26173+ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
26174+ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
26175+ inodev_set.i_hash =
26176+ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
26177+
26178+ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
26179+ !name_set.n_hash || !inodev_set.i_hash)
26180+ return 1;
26181+
26182+ memset(subj_map_set.s_hash, 0,
26183+ sizeof(struct subject_map *) * subj_map_set.s_size);
26184+ memset(acl_role_set.r_hash, 0,
26185+ sizeof (struct acl_role_label *) * acl_role_set.r_size);
26186+ memset(name_set.n_hash, 0,
26187+ sizeof (struct name_entry *) * name_set.n_size);
26188+ memset(inodev_set.i_hash, 0,
26189+ sizeof (struct inodev_entry *) * inodev_set.i_size);
26190+
26191+ return 0;
26192+}
26193+
26194+/* free information not needed after startup
26195+ currently contains user->kernel pointer mappings for subjects
26196+*/
26197+
26198+static void
26199+free_init_variables(void)
26200+{
26201+ __u32 i;
26202+
26203+ if (subj_map_set.s_hash) {
26204+ for (i = 0; i < subj_map_set.s_size; i++) {
26205+ if (subj_map_set.s_hash[i]) {
26206+ kfree(subj_map_set.s_hash[i]);
26207+ subj_map_set.s_hash[i] = NULL;
26208+ }
26209+ }
26210+
26211+ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
26212+ PAGE_SIZE)
26213+ kfree(subj_map_set.s_hash);
26214+ else
26215+ vfree(subj_map_set.s_hash);
26216+ }
26217+
26218+ return;
26219+}
26220+
26221+static void
26222+free_variables(void)
26223+{
26224+ struct acl_subject_label *s;
26225+ struct acl_role_label *r;
26226+ struct task_struct *task, *task2;
26227+ unsigned int i, x;
26228+
26229+ gr_clear_learn_entries();
26230+
26231+ read_lock(&tasklist_lock);
26232+ do_each_thread(task2, task) {
26233+ task->acl_sp_role = 0;
26234+ task->acl_role_id = 0;
26235+ task->acl = NULL;
26236+ task->role = NULL;
26237+ } while_each_thread(task2, task);
26238+ read_unlock(&tasklist_lock);
26239+
26240+ /* release the reference to the real root dentry and vfsmount */
26241+ if (real_root)
26242+ dput(real_root);
26243+ real_root = NULL;
26244+ if (real_root_mnt)
26245+ mntput(real_root_mnt);
26246+ real_root_mnt = NULL;
26247+
26248+ /* free all object hash tables */
26249+
26250+ FOR_EACH_ROLE_START(r, i)
26251+ if (r->subj_hash == NULL)
26252+ break;
26253+ FOR_EACH_SUBJECT_START(r, s, x)
26254+ if (s->obj_hash == NULL)
26255+ break;
26256+ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
26257+ kfree(s->obj_hash);
26258+ else
26259+ vfree(s->obj_hash);
26260+ FOR_EACH_SUBJECT_END(s, x)
26261+ FOR_EACH_NESTED_SUBJECT_START(r, s)
26262+ if (s->obj_hash == NULL)
26263+ break;
26264+ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
26265+ kfree(s->obj_hash);
26266+ else
26267+ vfree(s->obj_hash);
26268+ FOR_EACH_NESTED_SUBJECT_END(s)
26269+ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
26270+ kfree(r->subj_hash);
26271+ else
26272+ vfree(r->subj_hash);
26273+ r->subj_hash = NULL;
26274+ FOR_EACH_ROLE_END(r,i)
26275+
26276+ acl_free_all();
26277+
26278+ if (acl_role_set.r_hash) {
26279+ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
26280+ PAGE_SIZE)
26281+ kfree(acl_role_set.r_hash);
26282+ else
26283+ vfree(acl_role_set.r_hash);
26284+ }
26285+ if (name_set.n_hash) {
26286+ if ((name_set.n_size * sizeof (struct name_entry *)) <=
26287+ PAGE_SIZE)
26288+ kfree(name_set.n_hash);
26289+ else
26290+ vfree(name_set.n_hash);
26291+ }
26292+
26293+ if (inodev_set.i_hash) {
26294+ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
26295+ PAGE_SIZE)
26296+ kfree(inodev_set.i_hash);
26297+ else
26298+ vfree(inodev_set.i_hash);
26299+ }
26300+
26301+ gr_free_uidset();
26302+
26303+ memset(&name_set, 0, sizeof (struct name_db));
26304+ memset(&inodev_set, 0, sizeof (struct inodev_db));
26305+ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
26306+ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
26307+
26308+ default_role = NULL;
26309+
26310+ return;
26311+}
26312+
26313+static __u32
26314+count_user_objs(struct acl_object_label *userp)
26315+{
26316+ struct acl_object_label o_tmp;
26317+ __u32 num = 0;
26318+
26319+ while (userp) {
26320+ if (copy_from_user(&o_tmp, userp,
26321+ sizeof (struct acl_object_label)))
26322+ break;
26323+
26324+ userp = o_tmp.prev;
26325+ num++;
26326+ }
26327+
26328+ return num;
26329+}
26330+
26331+static struct acl_subject_label *
26332+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
26333+
26334+static int
26335+copy_user_glob(struct acl_object_label *obj)
26336+{
26337+ struct acl_object_label *g_tmp, **guser;
26338+ unsigned int len;
26339+ char *tmp;
26340+
26341+ if (obj->globbed == NULL)
26342+ return 0;
26343+
26344+ guser = &obj->globbed;
26345+ while (*guser) {
26346+ g_tmp = (struct acl_object_label *)
26347+ acl_alloc(sizeof (struct acl_object_label));
26348+ if (g_tmp == NULL)
26349+ return -ENOMEM;
26350+
26351+ if (copy_from_user(g_tmp, *guser,
26352+ sizeof (struct acl_object_label)))
26353+ return -EFAULT;
26354+
26355+ len = strnlen_user(g_tmp->filename, PATH_MAX);
26356+
26357+ if (!len || len >= PATH_MAX)
26358+ return -EINVAL;
26359+
26360+ if ((tmp = (char *) acl_alloc(len)) == NULL)
26361+ return -ENOMEM;
26362+
26363+ if (copy_from_user(tmp, g_tmp->filename, len))
26364+ return -EFAULT;
26365+
26366+ g_tmp->filename = tmp;
26367+
26368+ *guser = g_tmp;
26369+ guser = &(g_tmp->next);
26370+ }
26371+
26372+ return 0;
26373+}
26374+
26375+static int
26376+copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
26377+ struct acl_role_label *role)
26378+{
26379+ struct acl_object_label *o_tmp;
26380+ unsigned int len;
26381+ int ret;
26382+ char *tmp;
26383+
26384+ while (userp) {
26385+ if ((o_tmp = (struct acl_object_label *)
26386+ acl_alloc(sizeof (struct acl_object_label))) == NULL)
26387+ return -ENOMEM;
26388+
26389+ if (copy_from_user(o_tmp, userp,
26390+ sizeof (struct acl_object_label)))
26391+ return -EFAULT;
26392+
26393+ userp = o_tmp->prev;
26394+
26395+ len = strnlen_user(o_tmp->filename, PATH_MAX);
26396+
26397+ if (!len || len >= PATH_MAX)
26398+ return -EINVAL;
26399+
26400+ if ((tmp = (char *) acl_alloc(len)) == NULL)
26401+ return -ENOMEM;
26402+
26403+ if (copy_from_user(tmp, o_tmp->filename, len))
26404+ return -EFAULT;
26405+
26406+ o_tmp->filename = tmp;
26407+
26408+ insert_acl_obj_label(o_tmp, subj);
26409+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
26410+ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
26411+ return -ENOMEM;
26412+
26413+ ret = copy_user_glob(o_tmp);
26414+ if (ret)
26415+ return ret;
26416+
26417+ if (o_tmp->nested) {
26418+ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
26419+ if (IS_ERR(o_tmp->nested))
26420+ return PTR_ERR(o_tmp->nested);
26421+
26422+ /* insert into nested subject list */
26423+ o_tmp->nested->next = role->hash->first;
26424+ role->hash->first = o_tmp->nested;
26425+ }
26426+ }
26427+
26428+ return 0;
26429+}
26430+
26431+static __u32
26432+count_user_subjs(struct acl_subject_label *userp)
26433+{
26434+ struct acl_subject_label s_tmp;
26435+ __u32 num = 0;
26436+
26437+ while (userp) {
26438+ if (copy_from_user(&s_tmp, userp,
26439+ sizeof (struct acl_subject_label)))
26440+ break;
26441+
26442+ userp = s_tmp.prev;
26443+ /* do not count nested subjects against this count, since
26444+ they are not included in the hash table, but are
26445+ attached to objects. We have already counted
26446+ the subjects in userspace for the allocation
26447+ stack
26448+ */
26449+ if (!(s_tmp.mode & GR_NESTED))
26450+ num++;
26451+ }
26452+
26453+ return num;
26454+}
26455+
26456+static int
26457+copy_user_allowedips(struct acl_role_label *rolep)
26458+{
26459+ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
26460+
26461+ ruserip = rolep->allowed_ips;
26462+
26463+ while (ruserip) {
26464+ rlast = rtmp;
26465+
26466+ if ((rtmp = (struct role_allowed_ip *)
26467+ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
26468+ return -ENOMEM;
26469+
26470+ if (copy_from_user(rtmp, ruserip,
26471+ sizeof (struct role_allowed_ip)))
26472+ return -EFAULT;
26473+
26474+ ruserip = rtmp->prev;
26475+
26476+ if (!rlast) {
26477+ rtmp->prev = NULL;
26478+ rolep->allowed_ips = rtmp;
26479+ } else {
26480+ rlast->next = rtmp;
26481+ rtmp->prev = rlast;
26482+ }
26483+
26484+ if (!ruserip)
26485+ rtmp->next = NULL;
26486+ }
26487+
26488+ return 0;
26489+}
26490+
26491+static int
26492+copy_user_transitions(struct acl_role_label *rolep)
26493+{
26494+ struct role_transition *rusertp, *rtmp = NULL, *rlast;
26495+
26496+ unsigned int len;
26497+ char *tmp;
26498+
26499+ rusertp = rolep->transitions;
26500+
26501+ while (rusertp) {
26502+ rlast = rtmp;
26503+
26504+ if ((rtmp = (struct role_transition *)
26505+ acl_alloc(sizeof (struct role_transition))) == NULL)
26506+ return -ENOMEM;
26507+
26508+ if (copy_from_user(rtmp, rusertp,
26509+ sizeof (struct role_transition)))
26510+ return -EFAULT;
26511+
26512+ rusertp = rtmp->prev;
26513+
26514+ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
26515+
26516+ if (!len || len >= GR_SPROLE_LEN)
26517+ return -EINVAL;
26518+
26519+ if ((tmp = (char *) acl_alloc(len)) == NULL)
26520+ return -ENOMEM;
26521+
26522+ if (copy_from_user(tmp, rtmp->rolename, len))
26523+ return -EFAULT;
26524+
26525+ rtmp->rolename = tmp;
26526+
26527+ if (!rlast) {
26528+ rtmp->prev = NULL;
26529+ rolep->transitions = rtmp;
26530+ } else {
26531+ rlast->next = rtmp;
26532+ rtmp->prev = rlast;
26533+ }
26534+
26535+ if (!rusertp)
26536+ rtmp->next = NULL;
26537+ }
26538+
26539+ return 0;
26540+}
26541+
26542+static struct acl_subject_label *
26543+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
26544+{
26545+ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
26546+ unsigned int len;
26547+ char *tmp;
26548+ __u32 num_objs;
26549+ struct acl_ip_label **i_tmp, *i_utmp2;
26550+ struct gr_hash_struct ghash;
26551+ struct subject_map *subjmap;
26552+ unsigned int i_num;
26553+ int err;
26554+
26555+ s_tmp = lookup_subject_map(userp);
26556+
26557+ /* we've already copied this subject into the kernel, just return
26558+ the reference to it, and don't copy it over again
26559+ */
26560+ if (s_tmp)
26561+ return(s_tmp);
26562+
26563+ if ((s_tmp = (struct acl_subject_label *)
26564+ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
26565+ return ERR_PTR(-ENOMEM);
26566+
26567+ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
26568+ if (subjmap == NULL)
26569+ return ERR_PTR(-ENOMEM);
26570+
26571+ subjmap->user = userp;
26572+ subjmap->kernel = s_tmp;
26573+ insert_subj_map_entry(subjmap);
26574+
26575+ if (copy_from_user(s_tmp, userp,
26576+ sizeof (struct acl_subject_label)))
26577+ return ERR_PTR(-EFAULT);
26578+
26579+ len = strnlen_user(s_tmp->filename, PATH_MAX);
26580+
26581+ if (!len || len >= PATH_MAX)
26582+ return ERR_PTR(-EINVAL);
26583+
26584+ if ((tmp = (char *) acl_alloc(len)) == NULL)
26585+ return ERR_PTR(-ENOMEM);
26586+
26587+ if (copy_from_user(tmp, s_tmp->filename, len))
26588+ return ERR_PTR(-EFAULT);
26589+
26590+ s_tmp->filename = tmp;
26591+
26592+ if (!strcmp(s_tmp->filename, "/"))
26593+ role->root_label = s_tmp;
26594+
26595+ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
26596+ return ERR_PTR(-EFAULT);
26597+
26598+ /* copy user and group transition tables */
26599+
26600+ if (s_tmp->user_trans_num) {
26601+ uid_t *uidlist;
26602+
de855c5d 26603+ uidlist = (uid_t *)acl_alloc_num(s_tmp->user_trans_num, sizeof(uid_t));
2380c486
JR
26604+ if (uidlist == NULL)
26605+ return ERR_PTR(-ENOMEM);
26606+ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
26607+ return ERR_PTR(-EFAULT);
26608+
26609+ s_tmp->user_transitions = uidlist;
26610+ }
26611+
26612+ if (s_tmp->group_trans_num) {
26613+ gid_t *gidlist;
26614+
de855c5d 26615+ gidlist = (gid_t *)acl_alloc_num(s_tmp->group_trans_num, sizeof(gid_t));
2380c486
JR
26616+ if (gidlist == NULL)
26617+ return ERR_PTR(-ENOMEM);
26618+ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
26619+ return ERR_PTR(-EFAULT);
26620+
26621+ s_tmp->group_transitions = gidlist;
26622+ }
26623+
26624+ /* set up object hash table */
26625+ num_objs = count_user_objs(ghash.first);
26626+
26627+ s_tmp->obj_hash_size = num_objs;
26628+ s_tmp->obj_hash =
26629+ (struct acl_object_label **)
26630+ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
26631+
26632+ if (!s_tmp->obj_hash)
26633+ return ERR_PTR(-ENOMEM);
26634+
26635+ memset(s_tmp->obj_hash, 0,
26636+ s_tmp->obj_hash_size *
26637+ sizeof (struct acl_object_label *));
26638+
26639+ /* add in objects */
26640+ err = copy_user_objs(ghash.first, s_tmp, role);
26641+
26642+ if (err)
26643+ return ERR_PTR(err);
26644+
26645+ /* set pointer for parent subject */
26646+ if (s_tmp->parent_subject) {
26647+ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
26648+
26649+ if (IS_ERR(s_tmp2))
26650+ return s_tmp2;
26651+
26652+ s_tmp->parent_subject = s_tmp2;
26653+ }
26654+
26655+ /* add in ip acls */
26656+
26657+ if (!s_tmp->ip_num) {
26658+ s_tmp->ips = NULL;
26659+ goto insert;
26660+ }
26661+
26662+ i_tmp =
de855c5d
AM
26663+ (struct acl_ip_label **) acl_alloc_num(s_tmp->ip_num,
26664+ sizeof (struct acl_ip_label *));
2380c486
JR
26665+
26666+ if (!i_tmp)
26667+ return ERR_PTR(-ENOMEM);
26668+
26669+ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
26670+ *(i_tmp + i_num) =
26671+ (struct acl_ip_label *)
26672+ acl_alloc(sizeof (struct acl_ip_label));
26673+ if (!*(i_tmp + i_num))
26674+ return ERR_PTR(-ENOMEM);
26675+
26676+ if (copy_from_user
26677+ (&i_utmp2, s_tmp->ips + i_num,
26678+ sizeof (struct acl_ip_label *)))
26679+ return ERR_PTR(-EFAULT);
26680+
26681+ if (copy_from_user
26682+ (*(i_tmp + i_num), i_utmp2,
26683+ sizeof (struct acl_ip_label)))
26684+ return ERR_PTR(-EFAULT);
26685+
26686+ if ((*(i_tmp + i_num))->iface == NULL)
26687+ continue;
26688+
26689+ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
26690+ if (!len || len >= IFNAMSIZ)
26691+ return ERR_PTR(-EINVAL);
26692+ tmp = acl_alloc(len);
26693+ if (tmp == NULL)
26694+ return ERR_PTR(-ENOMEM);
26695+ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
26696+ return ERR_PTR(-EFAULT);
26697+ (*(i_tmp + i_num))->iface = tmp;
26698+ }
26699+
26700+ s_tmp->ips = i_tmp;
26701+
26702+insert:
26703+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
26704+ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
26705+ return ERR_PTR(-ENOMEM);
26706+
26707+ return s_tmp;
26708+}
26709+
26710+static int
26711+copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
26712+{
26713+ struct acl_subject_label s_pre;
26714+ struct acl_subject_label * ret;
26715+ int err;
26716+
26717+ while (userp) {
26718+ if (copy_from_user(&s_pre, userp,
26719+ sizeof (struct acl_subject_label)))
26720+ return -EFAULT;
26721+
26722+ /* do not add nested subjects here, add
26723+ while parsing objects
26724+ */
26725+
26726+ if (s_pre.mode & GR_NESTED) {
26727+ userp = s_pre.prev;
26728+ continue;
26729+ }
26730+
26731+ ret = do_copy_user_subj(userp, role);
26732+
26733+ err = PTR_ERR(ret);
26734+ if (IS_ERR(ret))
26735+ return err;
26736+
26737+ insert_acl_subj_label(ret, role);
26738+
26739+ userp = s_pre.prev;
26740+ }
26741+
26742+ return 0;
26743+}
26744+
26745+static int
26746+copy_user_acl(struct gr_arg *arg)
26747+{
26748+ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
26749+ struct sprole_pw *sptmp;
26750+ struct gr_hash_struct *ghash;
26751+ uid_t *domainlist;
26752+ unsigned int r_num;
26753+ unsigned int len;
26754+ char *tmp;
26755+ int err = 0;
26756+ __u16 i;
26757+ __u32 num_subjs;
26758+
26759+ /* we need a default and kernel role */
26760+ if (arg->role_db.num_roles < 2)
26761+ return -EINVAL;
26762+
26763+ /* copy special role authentication info from userspace */
26764+
26765+ num_sprole_pws = arg->num_sprole_pws;
de855c5d 26766+ acl_special_roles = (struct sprole_pw **) acl_alloc_num(num_sprole_pws, sizeof(struct sprole_pw *));
2380c486
JR
26767+
26768+ if (!acl_special_roles) {
26769+ err = -ENOMEM;
26770+ goto cleanup;
26771+ }
26772+
26773+ for (i = 0; i < num_sprole_pws; i++) {
26774+ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
26775+ if (!sptmp) {
26776+ err = -ENOMEM;
26777+ goto cleanup;
26778+ }
26779+ if (copy_from_user(sptmp, arg->sprole_pws + i,
26780+ sizeof (struct sprole_pw))) {
26781+ err = -EFAULT;
26782+ goto cleanup;
26783+ }
26784+
26785+ len =
26786+ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
26787+
26788+ if (!len || len >= GR_SPROLE_LEN) {
26789+ err = -EINVAL;
26790+ goto cleanup;
26791+ }
26792+
26793+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
26794+ err = -ENOMEM;
26795+ goto cleanup;
26796+ }
26797+
26798+ if (copy_from_user(tmp, sptmp->rolename, len)) {
26799+ err = -EFAULT;
26800+ goto cleanup;
26801+ }
26802+
26803+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
26804+ printk(KERN_ALERT "Copying special role %s\n", tmp);
26805+#endif
26806+ sptmp->rolename = tmp;
26807+ acl_special_roles[i] = sptmp;
26808+ }
26809+
26810+ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
26811+
26812+ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
26813+ r_tmp = acl_alloc(sizeof (struct acl_role_label));
26814+
26815+ if (!r_tmp) {
26816+ err = -ENOMEM;
26817+ goto cleanup;
26818+ }
26819+
26820+ if (copy_from_user(&r_utmp2, r_utmp + r_num,
26821+ sizeof (struct acl_role_label *))) {
26822+ err = -EFAULT;
26823+ goto cleanup;
26824+ }
26825+
26826+ if (copy_from_user(r_tmp, r_utmp2,
26827+ sizeof (struct acl_role_label))) {
26828+ err = -EFAULT;
26829+ goto cleanup;
26830+ }
26831+
26832+ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
26833+
26834+ if (!len || len >= PATH_MAX) {
26835+ err = -EINVAL;
26836+ goto cleanup;
26837+ }
26838+
26839+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
26840+ err = -ENOMEM;
26841+ goto cleanup;
26842+ }
26843+ if (copy_from_user(tmp, r_tmp->rolename, len)) {
26844+ err = -EFAULT;
26845+ goto cleanup;
26846+ }
26847+ r_tmp->rolename = tmp;
26848+
26849+ if (!strcmp(r_tmp->rolename, "default")
26850+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
26851+ default_role = r_tmp;
26852+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
26853+ kernel_role = r_tmp;
26854+ }
26855+
26856+ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
26857+ err = -ENOMEM;
26858+ goto cleanup;
26859+ }
26860+ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
26861+ err = -EFAULT;
26862+ goto cleanup;
26863+ }
26864+
26865+ r_tmp->hash = ghash;
26866+
26867+ num_subjs = count_user_subjs(r_tmp->hash->first);
26868+
26869+ r_tmp->subj_hash_size = num_subjs;
26870+ r_tmp->subj_hash =
26871+ (struct acl_subject_label **)
26872+ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
26873+
26874+ if (!r_tmp->subj_hash) {
26875+ err = -ENOMEM;
26876+ goto cleanup;
26877+ }
26878+
26879+ err = copy_user_allowedips(r_tmp);
26880+ if (err)
26881+ goto cleanup;
26882+
26883+ /* copy domain info */
26884+ if (r_tmp->domain_children != NULL) {
de855c5d 26885+ domainlist = acl_alloc_num(r_tmp->domain_child_num, sizeof(uid_t));
2380c486
JR
26886+ if (domainlist == NULL) {
26887+ err = -ENOMEM;
26888+ goto cleanup;
26889+ }
26890+ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
26891+ err = -EFAULT;
26892+ goto cleanup;
26893+ }
26894+ r_tmp->domain_children = domainlist;
26895+ }
26896+
26897+ err = copy_user_transitions(r_tmp);
26898+ if (err)
26899+ goto cleanup;
26900+
26901+ memset(r_tmp->subj_hash, 0,
26902+ r_tmp->subj_hash_size *
26903+ sizeof (struct acl_subject_label *));
26904+
26905+ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
26906+
26907+ if (err)
26908+ goto cleanup;
26909+
26910+ /* set nested subject list to null */
26911+ r_tmp->hash->first = NULL;
26912+
26913+ insert_acl_role_label(r_tmp);
26914+ }
26915+
26916+ goto return_err;
26917+ cleanup:
26918+ free_variables();
26919+ return_err:
26920+ return err;
26921+
26922+}
26923+
26924+static int
26925+gracl_init(struct gr_arg *args)
26926+{
26927+ int error = 0;
26928+
26929+ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
26930+ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
26931+
26932+ if (init_variables(args)) {
26933+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
26934+ error = -ENOMEM;
26935+ free_variables();
26936+ goto out;
26937+ }
26938+
26939+ error = copy_user_acl(args);
26940+ free_init_variables();
26941+ if (error) {
26942+ free_variables();
26943+ goto out;
26944+ }
26945+
26946+ if ((error = gr_set_acls(0))) {
26947+ free_variables();
26948+ goto out;
26949+ }
26950+
017d2877
AM
26951+#ifdef CONFIG_PAX_KERNEXEC
26952+ {
26953+ unsigned long cr0;
26954+
26955+ pax_open_kernel(cr0);
26956+ gr_status |= GR_READY;
26957+ pax_close_kernel(cr0);
26958+ }
26959+#else
2380c486 26960+ gr_status |= GR_READY;
017d2877
AM
26961+#endif
26962+
2380c486
JR
26963+ out:
26964+ return error;
26965+}
26966+
26967+/* derived from glibc fnmatch() 0: match, 1: no match*/
26968+
26969+static int
26970+glob_match(const char *p, const char *n)
26971+{
26972+ char c;
26973+
26974+ while ((c = *p++) != '\0') {
26975+ switch (c) {
26976+ case '?':
26977+ if (*n == '\0')
26978+ return 1;
26979+ else if (*n == '/')
26980+ return 1;
26981+ break;
26982+ case '\\':
26983+ if (*n != c)
26984+ return 1;
26985+ break;
26986+ case '*':
26987+ for (c = *p++; c == '?' || c == '*'; c = *p++) {
26988+ if (*n == '/')
26989+ return 1;
26990+ else if (c == '?') {
26991+ if (*n == '\0')
26992+ return 1;
26993+ else
26994+ ++n;
26995+ }
26996+ }
26997+ if (c == '\0') {
26998+ return 0;
26999+ } else {
27000+ const char *endp;
27001+
27002+ if ((endp = strchr(n, '/')) == NULL)
27003+ endp = n + strlen(n);
27004+
27005+ if (c == '[') {
27006+ for (--p; n < endp; ++n)
27007+ if (!glob_match(p, n))
27008+ return 0;
27009+ } else if (c == '/') {
27010+ while (*n != '\0' && *n != '/')
27011+ ++n;
27012+ if (*n == '/' && !glob_match(p, n + 1))
27013+ return 0;
27014+ } else {
27015+ for (--p; n < endp; ++n)
27016+ if (*n == c && !glob_match(p, n))
27017+ return 0;
27018+ }
27019+
27020+ return 1;
27021+ }
27022+ case '[':
27023+ {
27024+ int not;
27025+ char cold;
27026+
27027+ if (*n == '\0' || *n == '/')
27028+ return 1;
27029+
27030+ not = (*p == '!' || *p == '^');
27031+ if (not)
27032+ ++p;
27033+
27034+ c = *p++;
27035+ for (;;) {
27036+ unsigned char fn = (unsigned char)*n;
27037+
27038+ if (c == '\0')
27039+ return 1;
27040+ else {
27041+ if (c == fn)
27042+ goto matched;
27043+ cold = c;
27044+ c = *p++;
27045+
27046+ if (c == '-' && *p != ']') {
27047+ unsigned char cend = *p++;
27048+
27049+ if (cend == '\0')
27050+ return 1;
27051+
27052+ if (cold <= fn && fn <= cend)
27053+ goto matched;
27054+
27055+ c = *p++;
27056+ }
27057+ }
27058+
27059+ if (c == ']')
27060+ break;
27061+ }
27062+ if (!not)
27063+ return 1;
27064+ break;
27065+ matched:
27066+ while (c != ']') {
27067+ if (c == '\0')
27068+ return 1;
27069+
27070+ c = *p++;
27071+ }
27072+ if (not)
27073+ return 1;
27074+ }
27075+ break;
27076+ default:
27077+ if (c != *n)
27078+ return 1;
27079+ }
27080+
27081+ ++n;
27082+ }
27083+
27084+ if (*n == '\0')
27085+ return 0;
27086+
27087+ if (*n == '/')
27088+ return 0;
27089+
27090+ return 1;
27091+}
27092+
27093+static struct acl_object_label *
27094+chk_glob_label(struct acl_object_label *globbed,
27095+ struct dentry *dentry, struct vfsmount *mnt, char **path)
27096+{
27097+ struct acl_object_label *tmp;
27098+
27099+ if (*path == NULL)
27100+ *path = gr_to_filename_nolock(dentry, mnt);
27101+
27102+ tmp = globbed;
27103+
27104+ while (tmp) {
27105+ if (!glob_match(tmp->filename, *path))
27106+ return tmp;
27107+ tmp = tmp->next;
27108+ }
27109+
27110+ return NULL;
27111+}
27112+
27113+static struct acl_object_label *
27114+__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
27115+ const ino_t curr_ino, const dev_t curr_dev,
de855c5d 27116+ const struct acl_subject_label *subj, char **path, const int checkglob)
2380c486
JR
27117+{
27118+ struct acl_subject_label *tmpsubj;
27119+ struct acl_object_label *retval;
27120+ struct acl_object_label *retval2;
27121+
27122+ tmpsubj = (struct acl_subject_label *) subj;
27123+ read_lock(&gr_inode_lock);
27124+ do {
27125+ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
27126+ if (retval) {
de855c5d 27127+ if (checkglob && retval->globbed) {
2380c486
JR
27128+ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
27129+ (struct vfsmount *)orig_mnt, path);
27130+ if (retval2)
27131+ retval = retval2;
27132+ }
27133+ break;
27134+ }
27135+ } while ((tmpsubj = tmpsubj->parent_subject));
27136+ read_unlock(&gr_inode_lock);
27137+
27138+ return retval;
27139+}
27140+
27141+static __inline__ struct acl_object_label *
27142+full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
27143+ const struct dentry *curr_dentry,
de855c5d 27144+ const struct acl_subject_label *subj, char **path, const int checkglob)
2380c486
JR
27145+{
27146+ return __full_lookup(orig_dentry, orig_mnt,
27147+ curr_dentry->d_inode->i_ino,
de855c5d 27148+ curr_dentry->d_inode->i_sb->s_dev, subj, path, checkglob);
2380c486
JR
27149+}
27150+
27151+static struct acl_object_label *
27152+__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
de855c5d 27153+ const struct acl_subject_label *subj, char *path, const int checkglob)
2380c486
JR
27154+{
27155+ struct dentry *dentry = (struct dentry *) l_dentry;
27156+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
27157+ struct acl_object_label *retval;
27158+
27159+ spin_lock(&dcache_lock);
27160+
27161+ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
27162+ /* ignore Eric Biederman */
27163+ IS_PRIVATE(l_dentry->d_inode))) {
27164+ retval = fakefs_obj;
27165+ goto out;
27166+ }
27167+
27168+ for (;;) {
27169+ if (dentry == real_root && mnt == real_root_mnt)
27170+ break;
27171+
27172+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
27173+ if (mnt->mnt_parent == mnt)
27174+ break;
27175+
de855c5d 27176+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
2380c486
JR
27177+ if (retval != NULL)
27178+ goto out;
27179+
27180+ dentry = mnt->mnt_mountpoint;
27181+ mnt = mnt->mnt_parent;
27182+ continue;
27183+ }
27184+
de855c5d 27185+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
2380c486
JR
27186+ if (retval != NULL)
27187+ goto out;
27188+
27189+ dentry = dentry->d_parent;
27190+ }
27191+
de855c5d 27192+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob);
2380c486
JR
27193+
27194+ if (retval == NULL)
de855c5d 27195+ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path, checkglob);
2380c486
JR
27196+out:
27197+ spin_unlock(&dcache_lock);
27198+ return retval;
27199+}
27200+
27201+static __inline__ struct acl_object_label *
27202+chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
27203+ const struct acl_subject_label *subj)
27204+{
27205+ char *path = NULL;
de855c5d
AM
27206+ return __chk_obj_label(l_dentry, l_mnt, subj, path, 1);
27207+}
27208+
27209+static __inline__ struct acl_object_label *
27210+chk_obj_label_noglob(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
27211+ const struct acl_subject_label *subj)
27212+{
27213+ char *path = NULL;
27214+ return __chk_obj_label(l_dentry, l_mnt, subj, path, 0);
2380c486
JR
27215+}
27216+
27217+static __inline__ struct acl_object_label *
27218+chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
27219+ const struct acl_subject_label *subj, char *path)
27220+{
de855c5d 27221+ return __chk_obj_label(l_dentry, l_mnt, subj, path, 1);
2380c486
JR
27222+}
27223+
27224+static struct acl_subject_label *
27225+chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
27226+ const struct acl_role_label *role)
27227+{
27228+ struct dentry *dentry = (struct dentry *) l_dentry;
27229+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
27230+ struct acl_subject_label *retval;
27231+
27232+ spin_lock(&dcache_lock);
27233+
27234+ for (;;) {
27235+ if (dentry == real_root && mnt == real_root_mnt)
27236+ break;
27237+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
27238+ if (mnt->mnt_parent == mnt)
27239+ break;
27240+
27241+ read_lock(&gr_inode_lock);
27242+ retval =
27243+ lookup_acl_subj_label(dentry->d_inode->i_ino,
27244+ dentry->d_inode->i_sb->s_dev, role);
27245+ read_unlock(&gr_inode_lock);
27246+ if (retval != NULL)
27247+ goto out;
27248+
27249+ dentry = mnt->mnt_mountpoint;
27250+ mnt = mnt->mnt_parent;
27251+ continue;
27252+ }
27253+
27254+ read_lock(&gr_inode_lock);
27255+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
27256+ dentry->d_inode->i_sb->s_dev, role);
27257+ read_unlock(&gr_inode_lock);
27258+ if (retval != NULL)
27259+ goto out;
27260+
27261+ dentry = dentry->d_parent;
27262+ }
27263+
27264+ read_lock(&gr_inode_lock);
27265+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
27266+ dentry->d_inode->i_sb->s_dev, role);
27267+ read_unlock(&gr_inode_lock);
27268+
27269+ if (unlikely(retval == NULL)) {
27270+ read_lock(&gr_inode_lock);
27271+ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
27272+ real_root->d_inode->i_sb->s_dev, role);
27273+ read_unlock(&gr_inode_lock);
27274+ }
27275+out:
27276+ spin_unlock(&dcache_lock);
27277+
27278+ return retval;
27279+}
27280+
27281+static void
27282+gr_log_learn(const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
27283+{
27284+ struct task_struct *task = current;
27285+ const struct cred *cred = current_cred();
27286+
27287+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
27288+ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
27289+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
de855c5d 27290+ 1UL, 1UL, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
2380c486
JR
27291+
27292+ return;
27293+}
27294+
27295+static void
27296+gr_log_learn_sysctl(const char *path, const __u32 mode)
27297+{
27298+ struct task_struct *task = current;
27299+ const struct cred *cred = current_cred();
27300+
27301+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
27302+ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
27303+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
de855c5d 27304+ 1UL, 1UL, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
2380c486
JR
27305+
27306+ return;
27307+}
27308+
27309+static void
27310+gr_log_learn_id_change(const char type, const unsigned int real,
27311+ const unsigned int effective, const unsigned int fs)
27312+{
27313+ struct task_struct *task = current;
27314+ const struct cred *cred = current_cred();
27315+
27316+ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
27317+ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
27318+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
27319+ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
27320+
27321+ return;
27322+}
27323+
27324+__u32
27325+gr_check_link(const struct dentry * new_dentry,
27326+ const struct dentry * parent_dentry,
27327+ const struct vfsmount * parent_mnt,
27328+ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
27329+{
27330+ struct acl_object_label *obj;
27331+ __u32 oldmode, newmode;
27332+ __u32 needmode;
27333+
27334+ if (unlikely(!(gr_status & GR_READY)))
27335+ return (GR_CREATE | GR_LINK);
27336+
27337+ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
27338+ oldmode = obj->mode;
27339+
27340+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
27341+ oldmode |= (GR_CREATE | GR_LINK);
27342+
27343+ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
27344+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
27345+ needmode |= GR_SETID | GR_AUDIT_SETID;
27346+
27347+ newmode =
27348+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
27349+ oldmode | needmode);
27350+
27351+ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
27352+ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
27353+ GR_INHERIT | GR_AUDIT_INHERIT);
27354+
27355+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
27356+ goto bad;
27357+
27358+ if ((oldmode & needmode) != needmode)
27359+ goto bad;
27360+
27361+ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
27362+ if ((newmode & needmode) != needmode)
27363+ goto bad;
27364+
27365+ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
27366+ return newmode;
27367+bad:
27368+ needmode = oldmode;
27369+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
27370+ needmode |= GR_SETID;
27371+
27372+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
27373+ gr_log_learn(old_dentry, old_mnt, needmode);
27374+ return (GR_CREATE | GR_LINK);
27375+ } else if (newmode & GR_SUPPRESS)
27376+ return GR_SUPPRESS;
27377+ else
27378+ return 0;
27379+}
27380+
27381+__u32
27382+gr_search_file(const struct dentry * dentry, const __u32 mode,
27383+ const struct vfsmount * mnt)
27384+{
27385+ __u32 retval = mode;
27386+ struct acl_subject_label *curracl;
27387+ struct acl_object_label *currobj;
27388+
27389+ if (unlikely(!(gr_status & GR_READY)))
27390+ return (mode & ~GR_AUDITS);
27391+
27392+ curracl = current->acl;
27393+
27394+ currobj = chk_obj_label(dentry, mnt, curracl);
27395+ retval = currobj->mode & mode;
27396+
27397+ if (unlikely
27398+ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
27399+ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
27400+ __u32 new_mode = mode;
27401+
27402+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
27403+
27404+ retval = new_mode;
27405+
27406+ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
27407+ new_mode |= GR_INHERIT;
27408+
27409+ if (!(mode & GR_NOLEARN))
27410+ gr_log_learn(dentry, mnt, new_mode);
27411+ }
27412+
27413+ return retval;
27414+}
27415+
27416+__u32
27417+gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
27418+ const struct vfsmount * mnt, const __u32 mode)
27419+{
27420+ struct name_entry *match;
27421+ struct acl_object_label *matchpo;
27422+ struct acl_subject_label *curracl;
27423+ char *path;
27424+ __u32 retval;
27425+
27426+ if (unlikely(!(gr_status & GR_READY)))
27427+ return (mode & ~GR_AUDITS);
27428+
27429+ preempt_disable();
27430+ path = gr_to_filename_rbac(new_dentry, mnt);
27431+ match = lookup_name_entry_create(path);
27432+
27433+ if (!match)
27434+ goto check_parent;
27435+
27436+ curracl = current->acl;
27437+
27438+ read_lock(&gr_inode_lock);
27439+ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
27440+ read_unlock(&gr_inode_lock);
27441+
27442+ if (matchpo) {
27443+ if ((matchpo->mode & mode) !=
27444+ (mode & ~(GR_AUDITS | GR_SUPPRESS))
27445+ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
27446+ __u32 new_mode = mode;
27447+
27448+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
27449+
27450+ gr_log_learn(new_dentry, mnt, new_mode);
27451+
27452+ preempt_enable();
27453+ return new_mode;
27454+ }
27455+ preempt_enable();
27456+ return (matchpo->mode & mode);
27457+ }
27458+
27459+ check_parent:
27460+ curracl = current->acl;
27461+
27462+ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
27463+ retval = matchpo->mode & mode;
27464+
27465+ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
27466+ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
27467+ __u32 new_mode = mode;
27468+
27469+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
27470+
27471+ gr_log_learn(new_dentry, mnt, new_mode);
27472+ preempt_enable();
27473+ return new_mode;
27474+ }
27475+
27476+ preempt_enable();
27477+ return retval;
27478+}
27479+
27480+int
27481+gr_check_hidden_task(const struct task_struct *task)
27482+{
27483+ if (unlikely(!(gr_status & GR_READY)))
27484+ return 0;
27485+
27486+ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
27487+ return 1;
27488+
27489+ return 0;
27490+}
27491+
27492+int
27493+gr_check_protected_task(const struct task_struct *task)
27494+{
27495+ if (unlikely(!(gr_status & GR_READY) || !task))
27496+ return 0;
27497+
27498+ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
27499+ task->acl != current->acl)
27500+ return 1;
27501+
27502+ return 0;
27503+}
27504+
27505+void
27506+gr_copy_label(struct task_struct *tsk)
27507+{
27508+ tsk->signal->used_accept = 0;
27509+ tsk->acl_sp_role = 0;
27510+ tsk->acl_role_id = current->acl_role_id;
27511+ tsk->acl = current->acl;
27512+ tsk->role = current->role;
27513+ tsk->signal->curr_ip = current->signal->curr_ip;
27514+ if (current->exec_file)
27515+ get_file(current->exec_file);
27516+ tsk->exec_file = current->exec_file;
27517+ tsk->is_writable = current->is_writable;
27518+ if (unlikely(current->signal->used_accept))
27519+ current->signal->curr_ip = 0;
27520+
27521+ return;
27522+}
27523+
27524+static void
27525+gr_set_proc_res(struct task_struct *task)
27526+{
27527+ struct acl_subject_label *proc;
27528+ unsigned short i;
27529+
27530+ proc = task->acl;
27531+
27532+ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
27533+ return;
27534+
27535+ for (i = 0; i < RLIM_NLIMITS; i++) {
27536+ if (!(proc->resmask & (1 << i)))
27537+ continue;
27538+
27539+ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
27540+ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
27541+ }
27542+
27543+ return;
27544+}
27545+
27546+int
27547+gr_check_user_change(int real, int effective, int fs)
27548+{
27549+ unsigned int i;
27550+ __u16 num;
27551+ uid_t *uidlist;
27552+ int curuid;
27553+ int realok = 0;
27554+ int effectiveok = 0;
27555+ int fsok = 0;
27556+
27557+ if (unlikely(!(gr_status & GR_READY)))
27558+ return 0;
27559+
27560+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
27561+ gr_log_learn_id_change('u', real, effective, fs);
27562+
27563+ num = current->acl->user_trans_num;
27564+ uidlist = current->acl->user_transitions;
27565+
27566+ if (uidlist == NULL)
27567+ return 0;
27568+
27569+ if (real == -1)
27570+ realok = 1;
27571+ if (effective == -1)
27572+ effectiveok = 1;
27573+ if (fs == -1)
27574+ fsok = 1;
27575+
27576+ if (current->acl->user_trans_type & GR_ID_ALLOW) {
27577+ for (i = 0; i < num; i++) {
27578+ curuid = (int)uidlist[i];
27579+ if (real == curuid)
27580+ realok = 1;
27581+ if (effective == curuid)
27582+ effectiveok = 1;
27583+ if (fs == curuid)
27584+ fsok = 1;
27585+ }
27586+ } else if (current->acl->user_trans_type & GR_ID_DENY) {
27587+ for (i = 0; i < num; i++) {
27588+ curuid = (int)uidlist[i];
27589+ if (real == curuid)
27590+ break;
27591+ if (effective == curuid)
27592+ break;
27593+ if (fs == curuid)
27594+ break;
27595+ }
27596+ /* not in deny list */
27597+ if (i == num) {
27598+ realok = 1;
27599+ effectiveok = 1;
27600+ fsok = 1;
27601+ }
27602+ }
27603+
27604+ if (realok && effectiveok && fsok)
27605+ return 0;
27606+ else {
27607+ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
27608+ return 1;
27609+ }
27610+}
27611+
27612+int
27613+gr_check_group_change(int real, int effective, int fs)
27614+{
27615+ unsigned int i;
27616+ __u16 num;
27617+ gid_t *gidlist;
27618+ int curgid;
27619+ int realok = 0;
27620+ int effectiveok = 0;
27621+ int fsok = 0;
27622+
27623+ if (unlikely(!(gr_status & GR_READY)))
27624+ return 0;
27625+
27626+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
27627+ gr_log_learn_id_change('g', real, effective, fs);
27628+
27629+ num = current->acl->group_trans_num;
27630+ gidlist = current->acl->group_transitions;
27631+
27632+ if (gidlist == NULL)
27633+ return 0;
27634+
27635+ if (real == -1)
27636+ realok = 1;
27637+ if (effective == -1)
27638+ effectiveok = 1;
27639+ if (fs == -1)
27640+ fsok = 1;
27641+
27642+ if (current->acl->group_trans_type & GR_ID_ALLOW) {
27643+ for (i = 0; i < num; i++) {
27644+ curgid = (int)gidlist[i];
27645+ if (real == curgid)
27646+ realok = 1;
27647+ if (effective == curgid)
27648+ effectiveok = 1;
27649+ if (fs == curgid)
27650+ fsok = 1;
27651+ }
27652+ } else if (current->acl->group_trans_type & GR_ID_DENY) {
27653+ for (i = 0; i < num; i++) {
27654+ curgid = (int)gidlist[i];
27655+ if (real == curgid)
27656+ break;
27657+ if (effective == curgid)
27658+ break;
27659+ if (fs == curgid)
27660+ break;
27661+ }
27662+ /* not in deny list */
27663+ if (i == num) {
27664+ realok = 1;
27665+ effectiveok = 1;
27666+ fsok = 1;
27667+ }
27668+ }
27669+
27670+ if (realok && effectiveok && fsok)
27671+ return 0;
27672+ else {
27673+ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
27674+ return 1;
27675+ }
27676+}
27677+
27678+void
27679+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
27680+{
27681+ struct acl_role_label *role = task->role;
27682+ struct acl_subject_label *subj = NULL;
27683+ struct acl_object_label *obj;
27684+ struct file *filp;
27685+
27686+ if (unlikely(!(gr_status & GR_READY)))
27687+ return;
27688+
27689+ filp = task->exec_file;
27690+
27691+ /* kernel process, we'll give them the kernel role */
27692+ if (unlikely(!filp)) {
27693+ task->role = kernel_role;
27694+ task->acl = kernel_role->root_label;
27695+ return;
27696+ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
27697+ role = lookup_acl_role_label(task, uid, gid);
27698+
27699+ /* perform subject lookup in possibly new role
27700+ we can use this result below in the case where role == task->role
27701+ */
27702+ subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
27703+
27704+ /* if we changed uid/gid, but result in the same role
27705+ and are using inheritance, don't lose the inherited subject
27706+ if current subject is other than what normal lookup
27707+ would result in, we arrived via inheritance, don't
27708+ lose subject
27709+ */
27710+ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
27711+ (subj == task->acl)))
27712+ task->acl = subj;
27713+
27714+ task->role = role;
27715+
27716+ task->is_writable = 0;
27717+
27718+ /* ignore additional mmap checks for processes that are writable
27719+ by the default ACL */
27720+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
27721+ if (unlikely(obj->mode & GR_WRITE))
27722+ task->is_writable = 1;
27723+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
27724+ if (unlikely(obj->mode & GR_WRITE))
27725+ task->is_writable = 1;
27726+
27727+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
27728+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
27729+#endif
27730+
27731+ gr_set_proc_res(task);
27732+
27733+ return;
27734+}
27735+
27736+int
de855c5d
AM
27737+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt,
27738+ const int unsafe_share)
2380c486
JR
27739+{
27740+ struct task_struct *task = current;
27741+ struct acl_subject_label *newacl;
27742+ struct acl_object_label *obj;
27743+ __u32 retmode;
27744+
27745+ if (unlikely(!(gr_status & GR_READY)))
27746+ return 0;
27747+
27748+ newacl = chk_subj_label(dentry, mnt, task->role);
27749+
27750+ task_lock(task);
27751+ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
27752+ GR_POVERRIDE) && (task->acl != newacl) &&
27753+ !(task->role->roletype & GR_ROLE_GOD) &&
27754+ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
de855c5d
AM
27755+ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN)))
27756+ || unsafe_share) {
2380c486
JR
27757+ task_unlock(task);
27758+ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
27759+ return -EACCES;
27760+ }
27761+ task_unlock(task);
27762+
27763+ obj = chk_obj_label(dentry, mnt, task->acl);
27764+ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
27765+
27766+ if (!(task->acl->mode & GR_INHERITLEARN) &&
27767+ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
27768+ if (obj->nested)
27769+ task->acl = obj->nested;
27770+ else
27771+ task->acl = newacl;
27772+ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
27773+ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
27774+
27775+ task->is_writable = 0;
27776+
27777+ /* ignore additional mmap checks for processes that are writable
27778+ by the default ACL */
27779+ obj = chk_obj_label(dentry, mnt, default_role->root_label);
27780+ if (unlikely(obj->mode & GR_WRITE))
27781+ task->is_writable = 1;
27782+ obj = chk_obj_label(dentry, mnt, task->role->root_label);
27783+ if (unlikely(obj->mode & GR_WRITE))
27784+ task->is_writable = 1;
27785+
27786+ gr_set_proc_res(task);
27787+
27788+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
27789+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
27790+#endif
27791+ return 0;
27792+}
27793+
27794+/* always called with valid inodev ptr */
27795+static void
27796+do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
27797+{
27798+ struct acl_object_label *matchpo;
27799+ struct acl_subject_label *matchps;
27800+ struct acl_subject_label *subj;
27801+ struct acl_role_label *role;
27802+ unsigned int i, x;
27803+
27804+ FOR_EACH_ROLE_START(role, i)
27805+ FOR_EACH_SUBJECT_START(role, subj, x)
27806+ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
27807+ matchpo->mode |= GR_DELETED;
27808+ FOR_EACH_SUBJECT_END(subj,x)
27809+ FOR_EACH_NESTED_SUBJECT_START(role, subj)
27810+ if (subj->inode == ino && subj->device == dev)
27811+ subj->mode |= GR_DELETED;
27812+ FOR_EACH_NESTED_SUBJECT_END(subj)
27813+ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
27814+ matchps->mode |= GR_DELETED;
27815+ FOR_EACH_ROLE_END(role,i)
27816+
27817+ inodev->nentry->deleted = 1;
27818+
27819+ return;
27820+}
27821+
27822+void
27823+gr_handle_delete(const ino_t ino, const dev_t dev)
27824+{
27825+ struct inodev_entry *inodev;
27826+
27827+ if (unlikely(!(gr_status & GR_READY)))
27828+ return;
27829+
27830+ write_lock(&gr_inode_lock);
27831+ inodev = lookup_inodev_entry(ino, dev);
27832+ if (inodev != NULL)
27833+ do_handle_delete(inodev, ino, dev);
27834+ write_unlock(&gr_inode_lock);
27835+
27836+ return;
27837+}
27838+
27839+static void
27840+update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
27841+ const ino_t newinode, const dev_t newdevice,
27842+ struct acl_subject_label *subj)
27843+{
27844+ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
27845+ struct acl_object_label *match;
27846+
27847+ match = subj->obj_hash[index];
27848+
27849+ while (match && (match->inode != oldinode ||
27850+ match->device != olddevice ||
27851+ !(match->mode & GR_DELETED)))
27852+ match = match->next;
27853+
27854+ if (match && (match->inode == oldinode)
27855+ && (match->device == olddevice)
27856+ && (match->mode & GR_DELETED)) {
27857+ if (match->prev == NULL) {
27858+ subj->obj_hash[index] = match->next;
27859+ if (match->next != NULL)
27860+ match->next->prev = NULL;
27861+ } else {
27862+ match->prev->next = match->next;
27863+ if (match->next != NULL)
27864+ match->next->prev = match->prev;
27865+ }
27866+ match->prev = NULL;
27867+ match->next = NULL;
27868+ match->inode = newinode;
27869+ match->device = newdevice;
27870+ match->mode &= ~GR_DELETED;
27871+
27872+ insert_acl_obj_label(match, subj);
27873+ }
27874+
27875+ return;
27876+}
27877+
27878+static void
27879+update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
27880+ const ino_t newinode, const dev_t newdevice,
27881+ struct acl_role_label *role)
27882+{
27883+ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
27884+ struct acl_subject_label *match;
27885+
27886+ match = role->subj_hash[index];
27887+
27888+ while (match && (match->inode != oldinode ||
27889+ match->device != olddevice ||
27890+ !(match->mode & GR_DELETED)))
27891+ match = match->next;
27892+
27893+ if (match && (match->inode == oldinode)
27894+ && (match->device == olddevice)
27895+ && (match->mode & GR_DELETED)) {
27896+ if (match->prev == NULL) {
27897+ role->subj_hash[index] = match->next;
27898+ if (match->next != NULL)
27899+ match->next->prev = NULL;
27900+ } else {
27901+ match->prev->next = match->next;
27902+ if (match->next != NULL)
27903+ match->next->prev = match->prev;
27904+ }
27905+ match->prev = NULL;
27906+ match->next = NULL;
27907+ match->inode = newinode;
27908+ match->device = newdevice;
27909+ match->mode &= ~GR_DELETED;
27910+
27911+ insert_acl_subj_label(match, role);
27912+ }
27913+
27914+ return;
27915+}
27916+
27917+static void
27918+update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
27919+ const ino_t newinode, const dev_t newdevice)
27920+{
27921+ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
27922+ struct inodev_entry *match;
27923+
27924+ match = inodev_set.i_hash[index];
27925+
27926+ while (match && (match->nentry->inode != oldinode ||
27927+ match->nentry->device != olddevice || !match->nentry->deleted))
27928+ match = match->next;
27929+
27930+ if (match && (match->nentry->inode == oldinode)
27931+ && (match->nentry->device == olddevice) &&
27932+ match->nentry->deleted) {
27933+ if (match->prev == NULL) {
27934+ inodev_set.i_hash[index] = match->next;
27935+ if (match->next != NULL)
27936+ match->next->prev = NULL;
27937+ } else {
27938+ match->prev->next = match->next;
27939+ if (match->next != NULL)
27940+ match->next->prev = match->prev;
27941+ }
27942+ match->prev = NULL;
27943+ match->next = NULL;
27944+ match->nentry->inode = newinode;
27945+ match->nentry->device = newdevice;
27946+ match->nentry->deleted = 0;
27947+
27948+ insert_inodev_entry(match);
27949+ }
27950+
27951+ return;
27952+}
27953+
27954+static void
27955+do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
27956+ const struct vfsmount *mnt)
27957+{
27958+ struct acl_subject_label *subj;
27959+ struct acl_role_label *role;
27960+ unsigned int i, x;
27961+
27962+ FOR_EACH_ROLE_START(role, i)
27963+ update_acl_subj_label(matchn->inode, matchn->device,
27964+ dentry->d_inode->i_ino,
27965+ dentry->d_inode->i_sb->s_dev, role);
27966+
27967+ FOR_EACH_NESTED_SUBJECT_START(role, subj)
27968+ if ((subj->inode == dentry->d_inode->i_ino) &&
27969+ (subj->device == dentry->d_inode->i_sb->s_dev)) {
27970+ subj->inode = dentry->d_inode->i_ino;
27971+ subj->device = dentry->d_inode->i_sb->s_dev;
27972+ }
27973+ FOR_EACH_NESTED_SUBJECT_END(subj)
27974+ FOR_EACH_SUBJECT_START(role, subj, x)
27975+ update_acl_obj_label(matchn->inode, matchn->device,
27976+ dentry->d_inode->i_ino,
27977+ dentry->d_inode->i_sb->s_dev, subj);
27978+ FOR_EACH_SUBJECT_END(subj,x)
27979+ FOR_EACH_ROLE_END(role,i)
27980+
27981+ update_inodev_entry(matchn->inode, matchn->device,
27982+ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
27983+
27984+ return;
27985+}
27986+
27987+void
27988+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
27989+{
27990+ struct name_entry *matchn;
27991+
27992+ if (unlikely(!(gr_status & GR_READY)))
27993+ return;
27994+
27995+ preempt_disable();
27996+ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
27997+
27998+ if (unlikely((unsigned long)matchn)) {
27999+ write_lock(&gr_inode_lock);
28000+ do_handle_create(matchn, dentry, mnt);
28001+ write_unlock(&gr_inode_lock);
28002+ }
28003+ preempt_enable();
28004+
28005+ return;
28006+}
28007+
28008+void
28009+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
28010+ struct dentry *old_dentry,
28011+ struct dentry *new_dentry,
28012+ struct vfsmount *mnt, const __u8 replace)
28013+{
28014+ struct name_entry *matchn;
28015+ struct inodev_entry *inodev;
28016+
28017+ /* vfs_rename swaps the name and parent link for old_dentry and
28018+ new_dentry
28019+ at this point, old_dentry has the new name, parent link, and inode
28020+ for the renamed file
28021+ if a file is being replaced by a rename, new_dentry has the inode
28022+ and name for the replaced file
28023+ */
28024+
28025+ if (unlikely(!(gr_status & GR_READY)))
28026+ return;
28027+
28028+ preempt_disable();
28029+ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
28030+
28031+ /* we wouldn't have to check d_inode if it weren't for
28032+ NFS silly-renaming
28033+ */
28034+
28035+ write_lock(&gr_inode_lock);
28036+ if (unlikely(replace && new_dentry->d_inode)) {
28037+ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
28038+ new_dentry->d_inode->i_sb->s_dev);
28039+ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
28040+ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
28041+ new_dentry->d_inode->i_sb->s_dev);
28042+ }
28043+
28044+ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
28045+ old_dentry->d_inode->i_sb->s_dev);
28046+ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
28047+ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
28048+ old_dentry->d_inode->i_sb->s_dev);
28049+
28050+ if (unlikely((unsigned long)matchn))
28051+ do_handle_create(matchn, old_dentry, mnt);
28052+
28053+ write_unlock(&gr_inode_lock);
28054+ preempt_enable();
28055+
28056+ return;
28057+}
28058+
28059+static int
28060+lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
28061+ unsigned char **sum)
28062+{
28063+ struct acl_role_label *r;
28064+ struct role_allowed_ip *ipp;
28065+ struct role_transition *trans;
28066+ unsigned int i;
28067+ int found = 0;
28068+
28069+ /* check transition table */
28070+
28071+ for (trans = current->role->transitions; trans; trans = trans->next) {
28072+ if (!strcmp(rolename, trans->rolename)) {
28073+ found = 1;
28074+ break;
28075+ }
28076+ }
28077+
28078+ if (!found)
28079+ return 0;
28080+
28081+ /* handle special roles that do not require authentication
28082+ and check ip */
28083+
28084+ FOR_EACH_ROLE_START(r, i)
28085+ if (!strcmp(rolename, r->rolename) &&
28086+ (r->roletype & GR_ROLE_SPECIAL)) {
28087+ found = 0;
28088+ if (r->allowed_ips != NULL) {
28089+ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
28090+ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
28091+ (ntohl(ipp->addr) & ipp->netmask))
28092+ found = 1;
28093+ }
28094+ } else
28095+ found = 2;
28096+ if (!found)
28097+ return 0;
28098+
28099+ if (((mode == GR_SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
28100+ ((mode == GR_SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
28101+ *salt = NULL;
28102+ *sum = NULL;
28103+ return 1;
28104+ }
28105+ }
28106+ FOR_EACH_ROLE_END(r,i)
28107+
28108+ for (i = 0; i < num_sprole_pws; i++) {
28109+ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
28110+ *salt = acl_special_roles[i]->salt;
28111+ *sum = acl_special_roles[i]->sum;
28112+ return 1;
28113+ }
28114+ }
28115+
28116+ return 0;
28117+}
28118+
28119+static void
28120+assign_special_role(char *rolename)
28121+{
28122+ struct acl_object_label *obj;
28123+ struct acl_role_label *r;
28124+ struct acl_role_label *assigned = NULL;
28125+ struct task_struct *tsk;
28126+ struct file *filp;
28127+ unsigned int i;
28128+
28129+ FOR_EACH_ROLE_START(r, i)
28130+ if (!strcmp(rolename, r->rolename) &&
28131+ (r->roletype & GR_ROLE_SPECIAL))
28132+ assigned = r;
28133+ FOR_EACH_ROLE_END(r,i)
28134+
28135+ if (!assigned)
28136+ return;
28137+
28138+ read_lock(&tasklist_lock);
28139+ read_lock(&grsec_exec_file_lock);
28140+
28141+ tsk = current->parent;
28142+ if (tsk == NULL)
28143+ goto out_unlock;
28144+
28145+ filp = tsk->exec_file;
28146+ if (filp == NULL)
28147+ goto out_unlock;
28148+
28149+ tsk->is_writable = 0;
28150+
28151+ tsk->acl_sp_role = 1;
28152+ tsk->acl_role_id = ++acl_sp_role_value;
28153+ tsk->role = assigned;
28154+ tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
28155+
28156+ /* ignore additional mmap checks for processes that are writable
28157+ by the default ACL */
28158+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
28159+ if (unlikely(obj->mode & GR_WRITE))
28160+ tsk->is_writable = 1;
28161+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
28162+ if (unlikely(obj->mode & GR_WRITE))
28163+ tsk->is_writable = 1;
28164+
28165+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
28166+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
28167+#endif
28168+
28169+out_unlock:
28170+ read_unlock(&grsec_exec_file_lock);
28171+ read_unlock(&tasklist_lock);
28172+ return;
28173+}
28174+
28175+int gr_check_secure_terminal(struct task_struct *task)
28176+{
28177+ struct task_struct *p, *p2, *p3;
28178+ struct files_struct *files;
28179+ struct fdtable *fdt;
28180+ struct file *our_file = NULL, *file;
28181+ int i;
28182+
28183+ if (task->signal->tty == NULL)
28184+ return 1;
28185+
28186+ files = get_files_struct(task);
28187+ if (files != NULL) {
28188+ rcu_read_lock();
28189+ fdt = files_fdtable(files);
28190+ for (i=0; i < fdt->max_fds; i++) {
28191+ file = fcheck_files(files, i);
28192+ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
28193+ get_file(file);
28194+ our_file = file;
28195+ }
28196+ }
28197+ rcu_read_unlock();
28198+ put_files_struct(files);
28199+ }
28200+
28201+ if (our_file == NULL)
28202+ return 1;
28203+
28204+ read_lock(&tasklist_lock);
28205+ do_each_thread(p2, p) {
28206+ files = get_files_struct(p);
28207+ if (files == NULL ||
28208+ (p->signal && p->signal->tty == task->signal->tty)) {
28209+ if (files != NULL)
28210+ put_files_struct(files);
28211+ continue;
28212+ }
28213+ rcu_read_lock();
28214+ fdt = files_fdtable(files);
28215+ for (i=0; i < fdt->max_fds; i++) {
28216+ file = fcheck_files(files, i);
28217+ if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
28218+ file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
28219+ p3 = task;
28220+ while (p3->pid > 0) {
28221+ if (p3 == p)
28222+ break;
28223+ p3 = p3->parent;
28224+ }
28225+ if (p3 == p)
28226+ break;
28227+ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
28228+ gr_handle_alertkill(p);
28229+ rcu_read_unlock();
28230+ put_files_struct(files);
28231+ read_unlock(&tasklist_lock);
28232+ fput(our_file);
28233+ return 0;
28234+ }
28235+ }
28236+ rcu_read_unlock();
28237+ put_files_struct(files);
28238+ } while_each_thread(p2, p);
28239+ read_unlock(&tasklist_lock);
28240+
28241+ fput(our_file);
28242+ return 1;
28243+}
28244+
28245+ssize_t
28246+write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
28247+{
28248+ struct gr_arg_wrapper uwrap;
28249+ unsigned char *sprole_salt;
28250+ unsigned char *sprole_sum;
28251+ int error = sizeof (struct gr_arg_wrapper);
28252+ int error2 = 0;
28253+
28254+ down(&gr_dev_sem);
28255+
28256+ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
28257+ error = -EPERM;
28258+ goto out;
28259+ }
28260+
28261+ if (count != sizeof (struct gr_arg_wrapper)) {
28262+ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
28263+ error = -EINVAL;
28264+ goto out;
28265+ }
28266+
28267+
28268+ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
28269+ gr_auth_expires = 0;
28270+ gr_auth_attempts = 0;
28271+ }
28272+
28273+ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
28274+ error = -EFAULT;
28275+ goto out;
28276+ }
28277+
28278+ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
28279+ error = -EINVAL;
28280+ goto out;
28281+ }
28282+
28283+ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
28284+ error = -EFAULT;
28285+ goto out;
28286+ }
28287+
28288+ if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_SPROLEPAM &&
28289+ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
28290+ time_after(gr_auth_expires, get_seconds())) {
28291+ error = -EBUSY;
28292+ goto out;
28293+ }
28294+
28295+ /* if non-root trying to do anything other than use a special role,
28296+ do not attempt authentication, do not count towards authentication
28297+ locking
28298+ */
28299+
28300+ if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_STATUS &&
28301+ gr_usermode->mode != GR_UNSPROLE && gr_usermode->mode != GR_SPROLEPAM &&
28302+ current_uid()) {
28303+ error = -EPERM;
28304+ goto out;
28305+ }
28306+
28307+ /* ensure pw and special role name are null terminated */
28308+
28309+ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
28310+ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
28311+
28312+ /* Okay.
28313+ * We have our enough of the argument structure..(we have yet
28314+ * to copy_from_user the tables themselves) . Copy the tables
28315+ * only if we need them, i.e. for loading operations. */
28316+
28317+ switch (gr_usermode->mode) {
28318+ case GR_STATUS:
28319+ if (gr_status & GR_READY) {
28320+ error = 1;
28321+ if (!gr_check_secure_terminal(current))
28322+ error = 3;
28323+ } else
28324+ error = 2;
28325+ goto out;
28326+ case GR_SHUTDOWN:
28327+ if ((gr_status & GR_READY)
28328+ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
017d2877
AM
28329+#ifdef CONFIG_PAX_KERNEXEC
28330+ {
28331+ unsigned long cr0;
28332+
28333+ pax_open_kernel(cr0);
28334+ gr_status &= ~GR_READY;
28335+ pax_close_kernel(cr0);
28336+ }
28337+#else
2380c486 28338+ gr_status &= ~GR_READY;
017d2877 28339+#endif
2380c486
JR
28340+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
28341+ free_variables();
28342+ memset(gr_usermode, 0, sizeof (struct gr_arg));
28343+ memset(gr_system_salt, 0, GR_SALT_LEN);
28344+ memset(gr_system_sum, 0, GR_SHA_LEN);
28345+ } else if (gr_status & GR_READY) {
28346+ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
28347+ error = -EPERM;
28348+ } else {
28349+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
28350+ error = -EAGAIN;
28351+ }
28352+ break;
28353+ case GR_ENABLE:
28354+ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
28355+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
28356+ else {
28357+ if (gr_status & GR_READY)
28358+ error = -EAGAIN;
28359+ else
28360+ error = error2;
28361+ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
28362+ }
28363+ break;
28364+ case GR_RELOAD:
28365+ if (!(gr_status & GR_READY)) {
28366+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
28367+ error = -EAGAIN;
28368+ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
28369+ lock_kernel();
017d2877
AM
28370+#ifdef CONFIG_PAX_KERNEXEC
28371+ {
28372+ unsigned long cr0;
28373+
28374+ pax_open_kernel(cr0);
28375+ gr_status &= ~GR_READY;
28376+ pax_close_kernel(cr0);
28377+ }
28378+#else
2380c486 28379+ gr_status &= ~GR_READY;
017d2877 28380+#endif
2380c486
JR
28381+ free_variables();
28382+ if (!(error2 = gracl_init(gr_usermode))) {
28383+ unlock_kernel();
28384+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
28385+ } else {
28386+ unlock_kernel();
28387+ error = error2;
28388+ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
28389+ }
28390+ } else {
28391+ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
28392+ error = -EPERM;
28393+ }
28394+ break;
28395+ case GR_SEGVMOD:
28396+ if (unlikely(!(gr_status & GR_READY))) {
28397+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
28398+ error = -EAGAIN;
28399+ break;
28400+ }
28401+
28402+ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
28403+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
28404+ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
28405+ struct acl_subject_label *segvacl;
28406+ segvacl =
28407+ lookup_acl_subj_label(gr_usermode->segv_inode,
28408+ gr_usermode->segv_device,
28409+ current->role);
28410+ if (segvacl) {
28411+ segvacl->crashes = 0;
28412+ segvacl->expires = 0;
28413+ }
28414+ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
28415+ gr_remove_uid(gr_usermode->segv_uid);
28416+ }
28417+ } else {
28418+ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
28419+ error = -EPERM;
28420+ }
28421+ break;
28422+ case GR_SPROLE:
28423+ case GR_SPROLEPAM:
28424+ if (unlikely(!(gr_status & GR_READY))) {
28425+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
28426+ error = -EAGAIN;
28427+ break;
28428+ }
28429+
28430+ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
28431+ current->role->expires = 0;
28432+ current->role->auth_attempts = 0;
28433+ }
28434+
28435+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
28436+ time_after(current->role->expires, get_seconds())) {
28437+ error = -EBUSY;
28438+ goto out;
28439+ }
28440+
28441+ if (lookup_special_role_auth
28442+ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
28443+ && ((!sprole_salt && !sprole_sum)
28444+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
28445+ char *p = "";
28446+ assign_special_role(gr_usermode->sp_role);
28447+ read_lock(&tasklist_lock);
28448+ if (current->parent)
28449+ p = current->parent->role->rolename;
28450+ read_unlock(&tasklist_lock);
28451+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
28452+ p, acl_sp_role_value);
28453+ } else {
28454+ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
28455+ error = -EPERM;
28456+ if(!(current->role->auth_attempts++))
28457+ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
28458+
28459+ goto out;
28460+ }
28461+ break;
28462+ case GR_UNSPROLE:
28463+ if (unlikely(!(gr_status & GR_READY))) {
28464+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
28465+ error = -EAGAIN;
28466+ break;
28467+ }
28468+
28469+ if (current->role->roletype & GR_ROLE_SPECIAL) {
28470+ char *p = "";
28471+ int i = 0;
28472+
28473+ read_lock(&tasklist_lock);
28474+ if (current->parent) {
28475+ p = current->parent->role->rolename;
28476+ i = current->parent->acl_role_id;
28477+ }
28478+ read_unlock(&tasklist_lock);
28479+
28480+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
28481+ gr_set_acls(1);
28482+ } else {
28483+ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
28484+ error = -EPERM;
28485+ goto out;
28486+ }
28487+ break;
28488+ default:
28489+ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
28490+ error = -EINVAL;
28491+ break;
28492+ }
28493+
28494+ if (error != -EPERM)
28495+ goto out;
28496+
28497+ if(!(gr_auth_attempts++))
28498+ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
28499+
28500+ out:
28501+ up(&gr_dev_sem);
28502+ return error;
28503+}
28504+
28505+int
28506+gr_set_acls(const int type)
28507+{
28508+ struct acl_object_label *obj;
28509+ struct task_struct *task, *task2;
28510+ struct file *filp;
28511+ struct acl_role_label *role = current->role;
28512+ __u16 acl_role_id = current->acl_role_id;
28513+ const struct cred *cred;
de855c5d
AM
28514+ char *tmpname;
28515+ struct name_entry *nmatch;
28516+ struct acl_subject_label *tmpsubj;
2380c486
JR
28517+
28518+ read_lock(&tasklist_lock);
28519+ read_lock(&grsec_exec_file_lock);
28520+ do_each_thread(task2, task) {
28521+ /* check to see if we're called from the exit handler,
28522+ if so, only replace ACLs that have inherited the admin
28523+ ACL */
28524+
28525+ if (type && (task->role != role ||
28526+ task->acl_role_id != acl_role_id))
28527+ continue;
28528+
28529+ task->acl_role_id = 0;
28530+ task->acl_sp_role = 0;
28531+
28532+ if ((filp = task->exec_file)) {
28533+ cred = __task_cred(task);
28534+ task->role = lookup_acl_role_label(task, cred->uid, cred->gid);
28535+
de855c5d
AM
28536+ /* the following is to apply the correct subject
28537+ on binaries running when the RBAC system
28538+ is enabled, when the binaries have been
28539+ replaced or deleted since their execution
28540+ -----
28541+ when the RBAC system starts, the inode/dev
28542+ from exec_file will be one the RBAC system
28543+ is unaware of. It only knows the inode/dev
28544+ of the present file on disk, or the absence
28545+ of it.
28546+ */
28547+ preempt_disable();
28548+ tmpname = gr_to_filename_rbac(filp->f_path.dentry, filp->f_path.mnt);
28549+
28550+ nmatch = lookup_name_entry(tmpname);
28551+ preempt_enable();
28552+ tmpsubj = NULL;
28553+ if (nmatch) {
28554+ if (nmatch->deleted)
28555+ tmpsubj = lookup_acl_subj_label_deleted(nmatch->inode, nmatch->device, task->role);
28556+ else
28557+ tmpsubj = lookup_acl_subj_label(nmatch->inode, nmatch->device, task->role);
28558+ if (tmpsubj != NULL)
28559+ task->acl = tmpsubj;
28560+ }
28561+ if (tmpsubj == NULL)
28562+ task->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
28563+ task->role);
2380c486
JR
28564+ if (task->acl) {
28565+ struct acl_subject_label *curr;
28566+ curr = task->acl;
28567+
28568+ task->is_writable = 0;
28569+ /* ignore additional mmap checks for processes that are writable
28570+ by the default ACL */
28571+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
28572+ if (unlikely(obj->mode & GR_WRITE))
28573+ task->is_writable = 1;
28574+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
28575+ if (unlikely(obj->mode & GR_WRITE))
28576+ task->is_writable = 1;
28577+
28578+ gr_set_proc_res(task);
28579+
28580+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
28581+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
28582+#endif
28583+ } else {
28584+ read_unlock(&grsec_exec_file_lock);
28585+ read_unlock(&tasklist_lock);
28586+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
28587+ return 1;
28588+ }
28589+ } else {
28590+ // it's a kernel process
28591+ task->role = kernel_role;
28592+ task->acl = kernel_role->root_label;
28593+#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
28594+ task->acl->mode &= ~GR_PROCFIND;
28595+#endif
28596+ }
28597+ } while_each_thread(task2, task);
28598+ read_unlock(&grsec_exec_file_lock);
28599+ read_unlock(&tasklist_lock);
28600+ return 0;
28601+}
28602+
28603+void
28604+gr_learn_resource(const struct task_struct *task,
28605+ const int res, const unsigned long wanted, const int gt)
28606+{
28607+ struct acl_subject_label *acl;
de855c5d 28608+ const struct cred *cred;
2380c486
JR
28609+
28610+ if (unlikely((gr_status & GR_READY) &&
28611+ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
28612+ goto skip_reslog;
28613+
28614+#ifdef CONFIG_GRKERNSEC_RESLOG
28615+ gr_log_resource(task, res, wanted, gt);
28616+#endif
28617+ skip_reslog:
28618+
28619+ if (unlikely(!(gr_status & GR_READY) || !wanted || res >= GR_NLIMITS))
28620+ return;
28621+
28622+ acl = task->acl;
28623+
28624+ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
28625+ !(acl->resmask & (1 << (unsigned short) res))))
28626+ return;
28627+
28628+ if (wanted >= acl->res[res].rlim_cur) {
28629+ unsigned long res_add;
28630+
28631+ res_add = wanted;
28632+ switch (res) {
28633+ case RLIMIT_CPU:
28634+ res_add += GR_RLIM_CPU_BUMP;
28635+ break;
28636+ case RLIMIT_FSIZE:
28637+ res_add += GR_RLIM_FSIZE_BUMP;
28638+ break;
28639+ case RLIMIT_DATA:
28640+ res_add += GR_RLIM_DATA_BUMP;
28641+ break;
28642+ case RLIMIT_STACK:
28643+ res_add += GR_RLIM_STACK_BUMP;
28644+ break;
28645+ case RLIMIT_CORE:
28646+ res_add += GR_RLIM_CORE_BUMP;
28647+ break;
28648+ case RLIMIT_RSS:
28649+ res_add += GR_RLIM_RSS_BUMP;
28650+ break;
28651+ case RLIMIT_NPROC:
28652+ res_add += GR_RLIM_NPROC_BUMP;
28653+ break;
28654+ case RLIMIT_NOFILE:
28655+ res_add += GR_RLIM_NOFILE_BUMP;
28656+ break;
28657+ case RLIMIT_MEMLOCK:
28658+ res_add += GR_RLIM_MEMLOCK_BUMP;
28659+ break;
28660+ case RLIMIT_AS:
28661+ res_add += GR_RLIM_AS_BUMP;
28662+ break;
28663+ case RLIMIT_LOCKS:
28664+ res_add += GR_RLIM_LOCKS_BUMP;
28665+ break;
28666+ case RLIMIT_SIGPENDING:
28667+ res_add += GR_RLIM_SIGPENDING_BUMP;
28668+ break;
28669+ case RLIMIT_MSGQUEUE:
28670+ res_add += GR_RLIM_MSGQUEUE_BUMP;
28671+ break;
28672+ case RLIMIT_NICE:
28673+ res_add += GR_RLIM_NICE_BUMP;
28674+ break;
28675+ case RLIMIT_RTPRIO:
28676+ res_add += GR_RLIM_RTPRIO_BUMP;
28677+ break;
28678+ case RLIMIT_RTTIME:
28679+ res_add += GR_RLIM_RTTIME_BUMP;
28680+ break;
28681+ }
28682+
28683+ acl->res[res].rlim_cur = res_add;
28684+
28685+ if (wanted > acl->res[res].rlim_max)
28686+ acl->res[res].rlim_max = res_add;
28687+
de855c5d
AM
28688+ /* only log the subject filename, since resource logging is supported for
28689+ single-subject learning only */
28690+ cred = __task_cred(task);
2380c486 28691+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
de855c5d
AM
28692+ task->role->roletype, cred->uid, cred->gid, acl->filename,
28693+ acl->filename, acl->res[res].rlim_cur, acl->res[res].rlim_max,
28694+ "", (unsigned long) res, NIPQUAD(task->signal->curr_ip));
2380c486
JR
28695+ }
28696+
28697+ return;
28698+}
28699+
de855c5d 28700+#if defined(CONFIG_PAX_HAVE_ACL_FLAGS) && (defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR))
2380c486
JR
28701+void
28702+pax_set_initial_flags(struct linux_binprm *bprm)
28703+{
28704+ struct task_struct *task = current;
28705+ struct acl_subject_label *proc;
28706+ unsigned long flags;
28707+
28708+ if (unlikely(!(gr_status & GR_READY)))
28709+ return;
28710+
28711+ flags = pax_get_flags(task);
28712+
28713+ proc = task->acl;
28714+
28715+ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
28716+ flags &= ~MF_PAX_PAGEEXEC;
28717+ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
28718+ flags &= ~MF_PAX_SEGMEXEC;
28719+ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
28720+ flags &= ~MF_PAX_RANDMMAP;
28721+ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
28722+ flags &= ~MF_PAX_EMUTRAMP;
28723+ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
28724+ flags &= ~MF_PAX_MPROTECT;
28725+
28726+ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
28727+ flags |= MF_PAX_PAGEEXEC;
28728+ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
28729+ flags |= MF_PAX_SEGMEXEC;
28730+ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
28731+ flags |= MF_PAX_RANDMMAP;
28732+ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
28733+ flags |= MF_PAX_EMUTRAMP;
28734+ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
28735+ flags |= MF_PAX_MPROTECT;
28736+
28737+ pax_set_flags(task, flags);
28738+
28739+ return;
28740+}
28741+#endif
28742+
28743+#ifdef CONFIG_SYSCTL
28744+/* Eric Biederman likes breaking userland ABI and every inode-based security
28745+ system to save 35kb of memory */
28746+
28747+/* we modify the passed in filename, but adjust it back before returning */
28748+static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
28749+{
28750+ struct name_entry *nmatch;
28751+ char *p, *lastp = NULL;
28752+ struct acl_object_label *obj = NULL, *tmp;
28753+ struct acl_subject_label *tmpsubj;
28754+ char c = '\0';
28755+
28756+ read_lock(&gr_inode_lock);
28757+
28758+ p = name + len - 1;
28759+ do {
28760+ nmatch = lookup_name_entry(name);
28761+ if (lastp != NULL)
28762+ *lastp = c;
28763+
28764+ if (nmatch == NULL)
28765+ goto next_component;
28766+ tmpsubj = current->acl;
28767+ do {
28768+ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
28769+ if (obj != NULL) {
28770+ tmp = obj->globbed;
28771+ while (tmp) {
28772+ if (!glob_match(tmp->filename, name)) {
28773+ obj = tmp;
28774+ goto found_obj;
28775+ }
28776+ tmp = tmp->next;
28777+ }
28778+ goto found_obj;
28779+ }
28780+ } while ((tmpsubj = tmpsubj->parent_subject));
28781+next_component:
28782+ /* end case */
28783+ if (p == name)
28784+ break;
28785+
28786+ while (*p != '/')
28787+ p--;
28788+ if (p == name)
28789+ lastp = p + 1;
28790+ else {
28791+ lastp = p;
28792+ p--;
28793+ }
28794+ c = *lastp;
28795+ *lastp = '\0';
28796+ } while (1);
28797+found_obj:
28798+ read_unlock(&gr_inode_lock);
28799+ /* obj returned will always be non-null */
28800+ return obj;
28801+}
28802+
28803+/* returns 0 when allowing, non-zero on error
28804+ op of 0 is used for readdir, so we don't log the names of hidden files
28805+*/
28806+__u32
28807+gr_handle_sysctl(const struct ctl_table *table, const int op)
28808+{
28809+ ctl_table *tmp;
28810+ const char *proc_sys = "/proc/sys";
28811+ char *path;
28812+ struct acl_object_label *obj;
28813+ unsigned short len = 0, pos = 0, depth = 0, i;
28814+ __u32 err = 0;
28815+ __u32 mode = 0;
28816+
28817+ if (unlikely(!(gr_status & GR_READY)))
28818+ return 0;
28819+
28820+ /* for now, ignore operations on non-sysctl entries if it's not a
28821+ readdir*/
28822+ if (table->child != NULL && op != 0)
28823+ return 0;
28824+
28825+ mode |= GR_FIND;
28826+ /* it's only a read if it's an entry, read on dirs is for readdir */
28827+ if (op & MAY_READ)
28828+ mode |= GR_READ;
28829+ if (op & MAY_WRITE)
28830+ mode |= GR_WRITE;
28831+
28832+ preempt_disable();
28833+
28834+ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
28835+
28836+ /* it's only a read/write if it's an actual entry, not a dir
28837+ (which are opened for readdir)
28838+ */
28839+
28840+ /* convert the requested sysctl entry into a pathname */
28841+
28842+ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
28843+ len += strlen(tmp->procname);
28844+ len++;
28845+ depth++;
28846+ }
28847+
28848+ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
28849+ /* deny */
28850+ goto out;
28851+ }
28852+
28853+ memset(path, 0, PAGE_SIZE);
28854+
28855+ memcpy(path, proc_sys, strlen(proc_sys));
28856+
28857+ pos += strlen(proc_sys);
28858+
28859+ for (; depth > 0; depth--) {
28860+ path[pos] = '/';
28861+ pos++;
28862+ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
28863+ if (depth == i) {
28864+ memcpy(path + pos, tmp->procname,
28865+ strlen(tmp->procname));
28866+ pos += strlen(tmp->procname);
28867+ }
28868+ i++;
28869+ }
28870+ }
28871+
28872+ obj = gr_lookup_by_name(path, pos);
28873+ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
28874+
28875+ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
28876+ ((err & mode) != mode))) {
28877+ __u32 new_mode = mode;
28878+
28879+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
28880+
28881+ err = 0;
28882+ gr_log_learn_sysctl(path, new_mode);
28883+ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
28884+ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
28885+ err = -ENOENT;
28886+ } else if (!(err & GR_FIND)) {
28887+ err = -ENOENT;
28888+ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
28889+ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
28890+ path, (mode & GR_READ) ? " reading" : "",
28891+ (mode & GR_WRITE) ? " writing" : "");
28892+ err = -EACCES;
28893+ } else if ((err & mode) != mode) {
28894+ err = -EACCES;
28895+ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
28896+ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
28897+ path, (mode & GR_READ) ? " reading" : "",
28898+ (mode & GR_WRITE) ? " writing" : "");
28899+ err = 0;
28900+ } else
28901+ err = 0;
28902+
28903+ out:
28904+ preempt_enable();
28905+
28906+ return err;
28907+}
28908+#endif
28909+
28910+int
28911+gr_handle_proc_ptrace(struct task_struct *task)
28912+{
28913+ struct file *filp;
28914+ struct task_struct *tmp = task;
28915+ struct task_struct *curtemp = current;
28916+ __u32 retmode;
28917+
28918+ if (unlikely(!(gr_status & GR_READY)))
28919+ return 0;
28920+
28921+ read_lock(&tasklist_lock);
28922+ read_lock(&grsec_exec_file_lock);
28923+ filp = task->exec_file;
28924+
28925+ while (tmp->pid > 0) {
28926+ if (tmp == curtemp)
28927+ break;
28928+ tmp = tmp->parent;
28929+ }
28930+
28931+ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
28932+ read_unlock(&grsec_exec_file_lock);
28933+ read_unlock(&tasklist_lock);
28934+ return 1;
28935+ }
28936+
28937+ retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
28938+ read_unlock(&grsec_exec_file_lock);
28939+ read_unlock(&tasklist_lock);
28940+
28941+ if (retmode & GR_NOPTRACE)
28942+ return 1;
28943+
28944+ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
28945+ && (current->acl != task->acl || (current->acl != current->role->root_label
28946+ && current->pid != task->pid)))
28947+ return 1;
28948+
28949+ return 0;
28950+}
28951+
28952+int
28953+gr_handle_ptrace(struct task_struct *task, const long request)
28954+{
28955+ struct task_struct *tmp = task;
28956+ struct task_struct *curtemp = current;
28957+ __u32 retmode;
28958+
28959+ if (unlikely(!(gr_status & GR_READY)))
28960+ return 0;
28961+
28962+ read_lock(&tasklist_lock);
28963+ while (tmp->pid > 0) {
28964+ if (tmp == curtemp)
28965+ break;
28966+ tmp = tmp->parent;
28967+ }
28968+
28969+ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
28970+ read_unlock(&tasklist_lock);
28971+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
28972+ return 1;
28973+ }
28974+ read_unlock(&tasklist_lock);
28975+
28976+ read_lock(&grsec_exec_file_lock);
28977+ if (unlikely(!task->exec_file)) {
28978+ read_unlock(&grsec_exec_file_lock);
28979+ return 0;
28980+ }
28981+
28982+ retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
28983+ read_unlock(&grsec_exec_file_lock);
28984+
28985+ if (retmode & GR_NOPTRACE) {
28986+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
28987+ return 1;
28988+ }
28989+
28990+ if (retmode & GR_PTRACERD) {
28991+ switch (request) {
28992+ case PTRACE_POKETEXT:
28993+ case PTRACE_POKEDATA:
28994+ case PTRACE_POKEUSR:
28995+#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
28996+ case PTRACE_SETREGS:
28997+ case PTRACE_SETFPREGS:
28998+#endif
28999+#ifdef CONFIG_X86
29000+ case PTRACE_SETFPXREGS:
29001+#endif
29002+#ifdef CONFIG_ALTIVEC
29003+ case PTRACE_SETVRREGS:
29004+#endif
29005+ return 1;
29006+ default:
29007+ return 0;
29008+ }
29009+ } else if (!(current->acl->mode & GR_POVERRIDE) &&
29010+ !(current->role->roletype & GR_ROLE_GOD) &&
29011+ (current->acl != task->acl)) {
29012+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
29013+ return 1;
29014+ }
29015+
29016+ return 0;
29017+}
29018+
29019+static int is_writable_mmap(const struct file *filp)
29020+{
29021+ struct task_struct *task = current;
29022+ struct acl_object_label *obj, *obj2;
29023+
29024+ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
29025+ !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
29026+ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
29027+ obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
29028+ task->role->root_label);
29029+ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
29030+ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
29031+ return 1;
29032+ }
29033+ }
29034+ return 0;
29035+}
29036+
29037+int
29038+gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
29039+{
29040+ __u32 mode;
29041+
29042+ if (unlikely(!file || !(prot & PROT_EXEC)))
29043+ return 1;
29044+
29045+ if (is_writable_mmap(file))
29046+ return 0;
29047+
29048+ mode =
29049+ gr_search_file(file->f_path.dentry,
29050+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
29051+ file->f_path.mnt);
29052+
29053+ if (!gr_tpe_allow(file))
29054+ return 0;
29055+
29056+ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
29057+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
29058+ return 0;
29059+ } else if (unlikely(!(mode & GR_EXEC))) {
29060+ return 0;
29061+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
29062+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
29063+ return 1;
29064+ }
29065+
29066+ return 1;
29067+}
29068+
29069+int
29070+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
29071+{
29072+ __u32 mode;
29073+
29074+ if (unlikely(!file || !(prot & PROT_EXEC)))
29075+ return 1;
29076+
29077+ if (is_writable_mmap(file))
29078+ return 0;
29079+
29080+ mode =
29081+ gr_search_file(file->f_path.dentry,
29082+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
29083+ file->f_path.mnt);
29084+
29085+ if (!gr_tpe_allow(file))
29086+ return 0;
29087+
29088+ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
29089+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
29090+ return 0;
29091+ } else if (unlikely(!(mode & GR_EXEC))) {
29092+ return 0;
29093+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
29094+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
29095+ return 1;
29096+ }
29097+
29098+ return 1;
29099+}
29100+
29101+void
29102+gr_acl_handle_psacct(struct task_struct *task, const long code)
29103+{
29104+ unsigned long runtime;
29105+ unsigned long cputime;
29106+ unsigned int wday, cday;
29107+ __u8 whr, chr;
29108+ __u8 wmin, cmin;
29109+ __u8 wsec, csec;
29110+ struct timespec timeval;
29111+
29112+ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
29113+ !(task->acl->mode & GR_PROCACCT)))
29114+ return;
29115+
29116+ do_posix_clock_monotonic_gettime(&timeval);
29117+ runtime = timeval.tv_sec - task->start_time.tv_sec;
29118+ wday = runtime / (3600 * 24);
29119+ runtime -= wday * (3600 * 24);
29120+ whr = runtime / 3600;
29121+ runtime -= whr * 3600;
29122+ wmin = runtime / 60;
29123+ runtime -= wmin * 60;
29124+ wsec = runtime;
29125+
29126+ cputime = (task->utime + task->stime) / HZ;
29127+ cday = cputime / (3600 * 24);
29128+ cputime -= cday * (3600 * 24);
29129+ chr = cputime / 3600;
29130+ cputime -= chr * 3600;
29131+ cmin = cputime / 60;
29132+ cputime -= cmin * 60;
29133+ csec = cputime;
29134+
29135+ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
29136+
29137+ return;
29138+}
29139+
29140+void gr_set_kernel_label(struct task_struct *task)
29141+{
29142+ if (gr_status & GR_READY) {
29143+ task->role = kernel_role;
29144+ task->acl = kernel_role->root_label;
29145+ }
29146+ return;
29147+}
29148+
de855c5d
AM
29149+#ifdef CONFIG_TASKSTATS
29150+int gr_is_taskstats_denied(int pid)
29151+{
29152+ struct task_struct *task;
017d2877 29153+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
de855c5d 29154+ const struct cred *cred;
017d2877 29155+#endif
de855c5d
AM
29156+ int ret = 0;
29157+
29158+ /* restrict taskstats viewing to un-chrooted root users
29159+ who have the 'view' subject flag if the RBAC system is enabled
29160+ */
29161+
29162+ read_lock(&tasklist_lock);
29163+ task = find_task_by_vpid(pid);
29164+ if (task) {
29165+ task_lock(task);
29166+#ifdef CONFIG_GRKERNSEC_CHROOT
29167+ if (proc_is_chrooted(task))
29168+ ret = -EACCES;
29169+#endif
29170+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
29171+ cred = __task_cred(task);
29172+#ifdef CONFIG_GRKERNSEC_PROC_USER
29173+ if (cred->uid != 0)
29174+ ret = -EACCES;
29175+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
29176+ if (cred->uid != 0 && !groups_search(cred->group_info, CONFIG_GRKERNSEC_PROC_GID))
29177+ ret = -EACCES;
29178+#endif
29179+#endif
29180+ if (gr_status & GR_READY) {
29181+ if (!(task->acl->mode & GR_VIEW))
29182+ ret = -EACCES;
29183+ }
29184+
29185+ task_unlock(task);
29186+ } else
29187+ ret = -ENOENT;
29188+
29189+ read_unlock(&tasklist_lock);
29190+
29191+ return ret;
29192+}
29193+#endif
29194+
2380c486
JR
29195+int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
29196+{
29197+ struct task_struct *task = current;
29198+ struct dentry *dentry = file->f_path.dentry;
29199+ struct vfsmount *mnt = file->f_path.mnt;
29200+ struct acl_object_label *obj, *tmp;
29201+ struct acl_subject_label *subj;
29202+ unsigned int bufsize;
29203+ int is_not_root;
29204+ char *path;
29205+
29206+ if (unlikely(!(gr_status & GR_READY)))
29207+ return 1;
29208+
29209+ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
29210+ return 1;
29211+
29212+ /* ignore Eric Biederman */
29213+ if (IS_PRIVATE(dentry->d_inode))
29214+ return 1;
29215+
29216+ subj = task->acl;
29217+ do {
29218+ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
29219+ if (obj != NULL)
29220+ return (obj->mode & GR_FIND) ? 1 : 0;
29221+ } while ((subj = subj->parent_subject));
29222+
de855c5d
AM
29223+ /* this is purely an optimization since we're looking for an object
29224+ for the directory we're doing a readdir on
29225+ if it's possible for any globbed object to match the entry we're
29226+ filling into the directory, then the object we find here will be
29227+ an anchor point with attached globbed objects
29228+ */
29229+ obj = chk_obj_label_noglob(dentry, mnt, task->acl);
2380c486
JR
29230+ if (obj->globbed == NULL)
29231+ return (obj->mode & GR_FIND) ? 1 : 0;
29232+
29233+ is_not_root = ((obj->filename[0] == '/') &&
29234+ (obj->filename[1] == '\0')) ? 0 : 1;
29235+ bufsize = PAGE_SIZE - namelen - is_not_root;
29236+
29237+ /* check bufsize > PAGE_SIZE || bufsize == 0 */
29238+ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
29239+ return 1;
29240+
29241+ preempt_disable();
29242+ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
29243+ bufsize);
29244+
29245+ bufsize = strlen(path);
29246+
29247+ /* if base is "/", don't append an additional slash */
29248+ if (is_not_root)
29249+ *(path + bufsize) = '/';
29250+ memcpy(path + bufsize + is_not_root, name, namelen);
29251+ *(path + bufsize + namelen + is_not_root) = '\0';
29252+
29253+ tmp = obj->globbed;
29254+ while (tmp) {
29255+ if (!glob_match(tmp->filename, path)) {
29256+ preempt_enable();
29257+ return (tmp->mode & GR_FIND) ? 1 : 0;
29258+ }
29259+ tmp = tmp->next;
29260+ }
29261+ preempt_enable();
29262+ return (obj->mode & GR_FIND) ? 1 : 0;
29263+}
29264+
29265+EXPORT_SYMBOL(gr_learn_resource);
29266+EXPORT_SYMBOL(gr_set_kernel_label);
29267+#ifdef CONFIG_SECURITY
29268+EXPORT_SYMBOL(gr_check_user_change);
29269+EXPORT_SYMBOL(gr_check_group_change);
29270+#endif
29271+
017d2877
AM
29272diff -urNp linux-2.6.30.4/grsecurity/gracl_cap.c linux-2.6.30.4/grsecurity/gracl_cap.c
29273--- linux-2.6.30.4/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
29274+++ linux-2.6.30.4/grsecurity/gracl_cap.c 2009-07-30 11:10:49.347341041 -0400
2380c486
JR
29275@@ -0,0 +1,131 @@
29276+#include <linux/kernel.h>
29277+#include <linux/module.h>
29278+#include <linux/sched.h>
29279+#include <linux/gracl.h>
29280+#include <linux/grsecurity.h>
29281+#include <linux/grinternal.h>
29282+
29283+static const char *captab_log[] = {
29284+ "CAP_CHOWN",
29285+ "CAP_DAC_OVERRIDE",
29286+ "CAP_DAC_READ_SEARCH",
29287+ "CAP_FOWNER",
29288+ "CAP_FSETID",
29289+ "CAP_KILL",
29290+ "CAP_SETGID",
29291+ "CAP_SETUID",
29292+ "CAP_SETPCAP",
29293+ "CAP_LINUX_IMMUTABLE",
29294+ "CAP_NET_BIND_SERVICE",
29295+ "CAP_NET_BROADCAST",
29296+ "CAP_NET_ADMIN",
29297+ "CAP_NET_RAW",
29298+ "CAP_IPC_LOCK",
29299+ "CAP_IPC_OWNER",
29300+ "CAP_SYS_MODULE",
29301+ "CAP_SYS_RAWIO",
29302+ "CAP_SYS_CHROOT",
29303+ "CAP_SYS_PTRACE",
29304+ "CAP_SYS_PACCT",
29305+ "CAP_SYS_ADMIN",
29306+ "CAP_SYS_BOOT",
29307+ "CAP_SYS_NICE",
29308+ "CAP_SYS_RESOURCE",
29309+ "CAP_SYS_TIME",
29310+ "CAP_SYS_TTY_CONFIG",
29311+ "CAP_MKNOD",
29312+ "CAP_LEASE",
29313+ "CAP_AUDIT_WRITE",
29314+ "CAP_AUDIT_CONTROL",
29315+ "CAP_SETFCAP",
29316+ "CAP_MAC_OVERRIDE",
29317+ "CAP_MAC_ADMIN"
29318+};
29319+
29320+EXPORT_SYMBOL(gr_is_capable);
29321+EXPORT_SYMBOL(gr_is_capable_nolog);
29322+
29323+int
29324+gr_is_capable(const int cap)
29325+{
29326+ struct task_struct *task = current;
29327+ const struct cred *cred = current_cred();
29328+ struct acl_subject_label *curracl;
29329+ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
29330+
29331+ if (!gr_acl_is_enabled())
29332+ return 1;
29333+
29334+ curracl = task->acl;
29335+
29336+ cap_drop = curracl->cap_lower;
29337+ cap_mask = curracl->cap_mask;
29338+
29339+ while ((curracl = curracl->parent_subject)) {
29340+ /* if the cap isn't specified in the current computed mask but is specified in the
29341+ current level subject, and is lowered in the current level subject, then add
29342+ it to the set of dropped capabilities
29343+ otherwise, add the current level subject's mask to the current computed mask
29344+ */
29345+ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
29346+ cap_raise(cap_mask, cap);
29347+ if (cap_raised(curracl->cap_lower, cap))
29348+ cap_raise(cap_drop, cap);
29349+ }
29350+ }
29351+
29352+ if (!cap_raised(cap_drop, cap))
29353+ return 1;
29354+
29355+ curracl = task->acl;
29356+
29357+ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
29358+ && cap_raised(cred->cap_effective, cap)) {
29359+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
29360+ task->role->roletype, cred->uid,
29361+ cred->gid, task->exec_file ?
29362+ gr_to_filename(task->exec_file->f_path.dentry,
29363+ task->exec_file->f_path.mnt) : curracl->filename,
29364+ curracl->filename, 0UL,
29365+ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
29366+ return 1;
29367+ }
29368+
29369+ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(cred->cap_effective, cap))
29370+ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
29371+ return 0;
29372+}
29373+
29374+int
29375+gr_is_capable_nolog(const int cap)
29376+{
29377+ struct acl_subject_label *curracl;
29378+ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
29379+
29380+ if (!gr_acl_is_enabled())
29381+ return 1;
29382+
29383+ curracl = current->acl;
29384+
29385+ cap_drop = curracl->cap_lower;
29386+ cap_mask = curracl->cap_mask;
29387+
29388+ while ((curracl = curracl->parent_subject)) {
29389+ /* if the cap isn't specified in the current computed mask but is specified in the
29390+ current level subject, and is lowered in the current level subject, then add
29391+ it to the set of dropped capabilities
29392+ otherwise, add the current level subject's mask to the current computed mask
29393+ */
29394+ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
29395+ cap_raise(cap_mask, cap);
29396+ if (cap_raised(curracl->cap_lower, cap))
29397+ cap_raise(cap_drop, cap);
29398+ }
29399+ }
29400+
29401+ if (!cap_raised(cap_drop, cap))
29402+ return 1;
29403+
29404+ return 0;
29405+}
29406+
017d2877
AM
29407diff -urNp linux-2.6.30.4/grsecurity/gracl_fs.c linux-2.6.30.4/grsecurity/gracl_fs.c
29408--- linux-2.6.30.4/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
29409+++ linux-2.6.30.4/grsecurity/gracl_fs.c 2009-07-30 11:10:49.347341041 -0400
2380c486
JR
29410@@ -0,0 +1,423 @@
29411+#include <linux/kernel.h>
29412+#include <linux/sched.h>
29413+#include <linux/types.h>
29414+#include <linux/fs.h>
29415+#include <linux/file.h>
29416+#include <linux/stat.h>
29417+#include <linux/grsecurity.h>
29418+#include <linux/grinternal.h>
29419+#include <linux/gracl.h>
29420+
29421+__u32
29422+gr_acl_handle_hidden_file(const struct dentry * dentry,
29423+ const struct vfsmount * mnt)
29424+{
29425+ __u32 mode;
29426+
29427+ if (unlikely(!dentry->d_inode))
29428+ return GR_FIND;
29429+
29430+ mode =
29431+ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
29432+
29433+ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
29434+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
29435+ return mode;
29436+ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
29437+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
29438+ return 0;
29439+ } else if (unlikely(!(mode & GR_FIND)))
29440+ return 0;
29441+
29442+ return GR_FIND;
29443+}
29444+
29445+__u32
29446+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
29447+ const int fmode)
29448+{
29449+ __u32 reqmode = GR_FIND;
29450+ __u32 mode;
29451+
29452+ if (unlikely(!dentry->d_inode))
29453+ return reqmode;
29454+
29455+ if (unlikely(fmode & O_APPEND))
29456+ reqmode |= GR_APPEND;
29457+ else if (unlikely(fmode & FMODE_WRITE))
29458+ reqmode |= GR_WRITE;
29459+ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
29460+ reqmode |= GR_READ;
29461+
29462+ mode =
29463+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
29464+ mnt);
29465+
29466+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
29467+ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
29468+ reqmode & GR_READ ? " reading" : "",
29469+ reqmode & GR_WRITE ? " writing" : reqmode &
29470+ GR_APPEND ? " appending" : "");
29471+ return reqmode;
29472+ } else
29473+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
29474+ {
29475+ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
29476+ reqmode & GR_READ ? " reading" : "",
29477+ reqmode & GR_WRITE ? " writing" : reqmode &
29478+ GR_APPEND ? " appending" : "");
29479+ return 0;
29480+ } else if (unlikely((mode & reqmode) != reqmode))
29481+ return 0;
29482+
29483+ return reqmode;
29484+}
29485+
29486+__u32
29487+gr_acl_handle_creat(const struct dentry * dentry,
29488+ const struct dentry * p_dentry,
29489+ const struct vfsmount * p_mnt, const int fmode,
29490+ const int imode)
29491+{
29492+ __u32 reqmode = GR_WRITE | GR_CREATE;
29493+ __u32 mode;
29494+
29495+ if (unlikely(fmode & O_APPEND))
29496+ reqmode |= GR_APPEND;
29497+ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
29498+ reqmode |= GR_READ;
29499+ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
29500+ reqmode |= GR_SETID;
29501+
29502+ mode =
29503+ gr_check_create(dentry, p_dentry, p_mnt,
29504+ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
29505+
29506+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
29507+ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
29508+ reqmode & GR_READ ? " reading" : "",
29509+ reqmode & GR_WRITE ? " writing" : reqmode &
29510+ GR_APPEND ? " appending" : "");
29511+ return reqmode;
29512+ } else
29513+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
29514+ {
29515+ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
29516+ reqmode & GR_READ ? " reading" : "",
29517+ reqmode & GR_WRITE ? " writing" : reqmode &
29518+ GR_APPEND ? " appending" : "");
29519+ return 0;
29520+ } else if (unlikely((mode & reqmode) != reqmode))
29521+ return 0;
29522+
29523+ return reqmode;
29524+}
29525+
29526+__u32
29527+gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
29528+ const int fmode)
29529+{
29530+ __u32 mode, reqmode = GR_FIND;
29531+
29532+ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
29533+ reqmode |= GR_EXEC;
29534+ if (fmode & S_IWOTH)
29535+ reqmode |= GR_WRITE;
29536+ if (fmode & S_IROTH)
29537+ reqmode |= GR_READ;
29538+
29539+ mode =
29540+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
29541+ mnt);
29542+
29543+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
29544+ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
29545+ reqmode & GR_READ ? " reading" : "",
29546+ reqmode & GR_WRITE ? " writing" : "",
29547+ reqmode & GR_EXEC ? " executing" : "");
29548+ return reqmode;
29549+ } else
29550+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
29551+ {
29552+ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
29553+ reqmode & GR_READ ? " reading" : "",
29554+ reqmode & GR_WRITE ? " writing" : "",
29555+ reqmode & GR_EXEC ? " executing" : "");
29556+ return 0;
29557+ } else if (unlikely((mode & reqmode) != reqmode))
29558+ return 0;
29559+
29560+ return reqmode;
29561+}
29562+
29563+static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
29564+{
29565+ __u32 mode;
29566+
29567+ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
29568+
29569+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
29570+ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
29571+ return mode;
29572+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
29573+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
29574+ return 0;
29575+ } else if (unlikely((mode & (reqmode)) != (reqmode)))
29576+ return 0;
29577+
29578+ return (reqmode);
29579+}
29580+
29581+__u32
29582+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
29583+{
29584+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
29585+}
29586+
29587+__u32
29588+gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
29589+{
29590+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
29591+}
29592+
29593+__u32
29594+gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
29595+{
29596+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
29597+}
29598+
29599+__u32
29600+gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
29601+{
29602+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
29603+}
29604+
29605+__u32
29606+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
29607+ mode_t mode)
29608+{
29609+ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
29610+ return 1;
29611+
29612+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
29613+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
29614+ GR_FCHMOD_ACL_MSG);
29615+ } else {
29616+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
29617+ }
29618+}
29619+
29620+__u32
29621+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
29622+ mode_t mode)
29623+{
29624+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
29625+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
29626+ GR_CHMOD_ACL_MSG);
29627+ } else {
29628+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
29629+ }
29630+}
29631+
29632+__u32
29633+gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
29634+{
29635+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
29636+}
29637+
29638+__u32
29639+gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
29640+{
29641+ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
29642+}
29643+
29644+__u32
29645+gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
29646+{
29647+ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
29648+ GR_UNIXCONNECT_ACL_MSG);
29649+}
29650+
29651+/* hardlinks require at minimum create permission,
29652+ any additional privilege required is based on the
29653+ privilege of the file being linked to
29654+*/
29655+__u32
29656+gr_acl_handle_link(const struct dentry * new_dentry,
29657+ const struct dentry * parent_dentry,
29658+ const struct vfsmount * parent_mnt,
29659+ const struct dentry * old_dentry,
29660+ const struct vfsmount * old_mnt, const char *to)
29661+{
29662+ __u32 mode;
29663+ __u32 needmode = GR_CREATE | GR_LINK;
29664+ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
29665+
29666+ mode =
29667+ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
29668+ old_mnt);
29669+
29670+ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
29671+ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
29672+ return mode;
29673+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
29674+ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
29675+ return 0;
29676+ } else if (unlikely((mode & needmode) != needmode))
29677+ return 0;
29678+
29679+ return 1;
29680+}
29681+
29682+__u32
29683+gr_acl_handle_symlink(const struct dentry * new_dentry,
29684+ const struct dentry * parent_dentry,
29685+ const struct vfsmount * parent_mnt, const char *from)
29686+{
29687+ __u32 needmode = GR_WRITE | GR_CREATE;
29688+ __u32 mode;
29689+
29690+ mode =
29691+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
29692+ GR_CREATE | GR_AUDIT_CREATE |
29693+ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
29694+
29695+ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
29696+ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
29697+ return mode;
29698+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
29699+ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
29700+ return 0;
29701+ } else if (unlikely((mode & needmode) != needmode))
29702+ return 0;
29703+
29704+ return (GR_WRITE | GR_CREATE);
29705+}
29706+
29707+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)
29708+{
29709+ __u32 mode;
29710+
29711+ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
29712+
29713+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
29714+ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
29715+ return mode;
29716+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
29717+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
29718+ return 0;
29719+ } else if (unlikely((mode & (reqmode)) != (reqmode)))
29720+ return 0;
29721+
29722+ return (reqmode);
29723+}
29724+
29725+__u32
29726+gr_acl_handle_mknod(const struct dentry * new_dentry,
29727+ const struct dentry * parent_dentry,
29728+ const struct vfsmount * parent_mnt,
29729+ const int mode)
29730+{
29731+ __u32 reqmode = GR_WRITE | GR_CREATE;
29732+ if (unlikely(mode & (S_ISUID | S_ISGID)))
29733+ reqmode |= GR_SETID;
29734+
29735+ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
29736+ reqmode, GR_MKNOD_ACL_MSG);
29737+}
29738+
29739+__u32
29740+gr_acl_handle_mkdir(const struct dentry *new_dentry,
29741+ const struct dentry *parent_dentry,
29742+ const struct vfsmount *parent_mnt)
29743+{
29744+ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
29745+ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
29746+}
29747+
29748+#define RENAME_CHECK_SUCCESS(old, new) \
29749+ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
29750+ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
29751+
29752+int
29753+gr_acl_handle_rename(struct dentry *new_dentry,
29754+ struct dentry *parent_dentry,
29755+ const struct vfsmount *parent_mnt,
29756+ struct dentry *old_dentry,
29757+ struct inode *old_parent_inode,
29758+ struct vfsmount *old_mnt, const char *newname)
29759+{
29760+ __u32 comp1, comp2;
29761+ int error = 0;
29762+
29763+ if (unlikely(!gr_acl_is_enabled()))
29764+ return 0;
29765+
29766+ if (!new_dentry->d_inode) {
29767+ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
29768+ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
29769+ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
29770+ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
29771+ GR_DELETE | GR_AUDIT_DELETE |
29772+ GR_AUDIT_READ | GR_AUDIT_WRITE |
29773+ GR_SUPPRESS, old_mnt);
29774+ } else {
29775+ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
29776+ GR_CREATE | GR_DELETE |
29777+ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
29778+ GR_AUDIT_READ | GR_AUDIT_WRITE |
29779+ GR_SUPPRESS, parent_mnt);
29780+ comp2 =
29781+ gr_search_file(old_dentry,
29782+ GR_READ | GR_WRITE | GR_AUDIT_READ |
29783+ GR_DELETE | GR_AUDIT_DELETE |
29784+ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
29785+ }
29786+
29787+ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
29788+ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
29789+ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
29790+ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
29791+ && !(comp2 & GR_SUPPRESS)) {
29792+ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
29793+ error = -EACCES;
29794+ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
29795+ error = -EACCES;
29796+
29797+ return error;
29798+}
29799+
29800+void
29801+gr_acl_handle_exit(void)
29802+{
29803+ u16 id;
29804+ char *rolename;
29805+ struct file *exec_file;
29806+
29807+ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
29808+ id = current->acl_role_id;
29809+ rolename = current->role->rolename;
29810+ gr_set_acls(1);
29811+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
29812+ }
29813+
29814+ write_lock(&grsec_exec_file_lock);
29815+ exec_file = current->exec_file;
29816+ current->exec_file = NULL;
29817+ write_unlock(&grsec_exec_file_lock);
29818+
29819+ if (exec_file)
29820+ fput(exec_file);
29821+}
29822+
29823+int
29824+gr_acl_handle_procpidmem(const struct task_struct *task)
29825+{
29826+ if (unlikely(!gr_acl_is_enabled()))
29827+ return 0;
29828+
29829+ if (task != current && task->acl->mode & GR_PROTPROCFD)
29830+ return -EACCES;
29831+
29832+ return 0;
29833+}
017d2877
AM
29834diff -urNp linux-2.6.30.4/grsecurity/gracl_ip.c linux-2.6.30.4/grsecurity/gracl_ip.c
29835--- linux-2.6.30.4/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
29836+++ linux-2.6.30.4/grsecurity/gracl_ip.c 2009-07-30 11:10:49.347341041 -0400
2380c486
JR
29837@@ -0,0 +1,340 @@
29838+#include <linux/kernel.h>
29839+#include <asm/uaccess.h>
29840+#include <asm/errno.h>
29841+#include <net/sock.h>
29842+#include <linux/file.h>
29843+#include <linux/fs.h>
29844+#include <linux/net.h>
29845+#include <linux/in.h>
29846+#include <linux/skbuff.h>
29847+#include <linux/ip.h>
29848+#include <linux/udp.h>
29849+#include <linux/smp_lock.h>
29850+#include <linux/types.h>
29851+#include <linux/sched.h>
29852+#include <linux/netdevice.h>
29853+#include <linux/inetdevice.h>
29854+#include <linux/gracl.h>
29855+#include <linux/grsecurity.h>
29856+#include <linux/grinternal.h>
29857+
29858+#define GR_BIND 0x01
29859+#define GR_CONNECT 0x02
29860+#define GR_INVERT 0x04
29861+#define GR_BINDOVERRIDE 0x08
29862+#define GR_CONNECTOVERRIDE 0x10
29863+
29864+static const char * gr_protocols[256] = {
29865+ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
29866+ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
29867+ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
29868+ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
29869+ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
29870+ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
29871+ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
29872+ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
29873+ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
29874+ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
29875+ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
29876+ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
29877+ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
29878+ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
29879+ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
29880+ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
29881+ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
29882+ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
29883+ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
29884+ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
29885+ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
29886+ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
29887+ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
29888+ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
29889+ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
29890+ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
29891+ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
29892+ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
29893+ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
29894+ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
29895+ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
29896+ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
29897+ };
29898+
29899+static const char * gr_socktypes[11] = {
29900+ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
29901+ "unknown:7", "unknown:8", "unknown:9", "packet"
29902+ };
29903+
29904+const char *
29905+gr_proto_to_name(unsigned char proto)
29906+{
29907+ return gr_protocols[proto];
29908+}
29909+
29910+const char *
29911+gr_socktype_to_name(unsigned char type)
29912+{
29913+ return gr_socktypes[type];
29914+}
29915+
29916+int
29917+gr_search_socket(const int domain, const int type, const int protocol)
29918+{
29919+ struct acl_subject_label *curr;
29920+ const struct cred *cred = current_cred();
29921+
29922+ if (unlikely(!gr_acl_is_enabled()))
29923+ goto exit;
29924+
29925+ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
29926+ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
29927+ goto exit; // let the kernel handle it
29928+
29929+ curr = current->acl;
29930+
29931+ if (!curr->ips)
29932+ goto exit;
29933+
29934+ if ((curr->ip_type & (1 << type)) &&
29935+ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
29936+ goto exit;
29937+
29938+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
29939+ /* we don't place acls on raw sockets , and sometimes
29940+ dgram/ip sockets are opened for ioctl and not
29941+ bind/connect, so we'll fake a bind learn log */
29942+ if (type == SOCK_RAW || type == SOCK_PACKET) {
29943+ __u32 fakeip = 0;
29944+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
29945+ current->role->roletype, cred->uid,
29946+ cred->gid, current->exec_file ?
29947+ gr_to_filename(current->exec_file->f_path.dentry,
29948+ current->exec_file->f_path.mnt) :
29949+ curr->filename, curr->filename,
29950+ NIPQUAD(fakeip), 0, type,
29951+ protocol, GR_CONNECT,
29952+NIPQUAD(current->signal->curr_ip));
29953+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
29954+ __u32 fakeip = 0;
29955+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
29956+ current->role->roletype, cred->uid,
29957+ cred->gid, current->exec_file ?
29958+ gr_to_filename(current->exec_file->f_path.dentry,
29959+ current->exec_file->f_path.mnt) :
29960+ curr->filename, curr->filename,
29961+ NIPQUAD(fakeip), 0, type,
29962+ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
29963+ }
29964+ /* we'll log when they use connect or bind */
29965+ goto exit;
29966+ }
29967+
29968+ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
29969+ gr_socktype_to_name(type), gr_proto_to_name(protocol));
29970+
29971+ return 0;
29972+ exit:
29973+ return 1;
29974+}
29975+
29976+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)
29977+{
29978+ if ((ip->mode & mode) &&
29979+ (ip_port >= ip->low) &&
29980+ (ip_port <= ip->high) &&
29981+ ((ntohl(ip_addr) & our_netmask) ==
29982+ (ntohl(our_addr) & our_netmask))
29983+ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
29984+ && (ip->type & (1 << type))) {
29985+ if (ip->mode & GR_INVERT)
29986+ return 2; // specifically denied
29987+ else
29988+ return 1; // allowed
29989+ }
29990+
29991+ return 0; // not specifically allowed, may continue parsing
29992+}
29993+
29994+static int
29995+gr_search_connectbind(const int full_mode, struct sock *sk,
29996+ struct sockaddr_in *addr, const int type)
29997+{
29998+ char iface[IFNAMSIZ] = {0};
29999+ struct acl_subject_label *curr;
30000+ struct acl_ip_label *ip;
30001+ struct inet_sock *isk;
30002+ struct net_device *dev;
30003+ struct in_device *idev;
30004+ unsigned long i;
30005+ int ret;
30006+ int mode = full_mode & (GR_BIND | GR_CONNECT);
30007+ __u32 ip_addr = 0;
30008+ __u32 our_addr;
30009+ __u32 our_netmask;
30010+ char *p;
30011+ __u16 ip_port = 0;
30012+ const struct cred *cred = current_cred();
30013+
30014+ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
30015+ return 0;
30016+
30017+ curr = current->acl;
30018+ isk = inet_sk(sk);
30019+
30020+ /* INADDR_ANY overriding for binds, inaddr_any_override is already in network order */
30021+ if ((full_mode & GR_BINDOVERRIDE) && addr->sin_addr.s_addr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0)
30022+ addr->sin_addr.s_addr = curr->inaddr_any_override;
30023+ if ((full_mode & GR_CONNECT) && isk->saddr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0) {
30024+ struct sockaddr_in saddr;
30025+ int err;
30026+
30027+ saddr.sin_family = AF_INET;
30028+ saddr.sin_addr.s_addr = curr->inaddr_any_override;
30029+ saddr.sin_port = isk->sport;
30030+
30031+ err = security_socket_bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
30032+ if (err)
30033+ return err;
30034+
30035+ err = sk->sk_socket->ops->bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
30036+ if (err)
30037+ return err;
30038+ }
30039+
30040+ if (!curr->ips)
30041+ return 0;
30042+
30043+ ip_addr = addr->sin_addr.s_addr;
30044+ ip_port = ntohs(addr->sin_port);
30045+
30046+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
30047+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
30048+ current->role->roletype, cred->uid,
30049+ cred->gid, current->exec_file ?
30050+ gr_to_filename(current->exec_file->f_path.dentry,
30051+ current->exec_file->f_path.mnt) :
30052+ curr->filename, curr->filename,
30053+ NIPQUAD(ip_addr), ip_port, type,
30054+ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
30055+ return 0;
30056+ }
30057+
30058+ for (i = 0; i < curr->ip_num; i++) {
30059+ ip = *(curr->ips + i);
30060+ if (ip->iface != NULL) {
30061+ strncpy(iface, ip->iface, IFNAMSIZ - 1);
30062+ p = strchr(iface, ':');
30063+ if (p != NULL)
30064+ *p = '\0';
30065+ dev = dev_get_by_name(sock_net(sk), iface);
30066+ if (dev == NULL)
30067+ continue;
30068+ idev = in_dev_get(dev);
30069+ if (idev == NULL) {
30070+ dev_put(dev);
30071+ continue;
30072+ }
30073+ rcu_read_lock();
30074+ for_ifa(idev) {
30075+ if (!strcmp(ip->iface, ifa->ifa_label)) {
30076+ our_addr = ifa->ifa_address;
30077+ our_netmask = 0xffffffff;
30078+ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
30079+ if (ret == 1) {
30080+ rcu_read_unlock();
30081+ in_dev_put(idev);
30082+ dev_put(dev);
30083+ return 0;
30084+ } else if (ret == 2) {
30085+ rcu_read_unlock();
30086+ in_dev_put(idev);
30087+ dev_put(dev);
30088+ goto denied;
30089+ }
30090+ }
30091+ } endfor_ifa(idev);
30092+ rcu_read_unlock();
30093+ in_dev_put(idev);
30094+ dev_put(dev);
30095+ } else {
30096+ our_addr = ip->addr;
30097+ our_netmask = ip->netmask;
30098+ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
30099+ if (ret == 1)
30100+ return 0;
30101+ else if (ret == 2)
30102+ goto denied;
30103+ }
30104+ }
30105+
30106+denied:
30107+ if (mode == GR_BIND)
30108+ 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));
30109+ else if (mode == GR_CONNECT)
30110+ 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));
30111+
30112+ return -EACCES;
30113+}
30114+
30115+int
30116+gr_search_connect(struct socket *sock, struct sockaddr_in *addr)
30117+{
30118+ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sock->sk, addr, sock->type);
30119+}
30120+
30121+int
30122+gr_search_bind(struct socket *sock, struct sockaddr_in *addr)
30123+{
30124+ return gr_search_connectbind(GR_BIND | GR_BINDOVERRIDE, sock->sk, addr, sock->type);
30125+}
30126+
30127+int gr_search_listen(struct socket *sock)
30128+{
30129+ struct sock *sk = sock->sk;
30130+ struct sockaddr_in addr;
30131+
30132+ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
30133+ addr.sin_port = inet_sk(sk)->sport;
30134+
30135+ return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
30136+}
30137+
30138+int gr_search_accept(struct socket *sock)
30139+{
30140+ struct sock *sk = sock->sk;
30141+ struct sockaddr_in addr;
30142+
30143+ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
30144+ addr.sin_port = inet_sk(sk)->sport;
30145+
30146+ return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
30147+}
30148+
30149+int
30150+gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr)
30151+{
30152+ if (addr)
30153+ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
30154+ else {
30155+ struct sockaddr_in sin;
30156+ const struct inet_sock *inet = inet_sk(sk);
30157+
30158+ sin.sin_addr.s_addr = inet->daddr;
30159+ sin.sin_port = inet->dport;
30160+
30161+ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
30162+ }
30163+}
30164+
30165+int
30166+gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb)
30167+{
30168+ struct sockaddr_in sin;
30169+
30170+ if (unlikely(skb->len < sizeof (struct udphdr)))
30171+ return 0; // skip this packet
30172+
30173+ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
30174+ sin.sin_port = udp_hdr(skb)->source;
30175+
30176+ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
30177+}
017d2877
AM
30178diff -urNp linux-2.6.30.4/grsecurity/gracl_learn.c linux-2.6.30.4/grsecurity/gracl_learn.c
30179--- linux-2.6.30.4/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
30180+++ linux-2.6.30.4/grsecurity/gracl_learn.c 2009-07-30 11:10:49.347341041 -0400
2380c486
JR
30181@@ -0,0 +1,211 @@
30182+#include <linux/kernel.h>
30183+#include <linux/mm.h>
30184+#include <linux/sched.h>
30185+#include <linux/poll.h>
30186+#include <linux/smp_lock.h>
30187+#include <linux/string.h>
30188+#include <linux/file.h>
30189+#include <linux/types.h>
30190+#include <linux/vmalloc.h>
30191+#include <linux/grinternal.h>
30192+
30193+extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
30194+ size_t count, loff_t *ppos);
30195+extern int gr_acl_is_enabled(void);
30196+
30197+static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
30198+static int gr_learn_attached;
30199+
30200+/* use a 512k buffer */
30201+#define LEARN_BUFFER_SIZE (512 * 1024)
30202+
30203+static DEFINE_SPINLOCK(gr_learn_lock);
30204+static DECLARE_MUTEX(gr_learn_user_sem);
30205+
30206+/* we need to maintain two buffers, so that the kernel context of grlearn
30207+ uses a semaphore around the userspace copying, and the other kernel contexts
30208+ use a spinlock when copying into the buffer, since they cannot sleep
30209+*/
30210+static char *learn_buffer;
30211+static char *learn_buffer_user;
30212+static int learn_buffer_len;
30213+static int learn_buffer_user_len;
30214+
30215+static ssize_t
30216+read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
30217+{
30218+ DECLARE_WAITQUEUE(wait, current);
30219+ ssize_t retval = 0;
30220+
30221+ add_wait_queue(&learn_wait, &wait);
30222+ set_current_state(TASK_INTERRUPTIBLE);
30223+ do {
30224+ down(&gr_learn_user_sem);
30225+ spin_lock(&gr_learn_lock);
30226+ if (learn_buffer_len)
30227+ break;
30228+ spin_unlock(&gr_learn_lock);
30229+ up(&gr_learn_user_sem);
30230+ if (file->f_flags & O_NONBLOCK) {
30231+ retval = -EAGAIN;
30232+ goto out;
30233+ }
30234+ if (signal_pending(current)) {
30235+ retval = -ERESTARTSYS;
30236+ goto out;
30237+ }
30238+
30239+ schedule();
30240+ } while (1);
30241+
30242+ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
30243+ learn_buffer_user_len = learn_buffer_len;
30244+ retval = learn_buffer_len;
30245+ learn_buffer_len = 0;
30246+
30247+ spin_unlock(&gr_learn_lock);
30248+
30249+ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
30250+ retval = -EFAULT;
30251+
30252+ up(&gr_learn_user_sem);
30253+out:
30254+ set_current_state(TASK_RUNNING);
30255+ remove_wait_queue(&learn_wait, &wait);
30256+ return retval;
30257+}
30258+
30259+static unsigned int
30260+poll_learn(struct file * file, poll_table * wait)
30261+{
30262+ poll_wait(file, &learn_wait, wait);
30263+
30264+ if (learn_buffer_len)
30265+ return (POLLIN | POLLRDNORM);
30266+
30267+ return 0;
30268+}
30269+
30270+void
30271+gr_clear_learn_entries(void)
30272+{
30273+ char *tmp;
30274+
30275+ down(&gr_learn_user_sem);
30276+ if (learn_buffer != NULL) {
30277+ spin_lock(&gr_learn_lock);
30278+ tmp = learn_buffer;
30279+ learn_buffer = NULL;
30280+ spin_unlock(&gr_learn_lock);
30281+ vfree(learn_buffer);
30282+ }
30283+ if (learn_buffer_user != NULL) {
30284+ vfree(learn_buffer_user);
30285+ learn_buffer_user = NULL;
30286+ }
30287+ learn_buffer_len = 0;
30288+ up(&gr_learn_user_sem);
30289+
30290+ return;
30291+}
30292+
30293+void
30294+gr_add_learn_entry(const char *fmt, ...)
30295+{
30296+ va_list args;
30297+ unsigned int len;
30298+
30299+ if (!gr_learn_attached)
30300+ return;
30301+
30302+ spin_lock(&gr_learn_lock);
30303+
30304+ /* leave a gap at the end so we know when it's "full" but don't have to
30305+ compute the exact length of the string we're trying to append
30306+ */
30307+ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
30308+ spin_unlock(&gr_learn_lock);
30309+ wake_up_interruptible(&learn_wait);
30310+ return;
30311+ }
30312+ if (learn_buffer == NULL) {
30313+ spin_unlock(&gr_learn_lock);
30314+ return;
30315+ }
30316+
30317+ va_start(args, fmt);
30318+ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
30319+ va_end(args);
30320+
30321+ learn_buffer_len += len + 1;
30322+
30323+ spin_unlock(&gr_learn_lock);
30324+ wake_up_interruptible(&learn_wait);
30325+
30326+ return;
30327+}
30328+
30329+static int
30330+open_learn(struct inode *inode, struct file *file)
30331+{
30332+ if (file->f_mode & FMODE_READ && gr_learn_attached)
30333+ return -EBUSY;
30334+ if (file->f_mode & FMODE_READ) {
30335+ int retval = 0;
30336+ down(&gr_learn_user_sem);
30337+ if (learn_buffer == NULL)
30338+ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
30339+ if (learn_buffer_user == NULL)
30340+ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
30341+ if (learn_buffer == NULL) {
30342+ retval = -ENOMEM;
30343+ goto out_error;
30344+ }
30345+ if (learn_buffer_user == NULL) {
30346+ retval = -ENOMEM;
30347+ goto out_error;
30348+ }
30349+ learn_buffer_len = 0;
30350+ learn_buffer_user_len = 0;
30351+ gr_learn_attached = 1;
30352+out_error:
30353+ up(&gr_learn_user_sem);
30354+ return retval;
30355+ }
30356+ return 0;
30357+}
30358+
30359+static int
30360+close_learn(struct inode *inode, struct file *file)
30361+{
30362+ char *tmp;
30363+
30364+ if (file->f_mode & FMODE_READ) {
30365+ down(&gr_learn_user_sem);
30366+ if (learn_buffer != NULL) {
30367+ spin_lock(&gr_learn_lock);
30368+ tmp = learn_buffer;
30369+ learn_buffer = NULL;
30370+ spin_unlock(&gr_learn_lock);
30371+ vfree(tmp);
30372+ }
30373+ if (learn_buffer_user != NULL) {
30374+ vfree(learn_buffer_user);
30375+ learn_buffer_user = NULL;
30376+ }
30377+ learn_buffer_len = 0;
30378+ learn_buffer_user_len = 0;
30379+ gr_learn_attached = 0;
30380+ up(&gr_learn_user_sem);
30381+ }
30382+
30383+ return 0;
30384+}
30385+
017d2877 30386+const struct file_operations grsec_fops = {
2380c486
JR
30387+ .read = read_learn,
30388+ .write = write_grsec_handler,
30389+ .open = open_learn,
30390+ .release = close_learn,
30391+ .poll = poll_learn,
30392+};
017d2877
AM
30393diff -urNp linux-2.6.30.4/grsecurity/gracl_res.c linux-2.6.30.4/grsecurity/gracl_res.c
30394--- linux-2.6.30.4/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
30395+++ linux-2.6.30.4/grsecurity/gracl_res.c 2009-07-30 11:10:49.347341041 -0400
de855c5d 30396@@ -0,0 +1,58 @@
2380c486
JR
30397+#include <linux/kernel.h>
30398+#include <linux/sched.h>
30399+#include <linux/gracl.h>
30400+#include <linux/grinternal.h>
30401+
30402+static const char *restab_log[] = {
30403+ [RLIMIT_CPU] = "RLIMIT_CPU",
30404+ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
30405+ [RLIMIT_DATA] = "RLIMIT_DATA",
30406+ [RLIMIT_STACK] = "RLIMIT_STACK",
30407+ [RLIMIT_CORE] = "RLIMIT_CORE",
30408+ [RLIMIT_RSS] = "RLIMIT_RSS",
30409+ [RLIMIT_NPROC] = "RLIMIT_NPROC",
30410+ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
30411+ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
30412+ [RLIMIT_AS] = "RLIMIT_AS",
30413+ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
30414+ [RLIMIT_SIGPENDING] = "RLIMIT_SIGPENDING",
30415+ [RLIMIT_MSGQUEUE] = "RLIMIT_MSGQUEUE",
30416+ [RLIMIT_NICE] = "RLIMIT_NICE",
30417+ [RLIMIT_RTPRIO] = "RLIMIT_RTPRIO",
30418+ [RLIMIT_RTTIME] = "RLIMIT_RTTIME",
30419+ [GR_CRASH_RES] = "RLIMIT_CRASH"
30420+};
30421+
30422+void
30423+gr_log_resource(const struct task_struct *task,
30424+ const int res, const unsigned long wanted, const int gt)
30425+{
30426+ const struct cred *cred = __task_cred(task);
30427+
30428+ if (res == RLIMIT_NPROC &&
30429+ (cap_raised(cred->cap_effective, CAP_SYS_ADMIN) ||
30430+ cap_raised(cred->cap_effective, CAP_SYS_RESOURCE)))
30431+ return;
30432+ else if (res == RLIMIT_MEMLOCK &&
30433+ cap_raised(cred->cap_effective, CAP_IPC_LOCK))
30434+ return;
30435+ else if (res == RLIMIT_NICE && cap_raised(cred->cap_effective, CAP_SYS_NICE))
30436+ return;
30437+
30438+ if (!gr_acl_is_enabled() && !grsec_resource_logging)
30439+ return;
30440+
de855c5d
AM
30441+ // not yet supported resource
30442+ if (!restab_log[res])
30443+ return;
30444+
2380c486
JR
30445+ preempt_disable();
30446+
30447+ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
30448+ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
30449+ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
30450+ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
30451+ preempt_enable_no_resched();
30452+
30453+ return;
30454+}
017d2877
AM
30455diff -urNp linux-2.6.30.4/grsecurity/gracl_segv.c linux-2.6.30.4/grsecurity/gracl_segv.c
30456--- linux-2.6.30.4/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
30457+++ linux-2.6.30.4/grsecurity/gracl_segv.c 2009-07-30 11:10:49.347341041 -0400
2380c486
JR
30458@@ -0,0 +1,307 @@
30459+#include <linux/kernel.h>
30460+#include <linux/mm.h>
30461+#include <asm/uaccess.h>
30462+#include <asm/errno.h>
30463+#include <asm/mman.h>
30464+#include <net/sock.h>
30465+#include <linux/file.h>
30466+#include <linux/fs.h>
30467+#include <linux/net.h>
30468+#include <linux/in.h>
30469+#include <linux/smp_lock.h>
30470+#include <linux/slab.h>
30471+#include <linux/types.h>
30472+#include <linux/sched.h>
30473+#include <linux/timer.h>
30474+#include <linux/gracl.h>
30475+#include <linux/grsecurity.h>
30476+#include <linux/grinternal.h>
30477+
30478+static struct crash_uid *uid_set;
30479+static unsigned short uid_used;
30480+static DEFINE_SPINLOCK(gr_uid_lock);
30481+extern rwlock_t gr_inode_lock;
30482+extern struct acl_subject_label *
30483+ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
30484+ struct acl_role_label *role);
30485+extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
30486+
30487+int
30488+gr_init_uidset(void)
30489+{
30490+ uid_set =
30491+ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
30492+ uid_used = 0;
30493+
30494+ return uid_set ? 1 : 0;
30495+}
30496+
30497+void
30498+gr_free_uidset(void)
30499+{
30500+ if (uid_set)
30501+ kfree(uid_set);
30502+
30503+ return;
30504+}
30505+
30506+int
30507+gr_find_uid(const uid_t uid)
30508+{
30509+ struct crash_uid *tmp = uid_set;
30510+ uid_t buid;
30511+ int low = 0, high = uid_used - 1, mid;
30512+
30513+ while (high >= low) {
30514+ mid = (low + high) >> 1;
30515+ buid = tmp[mid].uid;
30516+ if (buid == uid)
30517+ return mid;
30518+ if (buid > uid)
30519+ high = mid - 1;
30520+ if (buid < uid)
30521+ low = mid + 1;
30522+ }
30523+
30524+ return -1;
30525+}
30526+
30527+static __inline__ void
30528+gr_insertsort(void)
30529+{
30530+ unsigned short i, j;
30531+ struct crash_uid index;
30532+
30533+ for (i = 1; i < uid_used; i++) {
30534+ index = uid_set[i];
30535+ j = i;
30536+ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
30537+ uid_set[j] = uid_set[j - 1];
30538+ j--;
30539+ }
30540+ uid_set[j] = index;
30541+ }
30542+
30543+ return;
30544+}
30545+
30546+static __inline__ void
30547+gr_insert_uid(const uid_t uid, const unsigned long expires)
30548+{
30549+ int loc;
30550+
30551+ if (uid_used == GR_UIDTABLE_MAX)
30552+ return;
30553+
30554+ loc = gr_find_uid(uid);
30555+
30556+ if (loc >= 0) {
30557+ uid_set[loc].expires = expires;
30558+ return;
30559+ }
30560+
30561+ uid_set[uid_used].uid = uid;
30562+ uid_set[uid_used].expires = expires;
30563+ uid_used++;
30564+
30565+ gr_insertsort();
30566+
30567+ return;
30568+}
30569+
30570+void
30571+gr_remove_uid(const unsigned short loc)
30572+{
30573+ unsigned short i;
30574+
30575+ for (i = loc + 1; i < uid_used; i++)
30576+ uid_set[i - 1] = uid_set[i];
30577+
30578+ uid_used--;
30579+
30580+ return;
30581+}
30582+
30583+int
30584+gr_check_crash_uid(const uid_t uid)
30585+{
30586+ int loc;
30587+ int ret = 0;
30588+
30589+ if (unlikely(!gr_acl_is_enabled()))
30590+ return 0;
30591+
30592+ spin_lock(&gr_uid_lock);
30593+ loc = gr_find_uid(uid);
30594+
30595+ if (loc < 0)
30596+ goto out_unlock;
30597+
30598+ if (time_before_eq(uid_set[loc].expires, get_seconds()))
30599+ gr_remove_uid(loc);
30600+ else
30601+ ret = 1;
30602+
30603+out_unlock:
30604+ spin_unlock(&gr_uid_lock);
30605+ return ret;
30606+}
30607+
30608+static __inline__ int
30609+proc_is_setxid(const struct cred *cred)
30610+{
30611+ if (cred->uid != cred->euid || cred->uid != cred->suid ||
30612+ cred->uid != cred->fsuid)
30613+ return 1;
30614+ if (cred->gid != cred->egid || cred->gid != cred->sgid ||
30615+ cred->gid != cred->fsgid)
30616+ return 1;
30617+
30618+ return 0;
30619+}
30620+static __inline__ int
30621+gr_fake_force_sig(int sig, struct task_struct *t)
30622+{
30623+ unsigned long int flags;
30624+ int ret, blocked, ignored;
30625+ struct k_sigaction *action;
30626+
30627+ spin_lock_irqsave(&t->sighand->siglock, flags);
30628+ action = &t->sighand->action[sig-1];
30629+ ignored = action->sa.sa_handler == SIG_IGN;
30630+ blocked = sigismember(&t->blocked, sig);
30631+ if (blocked || ignored) {
30632+ action->sa.sa_handler = SIG_DFL;
30633+ if (blocked) {
30634+ sigdelset(&t->blocked, sig);
30635+ recalc_sigpending_and_wake(t);
30636+ }
30637+ }
30638+ if (action->sa.sa_handler == SIG_DFL)
30639+ t->signal->flags &= ~SIGNAL_UNKILLABLE;
30640+ ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
30641+
30642+ spin_unlock_irqrestore(&t->sighand->siglock, flags);
30643+
30644+ return ret;
30645+}
30646+
30647+void
30648+gr_handle_crash(struct task_struct *task, const int sig)
30649+{
30650+ struct acl_subject_label *curr;
30651+ struct acl_subject_label *curr2;
30652+ struct task_struct *tsk, *tsk2;
30653+ const struct cred *cred = __task_cred(task);
30654+ const struct cred *cred2;
30655+
30656+ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
30657+ return;
30658+
30659+ if (unlikely(!gr_acl_is_enabled()))
30660+ return;
30661+
30662+ curr = task->acl;
30663+
30664+ if (!(curr->resmask & (1 << GR_CRASH_RES)))
30665+ return;
30666+
30667+ if (time_before_eq(curr->expires, get_seconds())) {
30668+ curr->expires = 0;
30669+ curr->crashes = 0;
30670+ }
30671+
30672+ curr->crashes++;
30673+
30674+ if (!curr->expires)
30675+ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
30676+
30677+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
30678+ time_after(curr->expires, get_seconds())) {
30679+ if (cred->uid && proc_is_setxid(cred)) {
30680+ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
30681+ spin_lock(&gr_uid_lock);
30682+ gr_insert_uid(cred->uid, curr->expires);
30683+ spin_unlock(&gr_uid_lock);
30684+ curr->expires = 0;
30685+ curr->crashes = 0;
30686+ read_lock(&tasklist_lock);
30687+ do_each_thread(tsk2, tsk) {
30688+ cred2 = __task_cred(tsk);
30689+ if (tsk != task && cred2->uid == cred->uid)
30690+ gr_fake_force_sig(SIGKILL, tsk);
30691+ } while_each_thread(tsk2, tsk);
30692+ read_unlock(&tasklist_lock);
30693+ } else {
30694+ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
30695+ read_lock(&tasklist_lock);
30696+ do_each_thread(tsk2, tsk) {
30697+ if (likely(tsk != task)) {
30698+ curr2 = tsk->acl;
30699+
30700+ if (curr2->device == curr->device &&
30701+ curr2->inode == curr->inode)
30702+ gr_fake_force_sig(SIGKILL, tsk);
30703+ }
30704+ } while_each_thread(tsk2, tsk);
30705+ read_unlock(&tasklist_lock);
30706+ }
30707+ }
30708+
30709+ return;
30710+}
30711+
30712+int
30713+gr_check_crash_exec(const struct file *filp)
30714+{
30715+ struct acl_subject_label *curr;
30716+
30717+ if (unlikely(!gr_acl_is_enabled()))
30718+ return 0;
30719+
30720+ read_lock(&gr_inode_lock);
30721+ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
30722+ filp->f_path.dentry->d_inode->i_sb->s_dev,
30723+ current->role);
30724+ read_unlock(&gr_inode_lock);
30725+
30726+ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
30727+ (!curr->crashes && !curr->expires))
30728+ return 0;
30729+
30730+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
30731+ time_after(curr->expires, get_seconds()))
30732+ return 1;
30733+ else if (time_before_eq(curr->expires, get_seconds())) {
30734+ curr->crashes = 0;
30735+ curr->expires = 0;
30736+ }
30737+
30738+ return 0;
30739+}
30740+
30741+void
30742+gr_handle_alertkill(struct task_struct *task)
30743+{
30744+ struct acl_subject_label *curracl;
30745+ __u32 curr_ip;
30746+ struct task_struct *p, *p2;
30747+
30748+ if (unlikely(!gr_acl_is_enabled()))
30749+ return;
30750+
30751+ curracl = task->acl;
30752+ curr_ip = task->signal->curr_ip;
30753+
30754+ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
30755+ read_lock(&tasklist_lock);
30756+ do_each_thread(p2, p) {
30757+ if (p->signal->curr_ip == curr_ip)
30758+ gr_fake_force_sig(SIGKILL, p);
30759+ } while_each_thread(p2, p);
30760+ read_unlock(&tasklist_lock);
30761+ } else if (curracl->mode & GR_KILLPROC)
30762+ gr_fake_force_sig(SIGKILL, task);
30763+
30764+ return;
30765+}
017d2877
AM
30766diff -urNp linux-2.6.30.4/grsecurity/gracl_shm.c linux-2.6.30.4/grsecurity/gracl_shm.c
30767--- linux-2.6.30.4/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
30768+++ linux-2.6.30.4/grsecurity/gracl_shm.c 2009-07-30 11:10:49.347341041 -0400
2380c486
JR
30769@@ -0,0 +1,37 @@
30770+#include <linux/kernel.h>
30771+#include <linux/mm.h>
30772+#include <linux/sched.h>
30773+#include <linux/file.h>
30774+#include <linux/ipc.h>
30775+#include <linux/gracl.h>
30776+#include <linux/grsecurity.h>
30777+#include <linux/grinternal.h>
30778+
30779+int
30780+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
30781+ const time_t shm_createtime, const uid_t cuid, const int shmid)
30782+{
30783+ struct task_struct *task;
30784+
30785+ if (!gr_acl_is_enabled())
30786+ return 1;
30787+
30788+ read_lock(&tasklist_lock);
30789+
30790+ task = find_task_by_vpid(shm_cprid);
30791+
30792+ if (unlikely(!task))
30793+ task = find_task_by_vpid(shm_lapid);
30794+
30795+ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
30796+ (task->pid == shm_lapid)) &&
30797+ (task->acl->mode & GR_PROTSHM) &&
30798+ (task->acl != current->acl))) {
30799+ read_unlock(&tasklist_lock);
30800+ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
30801+ return 0;
30802+ }
30803+ read_unlock(&tasklist_lock);
30804+
30805+ return 1;
30806+}
017d2877
AM
30807diff -urNp linux-2.6.30.4/grsecurity/grsec_chdir.c linux-2.6.30.4/grsecurity/grsec_chdir.c
30808--- linux-2.6.30.4/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
30809+++ linux-2.6.30.4/grsecurity/grsec_chdir.c 2009-07-30 11:10:49.347341041 -0400
2380c486
JR
30810@@ -0,0 +1,19 @@
30811+#include <linux/kernel.h>
30812+#include <linux/sched.h>
30813+#include <linux/fs.h>
30814+#include <linux/file.h>
30815+#include <linux/grsecurity.h>
30816+#include <linux/grinternal.h>
30817+
30818+void
30819+gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
30820+{
30821+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
30822+ if ((grsec_enable_chdir && grsec_enable_group &&
30823+ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
30824+ !grsec_enable_group)) {
30825+ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
30826+ }
30827+#endif
30828+ return;
30829+}
017d2877
AM
30830diff -urNp linux-2.6.30.4/grsecurity/grsec_chroot.c linux-2.6.30.4/grsecurity/grsec_chroot.c
30831--- linux-2.6.30.4/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
30832+++ linux-2.6.30.4/grsecurity/grsec_chroot.c 2009-07-30 11:10:49.347341041 -0400
2380c486
JR
30833@@ -0,0 +1,350 @@
30834+#include <linux/kernel.h>
30835+#include <linux/module.h>
30836+#include <linux/sched.h>
30837+#include <linux/file.h>
30838+#include <linux/fs.h>
30839+#include <linux/mount.h>
30840+#include <linux/types.h>
30841+#include <linux/pid_namespace.h>
30842+#include <linux/grsecurity.h>
30843+#include <linux/grinternal.h>
30844+
30845+int
30846+gr_handle_chroot_unix(const pid_t pid)
30847+{
30848+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
30849+ struct pid *spid = NULL;
30850+
30851+ if (unlikely(!grsec_enable_chroot_unix))
30852+ return 1;
30853+
30854+ if (likely(!proc_is_chrooted(current)))
30855+ return 1;
30856+
30857+ read_lock(&tasklist_lock);
30858+
30859+ spid = find_vpid(pid);
30860+ if (spid) {
30861+ struct task_struct *p;
30862+ p = pid_task(spid, PIDTYPE_PID);
30863+ task_lock(p);
30864+ if (unlikely(!have_same_root(current, p))) {
30865+ task_unlock(p);
30866+ read_unlock(&tasklist_lock);
30867+ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
30868+ return 0;
30869+ }
30870+ task_unlock(p);
30871+ }
30872+ read_unlock(&tasklist_lock);
30873+#endif
30874+ return 1;
30875+}
30876+
30877+int
30878+gr_handle_chroot_nice(void)
30879+{
30880+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
30881+ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
30882+ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
30883+ return -EPERM;
30884+ }
30885+#endif
30886+ return 0;
30887+}
30888+
30889+int
30890+gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
30891+{
30892+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
30893+ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
30894+ && proc_is_chrooted(current)) {
30895+ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
30896+ return -EACCES;
30897+ }
30898+#endif
30899+ return 0;
30900+}
30901+
30902+int
30903+gr_handle_chroot_rawio(const struct inode *inode)
30904+{
30905+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
30906+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
30907+ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
30908+ return 1;
30909+#endif
30910+ return 0;
30911+}
30912+
30913+int
30914+gr_pid_is_chrooted(struct task_struct *p)
30915+{
30916+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
30917+ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
30918+ return 0;
30919+
30920+ task_lock(p);
30921+ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
30922+ !have_same_root(current, p)) {
30923+ task_unlock(p);
30924+ return 1;
30925+ }
30926+ task_unlock(p);
30927+#endif
30928+ return 0;
30929+}
30930+
30931+EXPORT_SYMBOL(gr_pid_is_chrooted);
30932+
30933+#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
30934+int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
30935+{
30936+ struct dentry *dentry = (struct dentry *)u_dentry;
30937+ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
30938+ struct dentry *realroot;
30939+ struct vfsmount *realrootmnt;
30940+ struct dentry *currentroot;
30941+ struct vfsmount *currentmnt;
30942+ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
30943+ int ret = 1;
30944+
30945+ read_lock(&reaper->fs->lock);
30946+ realrootmnt = mntget(reaper->fs->root.mnt);
30947+ realroot = dget(reaper->fs->root.dentry);
30948+ read_unlock(&reaper->fs->lock);
30949+
30950+ read_lock(&current->fs->lock);
30951+ currentmnt = mntget(current->fs->root.mnt);
30952+ currentroot = dget(current->fs->root.dentry);
30953+ read_unlock(&current->fs->lock);
30954+
30955+ spin_lock(&dcache_lock);
30956+ for (;;) {
30957+ if (unlikely((dentry == realroot && mnt == realrootmnt)
30958+ || (dentry == currentroot && mnt == currentmnt)))
30959+ break;
30960+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
30961+ if (mnt->mnt_parent == mnt)
30962+ break;
30963+ dentry = mnt->mnt_mountpoint;
30964+ mnt = mnt->mnt_parent;
30965+ continue;
30966+ }
30967+ dentry = dentry->d_parent;
30968+ }
30969+ spin_unlock(&dcache_lock);
30970+
30971+ dput(currentroot);
30972+ mntput(currentmnt);
30973+
30974+ /* access is outside of chroot */
30975+ if (dentry == realroot && mnt == realrootmnt)
30976+ ret = 0;
30977+
30978+ dput(realroot);
30979+ mntput(realrootmnt);
30980+ return ret;
30981+}
30982+#endif
30983+
30984+int
30985+gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
30986+{
30987+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
30988+ if (!grsec_enable_chroot_fchdir)
30989+ return 1;
30990+
30991+ if (!proc_is_chrooted(current))
30992+ return 1;
30993+ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
30994+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
30995+ return 0;
30996+ }
30997+#endif
30998+ return 1;
30999+}
31000+
31001+int
31002+gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31003+ const time_t shm_createtime)
31004+{
31005+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
31006+ struct pid *pid = NULL;
31007+ time_t starttime;
31008+
31009+ if (unlikely(!grsec_enable_chroot_shmat))
31010+ return 1;
31011+
31012+ if (likely(!proc_is_chrooted(current)))
31013+ return 1;
31014+
31015+ read_lock(&tasklist_lock);
31016+
31017+ pid = find_vpid(shm_cprid);
31018+ if (pid) {
31019+ struct task_struct *p;
31020+ p = pid_task(pid, PIDTYPE_PID);
31021+ task_lock(p);
31022+ starttime = p->start_time.tv_sec;
31023+ if (unlikely(!have_same_root(current, p) &&
31024+ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
31025+ task_unlock(p);
31026+ read_unlock(&tasklist_lock);
31027+ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
31028+ return 0;
31029+ }
31030+ task_unlock(p);
31031+ } else {
31032+ pid = find_vpid(shm_lapid);
31033+ if (pid) {
31034+ struct task_struct *p;
31035+ p = pid_task(pid, PIDTYPE_PID);
31036+ task_lock(p);
31037+ if (unlikely(!have_same_root(current, p))) {
31038+ task_unlock(p);
31039+ read_unlock(&tasklist_lock);
31040+ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
31041+ return 0;
31042+ }
31043+ task_unlock(p);
31044+ }
31045+ }
31046+
31047+ read_unlock(&tasklist_lock);
31048+#endif
31049+ return 1;
31050+}
31051+
31052+void
31053+gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
31054+{
31055+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
31056+ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
31057+ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
31058+#endif
31059+ return;
31060+}
31061+
31062+int
31063+gr_handle_chroot_mknod(const struct dentry *dentry,
31064+ const struct vfsmount *mnt, const int mode)
31065+{
31066+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
31067+ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
31068+ proc_is_chrooted(current)) {
31069+ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
31070+ return -EPERM;
31071+ }
31072+#endif
31073+ return 0;
31074+}
31075+
31076+int
31077+gr_handle_chroot_mount(const struct dentry *dentry,
31078+ const struct vfsmount *mnt, const char *dev_name)
31079+{
31080+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
31081+ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
31082+ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
31083+ return -EPERM;
31084+ }
31085+#endif
31086+ return 0;
31087+}
31088+
31089+int
31090+gr_handle_chroot_pivot(void)
31091+{
31092+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
31093+ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
31094+ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
31095+ return -EPERM;
31096+ }
31097+#endif
31098+ return 0;
31099+}
31100+
31101+int
31102+gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
31103+{
31104+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
31105+ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
31106+ !gr_is_outside_chroot(dentry, mnt)) {
31107+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
31108+ return -EPERM;
31109+ }
31110+#endif
31111+ return 0;
31112+}
31113+
31114+int
31115+gr_handle_chroot_caps(struct path *path)
31116+{
31117+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
31118+ if (grsec_enable_chroot_caps && current->pid > 1 && current->fs != NULL &&
31119+ ((current->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb !=
31120+ path->dentry->d_inode->i_sb) ||
31121+ (current->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino !=
31122+ path->dentry->d_inode->i_ino))) {
31123+
31124+ kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
31125+ const struct cred *old = current_cred();
31126+ struct cred *new = prepare_creds();
31127+ if (new == NULL)
31128+ return 1;
31129+
31130+ new->cap_permitted = cap_drop(old->cap_permitted,
31131+ chroot_caps);
31132+ new->cap_inheritable = cap_drop(old->cap_inheritable,
31133+ chroot_caps);
31134+ new->cap_effective = cap_drop(old->cap_effective,
31135+ chroot_caps);
31136+
31137+ commit_creds(new);
31138+
31139+ return 0;
31140+ }
31141+#endif
31142+ return 0;
31143+}
31144+
31145+int
31146+gr_handle_chroot_sysctl(const int op)
31147+{
31148+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
31149+ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
31150+ && (op & MAY_WRITE))
31151+ return -EACCES;
31152+#endif
31153+ return 0;
31154+}
31155+
31156+void
31157+gr_handle_chroot_chdir(struct path *path)
31158+{
31159+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
31160+ if (grsec_enable_chroot_chdir)
31161+ set_fs_pwd(current->fs, path);
31162+#endif
31163+ return;
31164+}
31165+
31166+int
31167+gr_handle_chroot_chmod(const struct dentry *dentry,
31168+ const struct vfsmount *mnt, const int mode)
31169+{
31170+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
31171+ if (grsec_enable_chroot_chmod &&
31172+ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
31173+ proc_is_chrooted(current)) {
31174+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
31175+ return -EPERM;
31176+ }
31177+#endif
31178+ return 0;
31179+}
31180+
31181+#ifdef CONFIG_SECURITY
31182+EXPORT_SYMBOL(gr_handle_chroot_caps);
31183+#endif
017d2877
AM
31184diff -urNp linux-2.6.30.4/grsecurity/grsec_disabled.c linux-2.6.30.4/grsecurity/grsec_disabled.c
31185--- linux-2.6.30.4/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
31186+++ linux-2.6.30.4/grsecurity/grsec_disabled.c 2009-07-30 11:10:49.347341041 -0400
de855c5d 31187@@ -0,0 +1,426 @@
2380c486
JR
31188+#include <linux/kernel.h>
31189+#include <linux/module.h>
31190+#include <linux/sched.h>
31191+#include <linux/file.h>
31192+#include <linux/fs.h>
31193+#include <linux/kdev_t.h>
31194+#include <linux/net.h>
31195+#include <linux/in.h>
31196+#include <linux/ip.h>
31197+#include <linux/skbuff.h>
31198+#include <linux/sysctl.h>
31199+
31200+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
31201+void
31202+pax_set_initial_flags(struct linux_binprm *bprm)
31203+{
31204+ return;
31205+}
31206+#endif
31207+
31208+#ifdef CONFIG_SYSCTL
31209+__u32
31210+gr_handle_sysctl(const struct ctl_table * table, const int op)
31211+{
31212+ return 0;
31213+}
31214+#endif
31215+
de855c5d
AM
31216+#ifdef CONFIG_TASKSTATS
31217+int gr_is_taskstats_denied(int pid)
31218+{
31219+ return 0;
31220+}
31221+#endif
31222+
2380c486
JR
31223+int
31224+gr_acl_is_enabled(void)
31225+{
31226+ return 0;
31227+}
31228+
31229+int
31230+gr_handle_rawio(const struct inode *inode)
31231+{
31232+ return 0;
31233+}
31234+
31235+void
31236+gr_acl_handle_psacct(struct task_struct *task, const long code)
31237+{
31238+ return;
31239+}
31240+
31241+int
31242+gr_handle_ptrace(struct task_struct *task, const long request)
31243+{
31244+ return 0;
31245+}
31246+
31247+int
31248+gr_handle_proc_ptrace(struct task_struct *task)
31249+{
31250+ return 0;
31251+}
31252+
31253+void
31254+gr_learn_resource(const struct task_struct *task,
31255+ const int res, const unsigned long wanted, const int gt)
31256+{
31257+ return;
31258+}
31259+
31260+int
31261+gr_set_acls(const int type)
31262+{
31263+ return 0;
31264+}
31265+
31266+int
31267+gr_check_hidden_task(const struct task_struct *tsk)
31268+{
31269+ return 0;
31270+}
31271+
31272+int
31273+gr_check_protected_task(const struct task_struct *task)
31274+{
31275+ return 0;
31276+}
31277+
31278+void
31279+gr_copy_label(struct task_struct *tsk)
31280+{
31281+ return;
31282+}
31283+
31284+void
31285+gr_set_pax_flags(struct task_struct *task)
31286+{
31287+ return;
31288+}
31289+
31290+int
de855c5d
AM
31291+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt,
31292+ const int unsafe_share)
2380c486
JR
31293+{
31294+ return 0;
31295+}
31296+
31297+void
31298+gr_handle_delete(const ino_t ino, const dev_t dev)
31299+{
31300+ return;
31301+}
31302+
31303+void
31304+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
31305+{
31306+ return;
31307+}
31308+
31309+void
31310+gr_handle_crash(struct task_struct *task, const int sig)
31311+{
31312+ return;
31313+}
31314+
31315+int
31316+gr_check_crash_exec(const struct file *filp)
31317+{
31318+ return 0;
31319+}
31320+
31321+int
31322+gr_check_crash_uid(const uid_t uid)
31323+{
31324+ return 0;
31325+}
31326+
31327+void
31328+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
31329+ struct dentry *old_dentry,
31330+ struct dentry *new_dentry,
31331+ struct vfsmount *mnt, const __u8 replace)
31332+{
31333+ return;
31334+}
31335+
31336+int
31337+gr_search_socket(const int family, const int type, const int protocol)
31338+{
31339+ return 1;
31340+}
31341+
31342+int
31343+gr_search_connectbind(const int mode, const struct socket *sock,
31344+ const struct sockaddr_in *addr)
31345+{
31346+ return 0;
31347+}
31348+
31349+int
31350+gr_is_capable(const int cap)
31351+{
31352+ return 1;
31353+}
31354+
31355+int
31356+gr_is_capable_nolog(const int cap)
31357+{
31358+ return 1;
31359+}
31360+
31361+void
31362+gr_handle_alertkill(struct task_struct *task)
31363+{
31364+ return;
31365+}
31366+
31367+__u32
31368+gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
31369+{
31370+ return 1;
31371+}
31372+
31373+__u32
31374+gr_acl_handle_hidden_file(const struct dentry * dentry,
31375+ const struct vfsmount * mnt)
31376+{
31377+ return 1;
31378+}
31379+
31380+__u32
31381+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
31382+ const int fmode)
31383+{
31384+ return 1;
31385+}
31386+
31387+__u32
31388+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
31389+{
31390+ return 1;
31391+}
31392+
31393+__u32
31394+gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
31395+{
31396+ return 1;
31397+}
31398+
31399+int
31400+gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
31401+ unsigned int *vm_flags)
31402+{
31403+ return 1;
31404+}
31405+
31406+__u32
31407+gr_acl_handle_truncate(const struct dentry * dentry,
31408+ const struct vfsmount * mnt)
31409+{
31410+ return 1;
31411+}
31412+
31413+__u32
31414+gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
31415+{
31416+ return 1;
31417+}
31418+
31419+__u32
31420+gr_acl_handle_access(const struct dentry * dentry,
31421+ const struct vfsmount * mnt, const int fmode)
31422+{
31423+ return 1;
31424+}
31425+
31426+__u32
31427+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
31428+ mode_t mode)
31429+{
31430+ return 1;
31431+}
31432+
31433+__u32
31434+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
31435+ mode_t mode)
31436+{
31437+ return 1;
31438+}
31439+
31440+__u32
31441+gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
31442+{
31443+ return 1;
31444+}
31445+
31446+void
31447+grsecurity_init(void)
31448+{
31449+ return;
31450+}
31451+
31452+__u32
31453+gr_acl_handle_mknod(const struct dentry * new_dentry,
31454+ const struct dentry * parent_dentry,
31455+ const struct vfsmount * parent_mnt,
31456+ const int mode)
31457+{
31458+ return 1;
31459+}
31460+
31461+__u32
31462+gr_acl_handle_mkdir(const struct dentry * new_dentry,
31463+ const struct dentry * parent_dentry,
31464+ const struct vfsmount * parent_mnt)
31465+{
31466+ return 1;
31467+}
31468+
31469+__u32
31470+gr_acl_handle_symlink(const struct dentry * new_dentry,
31471+ const struct dentry * parent_dentry,
31472+ const struct vfsmount * parent_mnt, const char *from)
31473+{
31474+ return 1;
31475+}
31476+
31477+__u32
31478+gr_acl_handle_link(const struct dentry * new_dentry,
31479+ const struct dentry * parent_dentry,
31480+ const struct vfsmount * parent_mnt,
31481+ const struct dentry * old_dentry,
31482+ const struct vfsmount * old_mnt, const char *to)
31483+{
31484+ return 1;
31485+}
31486+
31487+int
31488+gr_acl_handle_rename(const struct dentry *new_dentry,
31489+ const struct dentry *parent_dentry,
31490+ const struct vfsmount *parent_mnt,
31491+ const struct dentry *old_dentry,
31492+ const struct inode *old_parent_inode,
31493+ const struct vfsmount *old_mnt, const char *newname)
31494+{
31495+ return 0;
31496+}
31497+
31498+int
31499+gr_acl_handle_filldir(const struct file *file, const char *name,
31500+ const int namelen, const ino_t ino)
31501+{
31502+ return 1;
31503+}
31504+
31505+int
31506+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31507+ const time_t shm_createtime, const uid_t cuid, const int shmid)
31508+{
31509+ return 1;
31510+}
31511+
31512+int
31513+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
31514+{
31515+ return 0;
31516+}
31517+
31518+int
31519+gr_search_accept(const struct socket *sock)
31520+{
31521+ return 0;
31522+}
31523+
31524+int
31525+gr_search_listen(const struct socket *sock)
31526+{
31527+ return 0;
31528+}
31529+
31530+int
31531+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
31532+{
31533+ return 0;
31534+}
31535+
31536+__u32
31537+gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
31538+{
31539+ return 1;
31540+}
31541+
31542+__u32
31543+gr_acl_handle_creat(const struct dentry * dentry,
31544+ const struct dentry * p_dentry,
31545+ const struct vfsmount * p_mnt, const int fmode,
31546+ const int imode)
31547+{
31548+ return 1;
31549+}
31550+
31551+void
31552+gr_acl_handle_exit(void)
31553+{
31554+ return;
31555+}
31556+
31557+int
31558+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
31559+{
31560+ return 1;
31561+}
31562+
31563+void
31564+gr_set_role_label(const uid_t uid, const gid_t gid)
31565+{
31566+ return;
31567+}
31568+
31569+int
31570+gr_acl_handle_procpidmem(const struct task_struct *task)
31571+{
31572+ return 0;
31573+}
31574+
31575+int
31576+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
31577+{
31578+ return 0;
31579+}
31580+
31581+int
31582+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
31583+{
31584+ return 0;
31585+}
31586+
31587+void
31588+gr_set_kernel_label(struct task_struct *task)
31589+{
31590+ return;
31591+}
31592+
31593+int
31594+gr_check_user_change(int real, int effective, int fs)
31595+{
31596+ return 0;
31597+}
31598+
31599+int
31600+gr_check_group_change(int real, int effective, int fs)
31601+{
31602+ return 0;
31603+}
31604+
31605+
31606+EXPORT_SYMBOL(gr_is_capable);
31607+EXPORT_SYMBOL(gr_is_capable_nolog);
31608+EXPORT_SYMBOL(gr_learn_resource);
31609+EXPORT_SYMBOL(gr_set_kernel_label);
31610+#ifdef CONFIG_SECURITY
31611+EXPORT_SYMBOL(gr_check_user_change);
31612+EXPORT_SYMBOL(gr_check_group_change);
31613+#endif
017d2877
AM
31614diff -urNp linux-2.6.30.4/grsecurity/grsec_exec.c linux-2.6.30.4/grsecurity/grsec_exec.c
31615--- linux-2.6.30.4/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
31616+++ linux-2.6.30.4/grsecurity/grsec_exec.c 2009-07-30 11:10:49.347341041 -0400
2380c486
JR
31617@@ -0,0 +1,89 @@
31618+#include <linux/kernel.h>
31619+#include <linux/sched.h>
31620+#include <linux/file.h>
31621+#include <linux/binfmts.h>
31622+#include <linux/smp_lock.h>
31623+#include <linux/fs.h>
31624+#include <linux/types.h>
31625+#include <linux/grdefs.h>
31626+#include <linux/grinternal.h>
31627+#include <linux/capability.h>
31628+
31629+#include <asm/uaccess.h>
31630+
31631+#ifdef CONFIG_GRKERNSEC_EXECLOG
31632+static char gr_exec_arg_buf[132];
31633+static DECLARE_MUTEX(gr_exec_arg_sem);
31634+#endif
31635+
31636+int
31637+gr_handle_nproc(void)
31638+{
31639+#ifdef CONFIG_GRKERNSEC_EXECVE
31640+ const struct cred *cred = current_cred();
31641+ if (grsec_enable_execve && cred->user &&
31642+ (atomic_read(&cred->user->processes) >
31643+ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
31644+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
31645+ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
31646+ return -EAGAIN;
31647+ }
31648+#endif
31649+ return 0;
31650+}
31651+
31652+void
31653+gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
31654+{
31655+#ifdef CONFIG_GRKERNSEC_EXECLOG
31656+ char *grarg = gr_exec_arg_buf;
31657+ unsigned int i, x, execlen = 0;
31658+ char c;
31659+
31660+ if (!((grsec_enable_execlog && grsec_enable_group &&
31661+ in_group_p(grsec_audit_gid))
31662+ || (grsec_enable_execlog && !grsec_enable_group)))
31663+ return;
31664+
31665+ down(&gr_exec_arg_sem);
31666+ memset(grarg, 0, sizeof(gr_exec_arg_buf));
31667+
31668+ if (unlikely(argv == NULL))
31669+ goto log;
31670+
31671+ for (i = 0; i < bprm->argc && execlen < 128; i++) {
31672+ const char __user *p;
31673+ unsigned int len;
31674+
31675+ if (copy_from_user(&p, argv + i, sizeof(p)))
31676+ goto log;
31677+ if (!p)
31678+ goto log;
31679+ len = strnlen_user(p, 128 - execlen);
31680+ if (len > 128 - execlen)
31681+ len = 128 - execlen;
31682+ else if (len > 0)
31683+ len--;
31684+ if (copy_from_user(grarg + execlen, p, len))
31685+ goto log;
31686+
31687+ /* rewrite unprintable characters */
31688+ for (x = 0; x < len; x++) {
31689+ c = *(grarg + execlen + x);
31690+ if (c < 32 || c > 126)
31691+ *(grarg + execlen + x) = ' ';
31692+ }
31693+
31694+ execlen += len;
31695+ *(grarg + execlen) = ' ';
31696+ *(grarg + execlen + 1) = '\0';
31697+ execlen++;
31698+ }
31699+
31700+ log:
31701+ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
31702+ bprm->file->f_path.mnt, grarg);
31703+ up(&gr_exec_arg_sem);
31704+#endif
31705+ return;
31706+}
017d2877
AM
31707diff -urNp linux-2.6.30.4/grsecurity/grsec_fifo.c linux-2.6.30.4/grsecurity/grsec_fifo.c
31708--- linux-2.6.30.4/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
31709+++ linux-2.6.30.4/grsecurity/grsec_fifo.c 2009-07-30 11:10:49.347341041 -0400
2380c486
JR
31710@@ -0,0 +1,24 @@
31711+#include <linux/kernel.h>
31712+#include <linux/sched.h>
31713+#include <linux/fs.h>
31714+#include <linux/file.h>
31715+#include <linux/grinternal.h>
31716+
31717+int
31718+gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
31719+ const struct dentry *dir, const int flag, const int acc_mode)
31720+{
31721+#ifdef CONFIG_GRKERNSEC_FIFO
31722+ const struct cred *cred = current_cred();
31723+
31724+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
31725+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
31726+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
31727+ (cred->fsuid != dentry->d_inode->i_uid)) {
31728+ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
31729+ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
31730+ return -EACCES;
31731+ }
31732+#endif
31733+ return 0;
31734+}
017d2877
AM
31735diff -urNp linux-2.6.30.4/grsecurity/grsec_fork.c linux-2.6.30.4/grsecurity/grsec_fork.c
31736--- linux-2.6.30.4/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
31737+++ linux-2.6.30.4/grsecurity/grsec_fork.c 2009-07-30 11:10:49.349503559 -0400
2380c486
JR
31738@@ -0,0 +1,15 @@
31739+#include <linux/kernel.h>
31740+#include <linux/sched.h>
31741+#include <linux/grsecurity.h>
31742+#include <linux/grinternal.h>
31743+#include <linux/errno.h>
31744+
31745+void
31746+gr_log_forkfail(const int retval)
31747+{
31748+#ifdef CONFIG_GRKERNSEC_FORKFAIL
31749+ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
31750+ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
31751+#endif
31752+ return;
31753+}
017d2877
AM
31754diff -urNp linux-2.6.30.4/grsecurity/grsec_init.c linux-2.6.30.4/grsecurity/grsec_init.c
31755--- linux-2.6.30.4/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
31756+++ linux-2.6.30.4/grsecurity/grsec_init.c 2009-07-30 12:01:03.627768838 -0400
2380c486
JR
31757@@ -0,0 +1,230 @@
31758+#include <linux/kernel.h>
31759+#include <linux/sched.h>
31760+#include <linux/mm.h>
31761+#include <linux/smp_lock.h>
31762+#include <linux/gracl.h>
31763+#include <linux/slab.h>
31764+#include <linux/vmalloc.h>
31765+#include <linux/percpu.h>
31766+
31767+int grsec_enable_link;
31768+int grsec_enable_dmesg;
31769+int grsec_enable_fifo;
31770+int grsec_enable_execve;
31771+int grsec_enable_execlog;
31772+int grsec_enable_signal;
31773+int grsec_enable_forkfail;
31774+int grsec_enable_time;
31775+int grsec_enable_audit_textrel;
31776+int grsec_enable_group;
31777+int grsec_audit_gid;
31778+int grsec_enable_chdir;
31779+int grsec_enable_audit_ipc;
31780+int grsec_enable_mount;
31781+int grsec_enable_chroot_findtask;
31782+int grsec_enable_chroot_mount;
31783+int grsec_enable_chroot_shmat;
31784+int grsec_enable_chroot_fchdir;
31785+int grsec_enable_chroot_double;
31786+int grsec_enable_chroot_pivot;
31787+int grsec_enable_chroot_chdir;
31788+int grsec_enable_chroot_chmod;
31789+int grsec_enable_chroot_mknod;
31790+int grsec_enable_chroot_nice;
31791+int grsec_enable_chroot_execlog;
31792+int grsec_enable_chroot_caps;
31793+int grsec_enable_chroot_sysctl;
31794+int grsec_enable_chroot_unix;
31795+int grsec_enable_tpe;
31796+int grsec_tpe_gid;
31797+int grsec_enable_tpe_all;
31798+int grsec_enable_socket_all;
31799+int grsec_socket_all_gid;
31800+int grsec_enable_socket_client;
31801+int grsec_socket_client_gid;
31802+int grsec_enable_socket_server;
31803+int grsec_socket_server_gid;
31804+int grsec_resource_logging;
31805+int grsec_lock;
31806+
31807+DEFINE_SPINLOCK(grsec_alert_lock);
31808+unsigned long grsec_alert_wtime = 0;
31809+unsigned long grsec_alert_fyet = 0;
31810+
31811+DEFINE_SPINLOCK(grsec_audit_lock);
31812+
31813+DEFINE_RWLOCK(grsec_exec_file_lock);
31814+
31815+char *gr_shared_page[4];
31816+
31817+char *gr_alert_log_fmt;
31818+char *gr_audit_log_fmt;
31819+char *gr_alert_log_buf;
31820+char *gr_audit_log_buf;
31821+
31822+extern struct gr_arg *gr_usermode;
31823+extern unsigned char *gr_system_salt;
31824+extern unsigned char *gr_system_sum;
31825+
017d2877 31826+void __init
2380c486
JR
31827+grsecurity_init(void)
31828+{
31829+ int j;
31830+ /* create the per-cpu shared pages */
31831+
31832+#ifdef CONFIG_X86
31833+ memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
31834+#endif
31835+
31836+ for (j = 0; j < 4; j++) {
017d2877 31837+ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, 0);
2380c486
JR
31838+ if (gr_shared_page[j] == NULL) {
31839+ panic("Unable to allocate grsecurity shared page");
31840+ return;
31841+ }
31842+ }
31843+
31844+ /* allocate log buffers */
31845+ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
31846+ if (!gr_alert_log_fmt) {
31847+ panic("Unable to allocate grsecurity alert log format buffer");
31848+ return;
31849+ }
31850+ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
31851+ if (!gr_audit_log_fmt) {
31852+ panic("Unable to allocate grsecurity audit log format buffer");
31853+ return;
31854+ }
31855+ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
31856+ if (!gr_alert_log_buf) {
31857+ panic("Unable to allocate grsecurity alert log buffer");
31858+ return;
31859+ }
31860+ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
31861+ if (!gr_audit_log_buf) {
31862+ panic("Unable to allocate grsecurity audit log buffer");
31863+ return;
31864+ }
31865+
31866+ /* allocate memory for authentication structure */
31867+ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
31868+ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
31869+ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
31870+
31871+ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
31872+ panic("Unable to allocate grsecurity authentication structure");
31873+ return;
31874+ }
31875+
31876+#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
31877+#ifndef CONFIG_GRKERNSEC_SYSCTL
31878+ grsec_lock = 1;
31879+#endif
31880+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
31881+ grsec_enable_audit_textrel = 1;
31882+#endif
31883+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
31884+ grsec_enable_group = 1;
31885+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
31886+#endif
31887+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
31888+ grsec_enable_chdir = 1;
31889+#endif
31890+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
31891+ grsec_enable_audit_ipc = 1;
31892+#endif
31893+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
31894+ grsec_enable_mount = 1;
31895+#endif
31896+#ifdef CONFIG_GRKERNSEC_LINK
31897+ grsec_enable_link = 1;
31898+#endif
31899+#ifdef CONFIG_GRKERNSEC_DMESG
31900+ grsec_enable_dmesg = 1;
31901+#endif
31902+#ifdef CONFIG_GRKERNSEC_FIFO
31903+ grsec_enable_fifo = 1;
31904+#endif
31905+#ifdef CONFIG_GRKERNSEC_EXECVE
31906+ grsec_enable_execve = 1;
31907+#endif
31908+#ifdef CONFIG_GRKERNSEC_EXECLOG
31909+ grsec_enable_execlog = 1;
31910+#endif
31911+#ifdef CONFIG_GRKERNSEC_SIGNAL
31912+ grsec_enable_signal = 1;
31913+#endif
31914+#ifdef CONFIG_GRKERNSEC_FORKFAIL
31915+ grsec_enable_forkfail = 1;
31916+#endif
31917+#ifdef CONFIG_GRKERNSEC_TIME
31918+ grsec_enable_time = 1;
31919+#endif
31920+#ifdef CONFIG_GRKERNSEC_RESLOG
31921+ grsec_resource_logging = 1;
31922+#endif
31923+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
31924+ grsec_enable_chroot_findtask = 1;
31925+#endif
31926+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
31927+ grsec_enable_chroot_unix = 1;
31928+#endif
31929+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
31930+ grsec_enable_chroot_mount = 1;
31931+#endif
31932+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
31933+ grsec_enable_chroot_fchdir = 1;
31934+#endif
31935+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
31936+ grsec_enable_chroot_shmat = 1;
31937+#endif
31938+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
31939+ grsec_enable_chroot_double = 1;
31940+#endif
31941+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
31942+ grsec_enable_chroot_pivot = 1;
31943+#endif
31944+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
31945+ grsec_enable_chroot_chdir = 1;
31946+#endif
31947+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
31948+ grsec_enable_chroot_chmod = 1;
31949+#endif
31950+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
31951+ grsec_enable_chroot_mknod = 1;
31952+#endif
31953+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
31954+ grsec_enable_chroot_nice = 1;
31955+#endif
31956+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
31957+ grsec_enable_chroot_execlog = 1;
31958+#endif
31959+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
31960+ grsec_enable_chroot_caps = 1;
31961+#endif
31962+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
31963+ grsec_enable_chroot_sysctl = 1;
31964+#endif
31965+#ifdef CONFIG_GRKERNSEC_TPE
31966+ grsec_enable_tpe = 1;
31967+ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
31968+#ifdef CONFIG_GRKERNSEC_TPE_ALL
31969+ grsec_enable_tpe_all = 1;
31970+#endif
31971+#endif
31972+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
31973+ grsec_enable_socket_all = 1;
31974+ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
31975+#endif
31976+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
31977+ grsec_enable_socket_client = 1;
31978+ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
31979+#endif
31980+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
31981+ grsec_enable_socket_server = 1;
31982+ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
31983+#endif
31984+#endif
31985+
31986+ return;
31987+}
017d2877
AM
31988diff -urNp linux-2.6.30.4/grsecurity/grsec_ipc.c linux-2.6.30.4/grsecurity/grsec_ipc.c
31989--- linux-2.6.30.4/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
31990+++ linux-2.6.30.4/grsecurity/grsec_ipc.c 2009-07-30 11:10:49.349503559 -0400
2380c486
JR
31991@@ -0,0 +1,81 @@
31992+#include <linux/kernel.h>
31993+#include <linux/sched.h>
31994+#include <linux/types.h>
31995+#include <linux/ipc.h>
31996+#include <linux/grsecurity.h>
31997+#include <linux/grinternal.h>
31998+
31999+void
32000+gr_log_msgget(const int ret, const int msgflg)
32001+{
32002+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
32003+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
32004+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
32005+ !grsec_enable_group)) && (ret >= 0)
32006+ && (msgflg & IPC_CREAT))
32007+ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
32008+#endif
32009+ return;
32010+}
32011+
32012+void
32013+gr_log_msgrm(const uid_t uid, const uid_t cuid)
32014+{
32015+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
32016+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
32017+ grsec_enable_audit_ipc) ||
32018+ (grsec_enable_audit_ipc && !grsec_enable_group))
32019+ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
32020+#endif
32021+ return;
32022+}
32023+
32024+void
32025+gr_log_semget(const int err, const int semflg)
32026+{
32027+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
32028+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
32029+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
32030+ !grsec_enable_group)) && (err >= 0)
32031+ && (semflg & IPC_CREAT))
32032+ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
32033+#endif
32034+ return;
32035+}
32036+
32037+void
32038+gr_log_semrm(const uid_t uid, const uid_t cuid)
32039+{
32040+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
32041+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
32042+ grsec_enable_audit_ipc) ||
32043+ (grsec_enable_audit_ipc && !grsec_enable_group))
32044+ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
32045+#endif
32046+ return;
32047+}
32048+
32049+void
32050+gr_log_shmget(const int err, const int shmflg, const size_t size)
32051+{
32052+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
32053+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
32054+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
32055+ !grsec_enable_group)) && (err >= 0)
32056+ && (shmflg & IPC_CREAT))
32057+ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
32058+#endif
32059+ return;
32060+}
32061+
32062+void
32063+gr_log_shmrm(const uid_t uid, const uid_t cuid)
32064+{
32065+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
32066+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
32067+ grsec_enable_audit_ipc) ||
32068+ (grsec_enable_audit_ipc && !grsec_enable_group))
32069+ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
32070+#endif
32071+ return;
32072+}
017d2877
AM
32073diff -urNp linux-2.6.30.4/grsecurity/grsec_link.c linux-2.6.30.4/grsecurity/grsec_link.c
32074--- linux-2.6.30.4/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
32075+++ linux-2.6.30.4/grsecurity/grsec_link.c 2009-07-30 11:10:49.349503559 -0400
2380c486
JR
32076@@ -0,0 +1,43 @@
32077+#include <linux/kernel.h>
32078+#include <linux/sched.h>
32079+#include <linux/fs.h>
32080+#include <linux/file.h>
32081+#include <linux/grinternal.h>
32082+
32083+int
32084+gr_handle_follow_link(const struct inode *parent,
32085+ const struct inode *inode,
32086+ const struct dentry *dentry, const struct vfsmount *mnt)
32087+{
32088+#ifdef CONFIG_GRKERNSEC_LINK
32089+ const struct cred *cred = current_cred();
32090+
32091+ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
32092+ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
32093+ (parent->i_mode & S_IWOTH) && (cred->fsuid != inode->i_uid)) {
32094+ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
32095+ return -EACCES;
32096+ }
32097+#endif
32098+ return 0;
32099+}
32100+
32101+int
32102+gr_handle_hardlink(const struct dentry *dentry,
32103+ const struct vfsmount *mnt,
32104+ struct inode *inode, const int mode, const char *to)
32105+{
32106+#ifdef CONFIG_GRKERNSEC_LINK
32107+ const struct cred *cred = current_cred();
32108+
32109+ if (grsec_enable_link && cred->fsuid != inode->i_uid &&
32110+ (!S_ISREG(mode) || (mode & S_ISUID) ||
32111+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
32112+ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
32113+ !capable(CAP_FOWNER) && cred->uid) {
32114+ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
32115+ return -EPERM;
32116+ }
32117+#endif
32118+ return 0;
32119+}
017d2877
AM
32120diff -urNp linux-2.6.30.4/grsecurity/grsec_log.c linux-2.6.30.4/grsecurity/grsec_log.c
32121--- linux-2.6.30.4/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
32122+++ linux-2.6.30.4/grsecurity/grsec_log.c 2009-07-30 11:10:49.350327012 -0400
de855c5d 32123@@ -0,0 +1,288 @@
2380c486
JR
32124+#include <linux/kernel.h>
32125+#include <linux/sched.h>
32126+#include <linux/file.h>
32127+#include <linux/tty.h>
32128+#include <linux/fs.h>
32129+#include <linux/grinternal.h>
32130+
32131+#define BEGIN_LOCKS(x) \
32132+ read_lock(&tasklist_lock); \
32133+ read_lock(&grsec_exec_file_lock); \
32134+ if (x != GR_DO_AUDIT) \
32135+ spin_lock(&grsec_alert_lock); \
32136+ else \
32137+ spin_lock(&grsec_audit_lock)
32138+
32139+#define END_LOCKS(x) \
32140+ if (x != GR_DO_AUDIT) \
32141+ spin_unlock(&grsec_alert_lock); \
32142+ else \
32143+ spin_unlock(&grsec_audit_lock); \
32144+ read_unlock(&grsec_exec_file_lock); \
32145+ read_unlock(&tasklist_lock); \
32146+ if (x == GR_DONT_AUDIT) \
32147+ gr_handle_alertkill(current)
32148+
32149+enum {
32150+ FLOODING,
32151+ NO_FLOODING
32152+};
32153+
32154+extern char *gr_alert_log_fmt;
32155+extern char *gr_audit_log_fmt;
32156+extern char *gr_alert_log_buf;
32157+extern char *gr_audit_log_buf;
32158+
32159+static int gr_log_start(int audit)
32160+{
32161+ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
32162+ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
32163+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
32164+
32165+ if (audit == GR_DO_AUDIT)
32166+ goto set_fmt;
32167+
32168+ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
32169+ grsec_alert_wtime = jiffies;
32170+ grsec_alert_fyet = 0;
32171+ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
32172+ grsec_alert_fyet++;
32173+ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
32174+ grsec_alert_wtime = jiffies;
32175+ grsec_alert_fyet++;
32176+ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
32177+ return FLOODING;
32178+ } else return FLOODING;
32179+
32180+set_fmt:
32181+ memset(buf, 0, PAGE_SIZE);
32182+ if (current->signal->curr_ip && gr_acl_is_enabled()) {
32183+ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
32184+ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
32185+ } else if (current->signal->curr_ip) {
32186+ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
32187+ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
32188+ } else if (gr_acl_is_enabled()) {
32189+ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
32190+ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
32191+ } else {
32192+ sprintf(fmt, "%s%s", loglevel, "grsec: ");
32193+ strcpy(buf, fmt);
32194+ }
32195+
32196+ return NO_FLOODING;
32197+}
32198+
32199+static void gr_log_middle(int audit, const char *msg, va_list ap)
de855c5d
AM
32200+ __attribute__ ((format (printf, 2, 0)));
32201+
32202+static void gr_log_middle(int audit, const char *msg, va_list ap)
2380c486
JR
32203+{
32204+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
32205+ unsigned int len = strlen(buf);
32206+
32207+ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
32208+
32209+ return;
32210+}
32211+
32212+static void gr_log_middle_varargs(int audit, const char *msg, ...)
de855c5d
AM
32213+ __attribute__ ((format (printf, 2, 3)));
32214+
32215+static void gr_log_middle_varargs(int audit, const char *msg, ...)
2380c486
JR
32216+{
32217+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
32218+ unsigned int len = strlen(buf);
32219+ va_list ap;
32220+
32221+ va_start(ap, msg);
32222+ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
32223+ va_end(ap);
32224+
32225+ return;
32226+}
32227+
32228+static void gr_log_end(int audit)
32229+{
32230+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
32231+ unsigned int len = strlen(buf);
32232+
32233+ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current, current_cred(), __task_cred(current->parent)));
32234+ printk("%s\n", buf);
32235+
32236+ return;
32237+}
32238+
32239+void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
32240+{
32241+ int logtype;
32242+ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
32243+ char *str1, *str2, *str3;
32244+ int num1, num2;
32245+ unsigned long ulong1, ulong2;
32246+ struct dentry *dentry;
32247+ struct vfsmount *mnt;
32248+ struct file *file;
32249+ struct task_struct *task;
32250+ const struct cred *cred, *pcred;
32251+ va_list ap;
32252+
32253+ BEGIN_LOCKS(audit);
32254+ logtype = gr_log_start(audit);
32255+ if (logtype == FLOODING) {
32256+ END_LOCKS(audit);
32257+ return;
32258+ }
32259+ va_start(ap, argtypes);
32260+ switch (argtypes) {
32261+ case GR_TTYSNIFF:
32262+ task = va_arg(ap, struct task_struct *);
32263+ 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);
32264+ break;
32265+ case GR_SYSCTL_HIDDEN:
32266+ str1 = va_arg(ap, char *);
32267+ gr_log_middle_varargs(audit, msg, result, str1);
32268+ break;
32269+ case GR_RBAC:
32270+ dentry = va_arg(ap, struct dentry *);
32271+ mnt = va_arg(ap, struct vfsmount *);
32272+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
32273+ break;
32274+ case GR_RBAC_STR:
32275+ dentry = va_arg(ap, struct dentry *);
32276+ mnt = va_arg(ap, struct vfsmount *);
32277+ str1 = va_arg(ap, char *);
32278+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
32279+ break;
32280+ case GR_STR_RBAC:
32281+ str1 = va_arg(ap, char *);
32282+ dentry = va_arg(ap, struct dentry *);
32283+ mnt = va_arg(ap, struct vfsmount *);
32284+ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
32285+ break;
32286+ case GR_RBAC_MODE2:
32287+ dentry = va_arg(ap, struct dentry *);
32288+ mnt = va_arg(ap, struct vfsmount *);
32289+ str1 = va_arg(ap, char *);
32290+ str2 = va_arg(ap, char *);
32291+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
32292+ break;
32293+ case GR_RBAC_MODE3:
32294+ dentry = va_arg(ap, struct dentry *);
32295+ mnt = va_arg(ap, struct vfsmount *);
32296+ str1 = va_arg(ap, char *);
32297+ str2 = va_arg(ap, char *);
32298+ str3 = va_arg(ap, char *);
32299+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
32300+ break;
32301+ case GR_FILENAME:
32302+ dentry = va_arg(ap, struct dentry *);
32303+ mnt = va_arg(ap, struct vfsmount *);
32304+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
32305+ break;
32306+ case GR_STR_FILENAME:
32307+ str1 = va_arg(ap, char *);
32308+ dentry = va_arg(ap, struct dentry *);
32309+ mnt = va_arg(ap, struct vfsmount *);
32310+ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
32311+ break;
32312+ case GR_FILENAME_STR:
32313+ dentry = va_arg(ap, struct dentry *);
32314+ mnt = va_arg(ap, struct vfsmount *);
32315+ str1 = va_arg(ap, char *);
32316+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
32317+ break;
32318+ case GR_FILENAME_TWO_INT:
32319+ dentry = va_arg(ap, struct dentry *);
32320+ mnt = va_arg(ap, struct vfsmount *);
32321+ num1 = va_arg(ap, int);
32322+ num2 = va_arg(ap, int);
32323+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
32324+ break;
32325+ case GR_FILENAME_TWO_INT_STR:
32326+ dentry = va_arg(ap, struct dentry *);
32327+ mnt = va_arg(ap, struct vfsmount *);
32328+ num1 = va_arg(ap, int);
32329+ num2 = va_arg(ap, int);
32330+ str1 = va_arg(ap, char *);
32331+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
32332+ break;
32333+ case GR_TEXTREL:
32334+ file = va_arg(ap, struct file *);
32335+ ulong1 = va_arg(ap, unsigned long);
32336+ ulong2 = va_arg(ap, unsigned long);
32337+ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
32338+ break;
32339+ case GR_PTRACE:
32340+ task = va_arg(ap, struct task_struct *);
32341+ 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);
32342+ break;
32343+ case GR_RESOURCE:
32344+ task = va_arg(ap, struct task_struct *);
32345+ cred = __task_cred(task);
32346+ pcred = __task_cred(task->parent);
32347+ ulong1 = va_arg(ap, unsigned long);
32348+ str1 = va_arg(ap, char *);
32349+ ulong2 = va_arg(ap, unsigned long);
32350+ 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);
32351+ break;
32352+ case GR_CAP:
32353+ task = va_arg(ap, struct task_struct *);
32354+ cred = __task_cred(task);
32355+ pcred = __task_cred(task->parent);
32356+ str1 = va_arg(ap, char *);
32357+ 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);
32358+ break;
32359+ case GR_SIG:
32360+ task = va_arg(ap, struct task_struct *);
32361+ cred = __task_cred(task);
32362+ pcred = __task_cred(task->parent);
32363+ num1 = va_arg(ap, int);
32364+ 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);
32365+ break;
32366+ case GR_CRASH1:
32367+ task = va_arg(ap, struct task_struct *);
32368+ cred = __task_cred(task);
32369+ pcred = __task_cred(task->parent);
32370+ ulong1 = va_arg(ap, unsigned long);
32371+ 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);
32372+ break;
32373+ case GR_CRASH2:
32374+ task = va_arg(ap, struct task_struct *);
32375+ cred = __task_cred(task);
32376+ pcred = __task_cred(task->parent);
32377+ ulong1 = va_arg(ap, unsigned long);
32378+ 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);
32379+ break;
32380+ case GR_PSACCT:
32381+ {
32382+ unsigned int wday, cday;
32383+ __u8 whr, chr;
32384+ __u8 wmin, cmin;
32385+ __u8 wsec, csec;
32386+ char cur_tty[64] = { 0 };
32387+ char parent_tty[64] = { 0 };
32388+
32389+ task = va_arg(ap, struct task_struct *);
32390+ wday = va_arg(ap, unsigned int);
32391+ cday = va_arg(ap, unsigned int);
32392+ whr = va_arg(ap, int);
32393+ chr = va_arg(ap, int);
32394+ wmin = va_arg(ap, int);
32395+ cmin = va_arg(ap, int);
32396+ wsec = va_arg(ap, int);
32397+ csec = va_arg(ap, int);
32398+ ulong1 = va_arg(ap, unsigned long);
32399+ cred = __task_cred(task);
32400+ pcred = __task_cred(task->parent);
32401+
32402+ 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);
32403+ }
32404+ break;
32405+ default:
32406+ gr_log_middle(audit, msg, ap);
32407+ }
32408+ va_end(ap);
32409+ gr_log_end(audit);
32410+ END_LOCKS(audit);
32411+}
017d2877
AM
32412diff -urNp linux-2.6.30.4/grsecurity/grsec_mem.c linux-2.6.30.4/grsecurity/grsec_mem.c
32413--- linux-2.6.30.4/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
32414+++ linux-2.6.30.4/grsecurity/grsec_mem.c 2009-07-30 11:10:49.350327012 -0400
2380c486
JR
32415@@ -0,0 +1,71 @@
32416+#include <linux/kernel.h>
32417+#include <linux/sched.h>
32418+#include <linux/mm.h>
32419+#include <linux/mman.h>
32420+#include <linux/grinternal.h>
32421+
32422+void
32423+gr_handle_ioperm(void)
32424+{
32425+ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
32426+ return;
32427+}
32428+
32429+void
32430+gr_handle_iopl(void)
32431+{
32432+ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
32433+ return;
32434+}
32435+
32436+void
32437+gr_handle_mem_write(void)
32438+{
32439+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
32440+ return;
32441+}
32442+
32443+void
32444+gr_handle_kmem_write(void)
32445+{
32446+ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
32447+ return;
32448+}
32449+
32450+void
32451+gr_handle_open_port(void)
32452+{
32453+ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
32454+ return;
32455+}
32456+
32457+int
32458+gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
32459+{
32460+ unsigned long start, end;
32461+
32462+ start = offset;
32463+ end = start + vma->vm_end - vma->vm_start;
32464+
32465+ if (start > end) {
32466+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
32467+ return -EPERM;
32468+ }
32469+
32470+ /* allowed ranges : ISA I/O BIOS */
32471+ if ((start >= __pa(high_memory))
32472+#ifdef CONFIG_X86
32473+ || (start >= 0x000a0000 && end <= 0x00100000)
32474+ || (start >= 0x00000000 && end <= 0x00001000)
32475+#endif
32476+ )
32477+ return 0;
32478+
32479+ if (vma->vm_flags & VM_WRITE) {
32480+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
32481+ return -EPERM;
32482+ } else
32483+ vma->vm_flags &= ~VM_MAYWRITE;
32484+
32485+ return 0;
32486+}
017d2877
AM
32487diff -urNp linux-2.6.30.4/grsecurity/grsec_mount.c linux-2.6.30.4/grsecurity/grsec_mount.c
32488--- linux-2.6.30.4/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
32489+++ linux-2.6.30.4/grsecurity/grsec_mount.c 2009-07-30 11:10:49.350327012 -0400
2380c486
JR
32490@@ -0,0 +1,34 @@
32491+#include <linux/kernel.h>
32492+#include <linux/sched.h>
32493+#include <linux/grsecurity.h>
32494+#include <linux/grinternal.h>
32495+
32496+void
32497+gr_log_remount(const char *devname, const int retval)
32498+{
32499+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
32500+ if (grsec_enable_mount && (retval >= 0))
32501+ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
32502+#endif
32503+ return;
32504+}
32505+
32506+void
32507+gr_log_unmount(const char *devname, const int retval)
32508+{
32509+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
32510+ if (grsec_enable_mount && (retval >= 0))
32511+ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
32512+#endif
32513+ return;
32514+}
32515+
32516+void
32517+gr_log_mount(const char *from, const char *to, const int retval)
32518+{
32519+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
32520+ if (grsec_enable_mount && (retval >= 0))
32521+ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
32522+#endif
32523+ return;
32524+}
017d2877
AM
32525diff -urNp linux-2.6.30.4/grsecurity/grsec_sig.c linux-2.6.30.4/grsecurity/grsec_sig.c
32526--- linux-2.6.30.4/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
32527+++ linux-2.6.30.4/grsecurity/grsec_sig.c 2009-07-30 11:10:49.350327012 -0400
2380c486
JR
32528@@ -0,0 +1,58 @@
32529+#include <linux/kernel.h>
32530+#include <linux/sched.h>
32531+#include <linux/delay.h>
32532+#include <linux/grsecurity.h>
32533+#include <linux/grinternal.h>
32534+
32535+void
32536+gr_log_signal(const int sig, const struct task_struct *t)
32537+{
32538+#ifdef CONFIG_GRKERNSEC_SIGNAL
32539+ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
32540+ (sig == SIGABRT) || (sig == SIGBUS))) {
32541+ if (t->pid == current->pid) {
32542+ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
32543+ } else {
32544+ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
32545+ }
32546+ }
32547+#endif
32548+ return;
32549+}
32550+
32551+int
32552+gr_handle_signal(const struct task_struct *p, const int sig)
32553+{
32554+#ifdef CONFIG_GRKERNSEC
32555+ if (current->pid > 1 && gr_check_protected_task(p)) {
32556+ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
32557+ return -EPERM;
32558+ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
32559+ return -EPERM;
32560+ }
32561+#endif
32562+ return 0;
32563+}
32564+
32565+void gr_handle_brute_attach(struct task_struct *p)
32566+{
32567+#ifdef CONFIG_GRKERNSEC_BRUTE
32568+ read_lock(&tasklist_lock);
32569+ read_lock(&grsec_exec_file_lock);
32570+ if (p->parent && p->parent->exec_file == p->exec_file)
32571+ p->parent->brute = 1;
32572+ read_unlock(&grsec_exec_file_lock);
32573+ read_unlock(&tasklist_lock);
32574+#endif
32575+ return;
32576+}
32577+
32578+void gr_handle_brute_check(void)
32579+{
32580+#ifdef CONFIG_GRKERNSEC_BRUTE
32581+ if (current->brute)
32582+ msleep(30 * 1000);
32583+#endif
32584+ return;
32585+}
32586+
017d2877
AM
32587diff -urNp linux-2.6.30.4/grsecurity/grsec_sock.c linux-2.6.30.4/grsecurity/grsec_sock.c
32588--- linux-2.6.30.4/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
32589+++ linux-2.6.30.4/grsecurity/grsec_sock.c 2009-07-30 11:10:49.350327012 -0400
2380c486
JR
32590@@ -0,0 +1,269 @@
32591+#include <linux/kernel.h>
32592+#include <linux/module.h>
32593+#include <linux/sched.h>
32594+#include <linux/file.h>
32595+#include <linux/net.h>
32596+#include <linux/in.h>
32597+#include <linux/ip.h>
32598+#include <net/sock.h>
32599+#include <net/inet_sock.h>
32600+#include <linux/grsecurity.h>
32601+#include <linux/grinternal.h>
32602+#include <linux/gracl.h>
32603+
32604+kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
32605+EXPORT_SYMBOL(gr_cap_rtnetlink);
32606+
32607+extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
32608+extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
32609+
32610+EXPORT_SYMBOL(gr_search_udp_recvmsg);
32611+EXPORT_SYMBOL(gr_search_udp_sendmsg);
32612+
32613+#ifdef CONFIG_UNIX_MODULE
32614+EXPORT_SYMBOL(gr_acl_handle_unix);
32615+EXPORT_SYMBOL(gr_acl_handle_mknod);
32616+EXPORT_SYMBOL(gr_handle_chroot_unix);
32617+EXPORT_SYMBOL(gr_handle_create);
32618+#endif
32619+
32620+#ifdef CONFIG_GRKERNSEC
32621+#define gr_conn_table_size 32749
32622+struct conn_table_entry {
32623+ struct conn_table_entry *next;
32624+ struct signal_struct *sig;
32625+};
32626+
32627+struct conn_table_entry *gr_conn_table[gr_conn_table_size];
32628+DEFINE_SPINLOCK(gr_conn_table_lock);
32629+
32630+extern const char * gr_socktype_to_name(unsigned char type);
32631+extern const char * gr_proto_to_name(unsigned char proto);
32632+
32633+static __inline__ int
32634+conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
32635+{
32636+ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
32637+}
32638+
32639+static __inline__ int
32640+conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
32641+ __u16 sport, __u16 dport)
32642+{
32643+ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
32644+ sig->gr_sport == sport && sig->gr_dport == dport))
32645+ return 1;
32646+ else
32647+ return 0;
32648+}
32649+
32650+static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
32651+{
32652+ struct conn_table_entry **match;
32653+ unsigned int index;
32654+
32655+ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
32656+ sig->gr_sport, sig->gr_dport,
32657+ gr_conn_table_size);
32658+
32659+ newent->sig = sig;
32660+
32661+ match = &gr_conn_table[index];
32662+ newent->next = *match;
32663+ *match = newent;
32664+
32665+ return;
32666+}
32667+
32668+static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
32669+{
32670+ struct conn_table_entry *match, *last = NULL;
32671+ unsigned int index;
32672+
32673+ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
32674+ sig->gr_sport, sig->gr_dport,
32675+ gr_conn_table_size);
32676+
32677+ match = gr_conn_table[index];
32678+ while (match && !conn_match(match->sig,
32679+ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
32680+ sig->gr_dport)) {
32681+ last = match;
32682+ match = match->next;
32683+ }
32684+
32685+ if (match) {
32686+ if (last)
32687+ last->next = match->next;
32688+ else
32689+ gr_conn_table[index] = NULL;
32690+ kfree(match);
32691+ }
32692+
32693+ return;
32694+}
32695+
32696+static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
32697+ __u16 sport, __u16 dport)
32698+{
32699+ struct conn_table_entry *match;
32700+ unsigned int index;
32701+
32702+ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
32703+
32704+ match = gr_conn_table[index];
32705+ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
32706+ match = match->next;
32707+
32708+ if (match)
32709+ return match->sig;
32710+ else
32711+ return NULL;
32712+}
32713+
32714+#endif
32715+
32716+void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
32717+{
32718+#ifdef CONFIG_GRKERNSEC
32719+ struct signal_struct *sig = task->signal;
32720+ struct conn_table_entry *newent;
32721+
32722+ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
32723+ if (newent == NULL)
32724+ return;
32725+ /* no bh lock needed since we are called with bh disabled */
32726+ spin_lock(&gr_conn_table_lock);
32727+ gr_del_task_from_ip_table_nolock(sig);
32728+ sig->gr_saddr = inet->rcv_saddr;
32729+ sig->gr_daddr = inet->daddr;
32730+ sig->gr_sport = inet->sport;
32731+ sig->gr_dport = inet->dport;
32732+ gr_add_to_task_ip_table_nolock(sig, newent);
32733+ spin_unlock(&gr_conn_table_lock);
32734+#endif
32735+ return;
32736+}
32737+
32738+void gr_del_task_from_ip_table(struct task_struct *task)
32739+{
32740+#ifdef CONFIG_GRKERNSEC
32741+ spin_lock_bh(&gr_conn_table_lock);
32742+ gr_del_task_from_ip_table_nolock(task->signal);
32743+ spin_unlock_bh(&gr_conn_table_lock);
32744+#endif
32745+ return;
32746+}
32747+
32748+void
32749+gr_attach_curr_ip(const struct sock *sk)
32750+{
32751+#ifdef CONFIG_GRKERNSEC
32752+ struct signal_struct *p, *set;
32753+ const struct inet_sock *inet = inet_sk(sk);
32754+
32755+ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
32756+ return;
32757+
32758+ set = current->signal;
32759+
32760+ spin_lock_bh(&gr_conn_table_lock);
32761+ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
32762+ inet->dport, inet->sport);
32763+ if (unlikely(p != NULL)) {
32764+ set->curr_ip = p->curr_ip;
32765+ set->used_accept = 1;
32766+ gr_del_task_from_ip_table_nolock(p);
32767+ spin_unlock_bh(&gr_conn_table_lock);
32768+ return;
32769+ }
32770+ spin_unlock_bh(&gr_conn_table_lock);
32771+
32772+ set->curr_ip = inet->daddr;
32773+ set->used_accept = 1;
32774+#endif
32775+ return;
32776+}
32777+
32778+int
32779+gr_handle_sock_all(const int family, const int type, const int protocol)
32780+{
32781+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
32782+ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
32783+ (family != AF_UNIX) && (family != AF_LOCAL)) {
32784+ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
32785+ return -EACCES;
32786+ }
32787+#endif
32788+ return 0;
32789+}
32790+
32791+int
32792+gr_handle_sock_server(const struct sockaddr *sck)
32793+{
32794+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
32795+ if (grsec_enable_socket_server &&
32796+ in_group_p(grsec_socket_server_gid) &&
32797+ sck && (sck->sa_family != AF_UNIX) &&
32798+ (sck->sa_family != AF_LOCAL)) {
32799+ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
32800+ return -EACCES;
32801+ }
32802+#endif
32803+ return 0;
32804+}
32805+
32806+int
32807+gr_handle_sock_server_other(const struct sock *sck)
32808+{
32809+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
32810+ if (grsec_enable_socket_server &&
32811+ in_group_p(grsec_socket_server_gid) &&
32812+ sck && (sck->sk_family != AF_UNIX) &&
32813+ (sck->sk_family != AF_LOCAL)) {
32814+ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
32815+ return -EACCES;
32816+ }
32817+#endif
32818+ return 0;
32819+}
32820+
32821+int
32822+gr_handle_sock_client(const struct sockaddr *sck)
32823+{
32824+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
32825+ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
32826+ sck && (sck->sa_family != AF_UNIX) &&
32827+ (sck->sa_family != AF_LOCAL)) {
32828+ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
32829+ return -EACCES;
32830+ }
32831+#endif
32832+ return 0;
32833+}
32834+
32835+kernel_cap_t
32836+gr_cap_rtnetlink(struct sock *sock)
32837+{
32838+#ifdef CONFIG_GRKERNSEC
32839+ if (!gr_acl_is_enabled())
32840+ return current_cap();
32841+ else if (sock->sk_protocol == NETLINK_ISCSI &&
32842+ cap_raised(current_cap(), CAP_SYS_ADMIN) &&
32843+ gr_is_capable(CAP_SYS_ADMIN))
32844+ return current_cap();
32845+ else if (sock->sk_protocol == NETLINK_AUDIT &&
32846+ cap_raised(current_cap(), CAP_AUDIT_WRITE) &&
32847+ gr_is_capable(CAP_AUDIT_WRITE) &&
32848+ cap_raised(current_cap(), CAP_AUDIT_CONTROL) &&
32849+ gr_is_capable(CAP_AUDIT_CONTROL))
32850+ return current_cap();
32851+ else if (cap_raised(current_cap(), CAP_NET_ADMIN) &&
32852+ gr_is_capable(CAP_NET_ADMIN))
32853+ return current_cap();
32854+ else
32855+ return __cap_empty_set;
32856+#else
32857+ return current_cap();
32858+#endif
32859+}
017d2877
AM
32860diff -urNp linux-2.6.30.4/grsecurity/grsec_sysctl.c linux-2.6.30.4/grsecurity/grsec_sysctl.c
32861--- linux-2.6.30.4/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
32862+++ linux-2.6.30.4/grsecurity/grsec_sysctl.c 2009-07-30 11:10:49.351429069 -0400
2380c486
JR
32863@@ -0,0 +1,435 @@
32864+#include <linux/kernel.h>
32865+#include <linux/sched.h>
32866+#include <linux/sysctl.h>
32867+#include <linux/grsecurity.h>
32868+#include <linux/grinternal.h>
32869+
32870+#ifdef CONFIG_GRKERNSEC_MODSTOP
32871+int grsec_modstop;
32872+#endif
32873+
32874+int
32875+gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
32876+{
32877+#ifdef CONFIG_GRKERNSEC_SYSCTL
32878+ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
32879+ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
32880+ return -EACCES;
32881+ }
32882+#endif
32883+#ifdef CONFIG_GRKERNSEC_MODSTOP
32884+ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
32885+ grsec_modstop && (op & MAY_WRITE)) {
32886+ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
32887+ return -EACCES;
32888+ }
32889+#endif
32890+ return 0;
32891+}
32892+
32893+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
32894+ctl_table grsecurity_table[] = {
32895+#ifdef CONFIG_GRKERNSEC_SYSCTL
32896+#ifdef CONFIG_GRKERNSEC_LINK
32897+ {
32898+ .ctl_name = CTL_UNNUMBERED,
32899+ .procname = "linking_restrictions",
32900+ .data = &grsec_enable_link,
32901+ .maxlen = sizeof(int),
32902+ .mode = 0600,
32903+ .proc_handler = &proc_dointvec,
32904+ },
32905+#endif
32906+#ifdef CONFIG_GRKERNSEC_FIFO
32907+ {
32908+ .ctl_name = CTL_UNNUMBERED,
32909+ .procname = "fifo_restrictions",
32910+ .data = &grsec_enable_fifo,
32911+ .maxlen = sizeof(int),
32912+ .mode = 0600,
32913+ .proc_handler = &proc_dointvec,
32914+ },
32915+#endif
32916+#ifdef CONFIG_GRKERNSEC_EXECVE
32917+ {
32918+ .ctl_name = CTL_UNNUMBERED,
32919+ .procname = "execve_limiting",
32920+ .data = &grsec_enable_execve,
32921+ .maxlen = sizeof(int),
32922+ .mode = 0600,
32923+ .proc_handler = &proc_dointvec,
32924+ },
32925+#endif
32926+#ifdef CONFIG_GRKERNSEC_EXECLOG
32927+ {
32928+ .ctl_name = CTL_UNNUMBERED,
32929+ .procname = "exec_logging",
32930+ .data = &grsec_enable_execlog,
32931+ .maxlen = sizeof(int),
32932+ .mode = 0600,
32933+ .proc_handler = &proc_dointvec,
32934+ },
32935+#endif
32936+#ifdef CONFIG_GRKERNSEC_SIGNAL
32937+ {
32938+ .ctl_name = CTL_UNNUMBERED,
32939+ .procname = "signal_logging",
32940+ .data = &grsec_enable_signal,
32941+ .maxlen = sizeof(int),
32942+ .mode = 0600,
32943+ .proc_handler = &proc_dointvec,
32944+ },
32945+#endif
32946+#ifdef CONFIG_GRKERNSEC_FORKFAIL
32947+ {
32948+ .ctl_name = CTL_UNNUMBERED,
32949+ .procname = "forkfail_logging",
32950+ .data = &grsec_enable_forkfail,
32951+ .maxlen = sizeof(int),
32952+ .mode = 0600,
32953+ .proc_handler = &proc_dointvec,
32954+ },
32955+#endif
32956+#ifdef CONFIG_GRKERNSEC_TIME
32957+ {
32958+ .ctl_name = CTL_UNNUMBERED,
32959+ .procname = "timechange_logging",
32960+ .data = &grsec_enable_time,
32961+ .maxlen = sizeof(int),
32962+ .mode = 0600,
32963+ .proc_handler = &proc_dointvec,
32964+ },
32965+#endif
32966+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
32967+ {
32968+ .ctl_name = CTL_UNNUMBERED,
32969+ .procname = "chroot_deny_shmat",
32970+ .data = &grsec_enable_chroot_shmat,
32971+ .maxlen = sizeof(int),
32972+ .mode = 0600,
32973+ .proc_handler = &proc_dointvec,
32974+ },
32975+#endif
32976+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
32977+ {
32978+ .ctl_name = CTL_UNNUMBERED,
32979+ .procname = "chroot_deny_unix",
32980+ .data = &grsec_enable_chroot_unix,
32981+ .maxlen = sizeof(int),
32982+ .mode = 0600,
32983+ .proc_handler = &proc_dointvec,
32984+ },
32985+#endif
32986+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
32987+ {
32988+ .ctl_name = CTL_UNNUMBERED,
32989+ .procname = "chroot_deny_mount",
32990+ .data = &grsec_enable_chroot_mount,
32991+ .maxlen = sizeof(int),
32992+ .mode = 0600,
32993+ .proc_handler = &proc_dointvec,
32994+ },
32995+#endif
32996+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
32997+ {
32998+ .ctl_name = CTL_UNNUMBERED,
32999+ .procname = "chroot_deny_fchdir",
33000+ .data = &grsec_enable_chroot_fchdir,
33001+ .maxlen = sizeof(int),
33002+ .mode = 0600,
33003+ .proc_handler = &proc_dointvec,
33004+ },
33005+#endif
33006+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
33007+ {
33008+ .ctl_name = CTL_UNNUMBERED,
33009+ .procname = "chroot_deny_chroot",
33010+ .data = &grsec_enable_chroot_double,
33011+ .maxlen = sizeof(int),
33012+ .mode = 0600,
33013+ .proc_handler = &proc_dointvec,
33014+ },
33015+#endif
33016+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
33017+ {
33018+ .ctl_name = CTL_UNNUMBERED,
33019+ .procname = "chroot_deny_pivot",
33020+ .data = &grsec_enable_chroot_pivot,
33021+ .maxlen = sizeof(int),
33022+ .mode = 0600,
33023+ .proc_handler = &proc_dointvec,
33024+ },
33025+#endif
33026+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
33027+ {
33028+ .ctl_name = CTL_UNNUMBERED,
33029+ .procname = "chroot_enforce_chdir",
33030+ .data = &grsec_enable_chroot_chdir,
33031+ .maxlen = sizeof(int),
33032+ .mode = 0600,
33033+ .proc_handler = &proc_dointvec,
33034+ },
33035+#endif
33036+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
33037+ {
33038+ .ctl_name = CTL_UNNUMBERED,
33039+ .procname = "chroot_deny_chmod",
33040+ .data = &grsec_enable_chroot_chmod,
33041+ .maxlen = sizeof(int),
33042+ .mode = 0600,
33043+ .proc_handler = &proc_dointvec,
33044+ },
33045+#endif
33046+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
33047+ {
33048+ .ctl_name = CTL_UNNUMBERED,
33049+ .procname = "chroot_deny_mknod",
33050+ .data = &grsec_enable_chroot_mknod,
33051+ .maxlen = sizeof(int),
33052+ .mode = 0600,
33053+ .proc_handler = &proc_dointvec,
33054+ },
33055+#endif
33056+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
33057+ {
33058+ .ctl_name = CTL_UNNUMBERED,
33059+ .procname = "chroot_restrict_nice",
33060+ .data = &grsec_enable_chroot_nice,
33061+ .maxlen = sizeof(int),
33062+ .mode = 0600,
33063+ .proc_handler = &proc_dointvec,
33064+ },
33065+#endif
33066+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
33067+ {
33068+ .ctl_name = CTL_UNNUMBERED,
33069+ .procname = "chroot_execlog",
33070+ .data = &grsec_enable_chroot_execlog,
33071+ .maxlen = sizeof(int),
33072+ .mode = 0600,
33073+ .proc_handler = &proc_dointvec,
33074+ },
33075+#endif
33076+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
33077+ {
33078+ .ctl_name = CTL_UNNUMBERED,
33079+ .procname = "chroot_caps",
33080+ .data = &grsec_enable_chroot_caps,
33081+ .maxlen = sizeof(int),
33082+ .mode = 0600,
33083+ .proc_handler = &proc_dointvec,
33084+ },
33085+#endif
33086+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
33087+ {
33088+ .ctl_name = CTL_UNNUMBERED,
33089+ .procname = "chroot_deny_sysctl",
33090+ .data = &grsec_enable_chroot_sysctl,
33091+ .maxlen = sizeof(int),
33092+ .mode = 0600,
33093+ .proc_handler = &proc_dointvec,
33094+ },
33095+#endif
33096+#ifdef CONFIG_GRKERNSEC_TPE
33097+ {
33098+ .ctl_name = CTL_UNNUMBERED,
33099+ .procname = "tpe",
33100+ .data = &grsec_enable_tpe,
33101+ .maxlen = sizeof(int),
33102+ .mode = 0600,
33103+ .proc_handler = &proc_dointvec,
33104+ },
33105+ {
33106+ .ctl_name = CTL_UNNUMBERED,
33107+ .procname = "tpe_gid",
33108+ .data = &grsec_tpe_gid,
33109+ .maxlen = sizeof(int),
33110+ .mode = 0600,
33111+ .proc_handler = &proc_dointvec,
33112+ },
33113+#endif
33114+#ifdef CONFIG_GRKERNSEC_TPE_ALL
33115+ {
33116+ .ctl_name = CTL_UNNUMBERED,
33117+ .procname = "tpe_restrict_all",
33118+ .data = &grsec_enable_tpe_all,
33119+ .maxlen = sizeof(int),
33120+ .mode = 0600,
33121+ .proc_handler = &proc_dointvec,
33122+ },
33123+#endif
33124+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
33125+ {
33126+ .ctl_name = CTL_UNNUMBERED,
33127+ .procname = "socket_all",
33128+ .data = &grsec_enable_socket_all,
33129+ .maxlen = sizeof(int),
33130+ .mode = 0600,
33131+ .proc_handler = &proc_dointvec,
33132+ },
33133+ {
33134+ .ctl_name = CTL_UNNUMBERED,
33135+ .procname = "socket_all_gid",
33136+ .data = &grsec_socket_all_gid,
33137+ .maxlen = sizeof(int),
33138+ .mode = 0600,
33139+ .proc_handler = &proc_dointvec,
33140+ },
33141+#endif
33142+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
33143+ {
33144+ .ctl_name = CTL_UNNUMBERED,
33145+ .procname = "socket_client",
33146+ .data = &grsec_enable_socket_client,
33147+ .maxlen = sizeof(int),
33148+ .mode = 0600,
33149+ .proc_handler = &proc_dointvec,
33150+ },
33151+ {
33152+ .ctl_name = CTL_UNNUMBERED,
33153+ .procname = "socket_client_gid",
33154+ .data = &grsec_socket_client_gid,
33155+ .maxlen = sizeof(int),
33156+ .mode = 0600,
33157+ .proc_handler = &proc_dointvec,
33158+ },
33159+#endif
33160+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
33161+ {
33162+ .ctl_name = CTL_UNNUMBERED,
33163+ .procname = "socket_server",
33164+ .data = &grsec_enable_socket_server,
33165+ .maxlen = sizeof(int),
33166+ .mode = 0600,
33167+ .proc_handler = &proc_dointvec,
33168+ },
33169+ {
33170+ .ctl_name = CTL_UNNUMBERED,
33171+ .procname = "socket_server_gid",
33172+ .data = &grsec_socket_server_gid,
33173+ .maxlen = sizeof(int),
33174+ .mode = 0600,
33175+ .proc_handler = &proc_dointvec,
33176+ },
33177+#endif
33178+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
33179+ {
33180+ .ctl_name = CTL_UNNUMBERED,
33181+ .procname = "audit_group",
33182+ .data = &grsec_enable_group,
33183+ .maxlen = sizeof(int),
33184+ .mode = 0600,
33185+ .proc_handler = &proc_dointvec,
33186+ },
33187+ {
33188+ .ctl_name = CTL_UNNUMBERED,
33189+ .procname = "audit_gid",
33190+ .data = &grsec_audit_gid,
33191+ .maxlen = sizeof(int),
33192+ .mode = 0600,
33193+ .proc_handler = &proc_dointvec,
33194+ },
33195+#endif
33196+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
33197+ {
33198+ .ctl_name = CTL_UNNUMBERED,
33199+ .procname = "audit_chdir",
33200+ .data = &grsec_enable_chdir,
33201+ .maxlen = sizeof(int),
33202+ .mode = 0600,
33203+ .proc_handler = &proc_dointvec,
33204+ },
33205+#endif
33206+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
33207+ {
33208+ .ctl_name = CTL_UNNUMBERED,
33209+ .procname = "audit_mount",
33210+ .data = &grsec_enable_mount,
33211+ .maxlen = sizeof(int),
33212+ .mode = 0600,
33213+ .proc_handler = &proc_dointvec,
33214+ },
33215+#endif
33216+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
33217+ {
33218+ .ctl_name = CTL_UNNUMBERED,
33219+ .procname = "audit_ipc",
33220+ .data = &grsec_enable_audit_ipc,
33221+ .maxlen = sizeof(int),
33222+ .mode = 0600,
33223+ .proc_handler = &proc_dointvec,
33224+ },
33225+#endif
33226+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
33227+ {
33228+ .ctl_name = CTL_UNNUMBERED,
33229+ .procname = "audit_textrel",
33230+ .data = &grsec_enable_audit_textrel,
33231+ .maxlen = sizeof(int),
33232+ .mode = 0600,
33233+ .proc_handler = &proc_dointvec,
33234+ },
33235+#endif
33236+#ifdef CONFIG_GRKERNSEC_DMESG
33237+ {
33238+ .ctl_name = CTL_UNNUMBERED,
33239+ .procname = "dmesg",
33240+ .data = &grsec_enable_dmesg,
33241+ .maxlen = sizeof(int),
33242+ .mode = 0600,
33243+ .proc_handler = &proc_dointvec,
33244+ },
33245+#endif
33246+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
33247+ {
33248+ .ctl_name = CTL_UNNUMBERED,
33249+ .procname = "chroot_findtask",
33250+ .data = &grsec_enable_chroot_findtask,
33251+ .maxlen = sizeof(int),
33252+ .mode = 0600,
33253+ .proc_handler = &proc_dointvec,
33254+ },
33255+#endif
33256+#ifdef CONFIG_GRKERNSEC_RESLOG
33257+ {
33258+ .ctl_name = CTL_UNNUMBERED,
33259+ .procname = "resource_logging",
33260+ .data = &grsec_resource_logging,
33261+ .maxlen = sizeof(int),
33262+ .mode = 0600,
33263+ .proc_handler = &proc_dointvec,
33264+ },
33265+#endif
33266+ {
33267+ .ctl_name = CTL_UNNUMBERED,
33268+ .procname = "grsec_lock",
33269+ .data = &grsec_lock,
33270+ .maxlen = sizeof(int),
33271+ .mode = 0600,
33272+ .proc_handler = &proc_dointvec,
33273+ },
33274+#endif
33275+#ifdef CONFIG_GRKERNSEC_MODSTOP
33276+ {
33277+ .ctl_name = CTL_UNNUMBERED,
33278+ .procname = "disable_modules",
33279+ .data = &grsec_modstop,
33280+ .maxlen = sizeof(int),
33281+ .mode = 0600,
33282+ .proc_handler = &proc_dointvec,
33283+ },
33284+#endif
33285+ { .ctl_name = 0 }
33286+};
33287+#endif
33288+
33289+int gr_check_modstop(void)
33290+{
33291+#ifdef CONFIG_GRKERNSEC_MODSTOP
33292+ if (grsec_modstop == 1) {
33293+ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
33294+ return 1;
33295+ }
33296+#endif
33297+ return 0;
33298+}
017d2877
AM
33299diff -urNp linux-2.6.30.4/grsecurity/grsec_textrel.c linux-2.6.30.4/grsecurity/grsec_textrel.c
33300--- linux-2.6.30.4/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
33301+++ linux-2.6.30.4/grsecurity/grsec_textrel.c 2009-07-30 11:10:49.351429069 -0400
2380c486
JR
33302@@ -0,0 +1,16 @@
33303+#include <linux/kernel.h>
33304+#include <linux/sched.h>
33305+#include <linux/mm.h>
33306+#include <linux/file.h>
33307+#include <linux/grinternal.h>
33308+#include <linux/grsecurity.h>
33309+
33310+void
33311+gr_log_textrel(struct vm_area_struct * vma)
33312+{
33313+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
33314+ if (grsec_enable_audit_textrel)
33315+ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
33316+#endif
33317+ return;
33318+}
017d2877
AM
33319diff -urNp linux-2.6.30.4/grsecurity/grsec_time.c linux-2.6.30.4/grsecurity/grsec_time.c
33320--- linux-2.6.30.4/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
33321+++ linux-2.6.30.4/grsecurity/grsec_time.c 2009-07-30 11:10:49.351429069 -0400
2380c486
JR
33322@@ -0,0 +1,13 @@
33323+#include <linux/kernel.h>
33324+#include <linux/sched.h>
33325+#include <linux/grinternal.h>
33326+
33327+void
33328+gr_log_timechange(void)
33329+{
33330+#ifdef CONFIG_GRKERNSEC_TIME
33331+ if (grsec_enable_time)
33332+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
33333+#endif
33334+ return;
33335+}
017d2877
AM
33336diff -urNp linux-2.6.30.4/grsecurity/grsec_tpe.c linux-2.6.30.4/grsecurity/grsec_tpe.c
33337--- linux-2.6.30.4/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
33338+++ linux-2.6.30.4/grsecurity/grsec_tpe.c 2009-07-30 11:10:49.351429069 -0400
2380c486
JR
33339@@ -0,0 +1,38 @@
33340+#include <linux/kernel.h>
33341+#include <linux/sched.h>
33342+#include <linux/file.h>
33343+#include <linux/fs.h>
33344+#include <linux/grinternal.h>
33345+
33346+extern int gr_acl_tpe_check(void);
33347+
33348+int
33349+gr_tpe_allow(const struct file *file)
33350+{
33351+#ifdef CONFIG_GRKERNSEC
33352+ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
33353+ const struct cred *cred = current_cred();
33354+
33355+ if (cred->uid && ((grsec_enable_tpe &&
33356+#ifdef CONFIG_GRKERNSEC_TPE_INVERT
33357+ !in_group_p(grsec_tpe_gid)
33358+#else
33359+ in_group_p(grsec_tpe_gid)
33360+#endif
33361+ ) || gr_acl_tpe_check()) &&
33362+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
33363+ (inode->i_mode & S_IWOTH))))) {
33364+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
33365+ return 0;
33366+ }
33367+#ifdef CONFIG_GRKERNSEC_TPE_ALL
33368+ if (cred->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
33369+ ((inode->i_uid && (inode->i_uid != cred->uid)) ||
33370+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
33371+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
33372+ return 0;
33373+ }
33374+#endif
33375+#endif
33376+ return 1;
33377+}
017d2877
AM
33378diff -urNp linux-2.6.30.4/grsecurity/grsum.c linux-2.6.30.4/grsecurity/grsum.c
33379--- linux-2.6.30.4/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
33380+++ linux-2.6.30.4/grsecurity/grsum.c 2009-07-30 11:10:49.351429069 -0400
2380c486
JR
33381@@ -0,0 +1,59 @@
33382+#include <linux/err.h>
33383+#include <linux/kernel.h>
33384+#include <linux/sched.h>
33385+#include <linux/mm.h>
33386+#include <linux/scatterlist.h>
33387+#include <linux/crypto.h>
33388+#include <linux/gracl.h>
33389+
33390+
33391+#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
33392+#error "crypto and sha256 must be built into the kernel"
33393+#endif
33394+
33395+int
33396+chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
33397+{
33398+ char *p;
33399+ struct crypto_hash *tfm;
33400+ struct hash_desc desc;
33401+ struct scatterlist sg;
33402+ unsigned char temp_sum[GR_SHA_LEN];
33403+ volatile int retval = 0;
33404+ volatile int dummy = 0;
33405+ unsigned int i;
33406+
33407+ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
33408+ if (IS_ERR(tfm)) {
33409+ /* should never happen, since sha256 should be built in */
33410+ return 1;
33411+ }
33412+
33413+ desc.tfm = tfm;
33414+ desc.flags = 0;
33415+
33416+ crypto_hash_init(&desc);
33417+
33418+ p = salt;
33419+ sg_set_buf(&sg, p, GR_SALT_LEN);
33420+ crypto_hash_update(&desc, &sg, sg.length);
33421+
33422+ p = entry->pw;
33423+ sg_set_buf(&sg, p, strlen(p));
33424+
33425+ crypto_hash_update(&desc, &sg, sg.length);
33426+
33427+ crypto_hash_final(&desc, temp_sum);
33428+
33429+ memset(entry->pw, 0, GR_PW_LEN);
33430+
33431+ for (i = 0; i < GR_SHA_LEN; i++)
33432+ if (sum[i] != temp_sum[i])
33433+ retval = 1;
33434+ else
33435+ dummy = 1; // waste a cycle
33436+
33437+ crypto_free_hash(tfm);
33438+
33439+ return retval;
33440+}
017d2877
AM
33441diff -urNp linux-2.6.30.4/grsecurity/Kconfig linux-2.6.30.4/grsecurity/Kconfig
33442--- linux-2.6.30.4/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
33443+++ linux-2.6.30.4/grsecurity/Kconfig 2009-07-30 11:21:32.668508126 -0400
33444@@ -0,0 +1,895 @@
2380c486
JR
33445+#
33446+# grecurity configuration
33447+#
33448+
33449+menu "Grsecurity"
33450+
33451+config GRKERNSEC
33452+ bool "Grsecurity"
33453+ select CRYPTO
33454+ select CRYPTO_SHA256
33455+ select SECURITY
33456+ select SECURITY_CAPABILITIES
33457+ help
33458+ If you say Y here, you will be able to configure many features
33459+ that will enhance the security of your system. It is highly
33460+ recommended that you say Y here and read through the help
33461+ for each option so that you fully understand the features and
33462+ can evaluate their usefulness for your machine.
33463+
33464+choice
33465+ prompt "Security Level"
33466+ depends on GRKERNSEC
33467+ default GRKERNSEC_CUSTOM
33468+
33469+config GRKERNSEC_LOW
33470+ bool "Low"
33471+ select GRKERNSEC_LINK
33472+ select GRKERNSEC_FIFO
33473+ select GRKERNSEC_EXECVE
33474+ select GRKERNSEC_RANDNET
33475+ select GRKERNSEC_DMESG
33476+ select GRKERNSEC_CHROOT
33477+ select GRKERNSEC_CHROOT_CHDIR
33478+ select GRKERNSEC_MODSTOP if (MODULES)
33479+
33480+ help
33481+ If you choose this option, several of the grsecurity options will
33482+ be enabled that will give you greater protection against a number
33483+ of attacks, while assuring that none of your software will have any
33484+ conflicts with the additional security measures. If you run a lot
33485+ of unusual software, or you are having problems with the higher
33486+ security levels, you should say Y here. With this option, the
33487+ following features are enabled:
33488+
33489+ - Linking restrictions
33490+ - FIFO restrictions
33491+ - Enforcing RLIMIT_NPROC on execve
33492+ - Restricted dmesg
33493+ - Enforced chdir("/") on chroot
33494+ - Runtime module disabling
33495+
33496+config GRKERNSEC_MEDIUM
33497+ bool "Medium"
33498+ select PAX
33499+ select PAX_EI_PAX
33500+ select PAX_PT_PAX_FLAGS
33501+ select PAX_HAVE_ACL_FLAGS
33502+ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
33503+ select GRKERNSEC_CHROOT
33504+ select GRKERNSEC_CHROOT_SYSCTL
33505+ select GRKERNSEC_LINK
33506+ select GRKERNSEC_FIFO
33507+ select GRKERNSEC_EXECVE
33508+ select GRKERNSEC_DMESG
33509+ select GRKERNSEC_RANDNET
33510+ select GRKERNSEC_FORKFAIL
33511+ select GRKERNSEC_TIME
33512+ select GRKERNSEC_SIGNAL
33513+ select GRKERNSEC_CHROOT
33514+ select GRKERNSEC_CHROOT_UNIX
33515+ select GRKERNSEC_CHROOT_MOUNT
33516+ select GRKERNSEC_CHROOT_PIVOT
33517+ select GRKERNSEC_CHROOT_DOUBLE
33518+ select GRKERNSEC_CHROOT_CHDIR
33519+ select GRKERNSEC_CHROOT_MKNOD
33520+ select GRKERNSEC_PROC
33521+ select GRKERNSEC_PROC_USERGROUP
33522+ select GRKERNSEC_MODSTOP if (MODULES)
33523+ select PAX_RANDUSTACK
33524+ select PAX_ASLR
33525+ select PAX_RANDMMAP
33526+ select PAX_REFCOUNT if (X86)
017d2877 33527+ select PAX_USERCOPY if (X86 && (SLAB || SLUB || SLOB))
2380c486
JR
33528+
33529+ help
33530+ If you say Y here, several features in addition to those included
33531+ in the low additional security level will be enabled. These
33532+ features provide even more security to your system, though in rare
33533+ cases they may be incompatible with very old or poorly written
33534+ software. If you enable this option, make sure that your auth
33535+ service (identd) is running as gid 1001. With this option,
33536+ the following features (in addition to those provided in the
33537+ low additional security level) will be enabled:
33538+
33539+ - Failed fork logging
33540+ - Time change logging
33541+ - Signal logging
33542+ - Deny mounts in chroot
33543+ - Deny double chrooting
33544+ - Deny sysctl writes in chroot
33545+ - Deny mknod in chroot
33546+ - Deny access to abstract AF_UNIX sockets out of chroot
33547+ - Deny pivot_root in chroot
33548+ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
33549+ - /proc restrictions with special GID set to 10 (usually wheel)
33550+ - Address Space Layout Randomization (ASLR)
33551+ - Prevent exploitation of most refcount overflows
de855c5d 33552+ - Bounds checking of copying between the kernel and userland
2380c486
JR
33553+
33554+config GRKERNSEC_HIGH
33555+ bool "High"
33556+ select GRKERNSEC_LINK
33557+ select GRKERNSEC_FIFO
33558+ select GRKERNSEC_EXECVE
33559+ select GRKERNSEC_DMESG
33560+ select GRKERNSEC_FORKFAIL
33561+ select GRKERNSEC_TIME
33562+ select GRKERNSEC_SIGNAL
33563+ select GRKERNSEC_CHROOT
33564+ select GRKERNSEC_CHROOT_SHMAT
33565+ select GRKERNSEC_CHROOT_UNIX
33566+ select GRKERNSEC_CHROOT_MOUNT
33567+ select GRKERNSEC_CHROOT_FCHDIR
33568+ select GRKERNSEC_CHROOT_PIVOT
33569+ select GRKERNSEC_CHROOT_DOUBLE
33570+ select GRKERNSEC_CHROOT_CHDIR
33571+ select GRKERNSEC_CHROOT_MKNOD
33572+ select GRKERNSEC_CHROOT_CAPS
33573+ select GRKERNSEC_CHROOT_SYSCTL
33574+ select GRKERNSEC_CHROOT_FINDTASK
33575+ select GRKERNSEC_PROC
33576+ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
33577+ select GRKERNSEC_HIDESYM
33578+ select GRKERNSEC_BRUTE
33579+ select GRKERNSEC_PROC_USERGROUP
33580+ select GRKERNSEC_KMEM
33581+ select GRKERNSEC_RESLOG
33582+ select GRKERNSEC_RANDNET
33583+ select GRKERNSEC_PROC_ADD
33584+ select GRKERNSEC_CHROOT_CHMOD
33585+ select GRKERNSEC_CHROOT_NICE
33586+ select GRKERNSEC_AUDIT_MOUNT
33587+ select GRKERNSEC_MODSTOP if (MODULES)
33588+ select PAX
33589+ select PAX_RANDUSTACK
33590+ select PAX_ASLR
33591+ select PAX_RANDMMAP
33592+ select PAX_NOEXEC
33593+ select PAX_MPROTECT
33594+ select PAX_EI_PAX
33595+ select PAX_PT_PAX_FLAGS
33596+ select PAX_HAVE_ACL_FLAGS
017d2877
AM
33597+ select PAX_KERNEXEC if (X86 && (!X86_32 || X86_WP_WORKS_OK))
33598+ select PAX_MEMORY_UDEREF if (X86_32)
2380c486 33599+ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
017d2877
AM
33600+ select PAX_SEGMEXEC if (X86_32)
33601+ select PAX_PAGEEXEC
2380c486
JR
33602+ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
33603+ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
33604+ select PAX_SYSCALL if (PPC32)
33605+ select PAX_EMUTRAMP if (PARISC)
33606+ select PAX_EMUSIGRT if (PARISC)
33607+ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
33608+ select PAX_REFCOUNT if (X86)
017d2877 33609+ select PAX_USERCOPY if (X86 && (SLAB || SLUB || SLOB))
2380c486
JR
33610+ help
33611+ If you say Y here, many of the features of grsecurity will be
33612+ enabled, which will protect you against many kinds of attacks
33613+ against your system. The heightened security comes at a cost
33614+ of an increased chance of incompatibilities with rare software
33615+ on your machine. Since this security level enables PaX, you should
33616+ view <http://pax.grsecurity.net> and read about the PaX
33617+ project. While you are there, download chpax and run it on
33618+ binaries that cause problems with PaX. Also remember that
33619+ since the /proc restrictions are enabled, you must run your
33620+ identd as gid 1001. This security level enables the following
33621+ features in addition to those listed in the low and medium
33622+ security levels:
33623+
33624+ - Additional /proc restrictions
33625+ - Chmod restrictions in chroot
33626+ - No signals, ptrace, or viewing of processes outside of chroot
33627+ - Capability restrictions in chroot
33628+ - Deny fchdir out of chroot
33629+ - Priority restrictions in chroot
33630+ - Segmentation-based implementation of PaX
33631+ - Mprotect restrictions
33632+ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
33633+ - Kernel stack randomization
33634+ - Mount/unmount/remount logging
33635+ - Kernel symbol hiding
33636+ - Prevention of memory exhaustion-based exploits
33637+config GRKERNSEC_CUSTOM
33638+ bool "Custom"
33639+ help
33640+ If you say Y here, you will be able to configure every grsecurity
33641+ option, which allows you to enable many more features that aren't
33642+ covered in the basic security levels. These additional features
33643+ include TPE, socket restrictions, and the sysctl system for
33644+ grsecurity. It is advised that you read through the help for
33645+ each option to determine its usefulness in your situation.
33646+
33647+endchoice
33648+
33649+menu "Address Space Protection"
33650+depends on GRKERNSEC
33651+
33652+config GRKERNSEC_KMEM
33653+ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
33654+ help
33655+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
33656+ be written to via mmap or otherwise to modify the running kernel.
33657+ /dev/port will also not be allowed to be opened. If you have module
33658+ support disabled, enabling this will close up four ways that are
33659+ currently used to insert malicious code into the running kernel.
33660+ Even with all these features enabled, we still highly recommend that
33661+ you use the RBAC system, as it is still possible for an attacker to
33662+ modify the running kernel through privileged I/O granted by ioperm/iopl.
33663+ If you are not using XFree86, you may be able to stop this additional
33664+ case by enabling the 'Disable privileged I/O' option. Though nothing
33665+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
33666+ but only to video memory, which is the only writing we allow in this
33667+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
33668+ not be allowed to mprotect it with PROT_WRITE later.
33669+ It is highly recommended that you say Y here if you meet all the
33670+ conditions above.
33671+
33672+config GRKERNSEC_IO
33673+ bool "Disable privileged I/O"
33674+ depends on X86
33675+ select RTC_CLASS
33676+ select RTC_INTF_DEV
33677+ select RTC_DRV_CMOS
33678+
33679+ help
33680+ If you say Y here, all ioperm and iopl calls will return an error.
33681+ Ioperm and iopl can be used to modify the running kernel.
33682+ Unfortunately, some programs need this access to operate properly,
33683+ the most notable of which are XFree86 and hwclock. hwclock can be
33684+ remedied by having RTC support in the kernel, so real-time
33685+ clock support is enabled if this option is enabled, to ensure
33686+ that hwclock operates correctly. XFree86 still will not
33687+ operate correctly with this option enabled, so DO NOT CHOOSE Y
33688+ IF YOU USE XFree86. If you use XFree86 and you still want to
33689+ protect your kernel against modification, use the RBAC system.
33690+
33691+config GRKERNSEC_PROC_MEMMAP
33692+ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
017d2877 33693+ default y if (PAX_NOEXEC || PAX_ASLR)
2380c486
JR
33694+ depends on PAX_NOEXEC || PAX_ASLR
33695+ help
33696+ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
33697+ give no information about the addresses of its mappings if
33698+ PaX features that rely on random addresses are enabled on the task.
33699+ If you use PaX it is greatly recommended that you say Y here as it
33700+ closes up a hole that makes the full ASLR useless for suid
33701+ binaries.
33702+
33703+config GRKERNSEC_BRUTE
33704+ bool "Deter exploit bruteforcing"
33705+ help
33706+ If you say Y here, attempts to bruteforce exploits against forking
33707+ daemons such as apache or sshd will be deterred. When a child of a
33708+ forking daemon is killed by PaX or crashes due to an illegal
33709+ instruction, the parent process will be delayed 30 seconds upon every
33710+ subsequent fork until the administrator is able to assess the
33711+ situation and restart the daemon. It is recommended that you also
33712+ enable signal logging in the auditing section so that logs are
33713+ generated when a process performs an illegal instruction.
33714+
33715+config GRKERNSEC_MODSTOP
33716+ bool "Runtime module disabling"
33717+ depends on MODULES
33718+ help
33719+ If you say Y here, you will be able to disable the ability to (un)load
33720+ modules at runtime. This feature is useful if you need the ability
33721+ to load kernel modules at boot time, but do not want to allow an
33722+ attacker to load a rootkit kernel module into the system, or to remove
33723+ a loaded kernel module important to system functioning. You should
33724+ enable the /dev/mem protection feature as well, since rootkits can be
33725+ inserted into the kernel via other methods than kernel modules. Since
33726+ an untrusted module could still be loaded by modifying init scripts and
33727+ rebooting the system, it is also recommended that you enable the RBAC
33728+ system. If you enable this option, a sysctl option with name
33729+ "disable_modules" will be created. Setting this option to "1" disables
33730+ module loading. After this option is set, no further writes to it are
33731+ allowed until the system is rebooted.
33732+
33733+config GRKERNSEC_HIDESYM
33734+ bool "Hide kernel symbols"
33735+ help
33736+ If you say Y here, getting information on loaded modules, and
33737+ displaying all kernel symbols through a syscall will be restricted
33738+ to users with CAP_SYS_MODULE. This option is only effective
33739+ provided the following conditions are met:
33740+ 1) The kernel using grsecurity is not precompiled by some distribution
33741+ 2) You are using the RBAC system and hiding other files such as your
33742+ kernel image and System.map
33743+ 3) You have the additional /proc restrictions enabled, which removes
33744+ /proc/kcore
33745+ If the above conditions are met, this option will aid to provide a
33746+ useful protection against local and remote kernel exploitation of
33747+ overflows and arbitrary read/write vulnerabilities.
33748+
33749+endmenu
33750+menu "Role Based Access Control Options"
33751+depends on GRKERNSEC
33752+
de855c5d
AM
33753+config GRKERNSEC_NO_RBAC
33754+ bool "Disable RBAC system"
33755+ help
33756+ If you say Y here, the /dev/grsec device will be removed from the kernel,
33757+ preventing the RBAC system from being enabled. You should only say Y
33758+ here if you have no intention of using the RBAC system, so as to prevent
33759+ an attacker with root access from misusing the RBAC system to hide files
33760+ and processes when loadable module support and /dev/[k]mem have been
33761+ locked down.
33762+
2380c486
JR
33763+config GRKERNSEC_ACL_HIDEKERN
33764+ bool "Hide kernel processes"
33765+ help
33766+ If you say Y here, all kernel threads will be hidden to all
33767+ processes but those whose subject has the "view hidden processes"
33768+ flag.
33769+
33770+config GRKERNSEC_ACL_MAXTRIES
33771+ int "Maximum tries before password lockout"
33772+ default 3
33773+ help
33774+ This option enforces the maximum number of times a user can attempt
33775+ to authorize themselves with the grsecurity RBAC system before being
33776+ denied the ability to attempt authorization again for a specified time.
33777+ The lower the number, the harder it will be to brute-force a password.
33778+
33779+config GRKERNSEC_ACL_TIMEOUT
33780+ int "Time to wait after max password tries, in seconds"
33781+ default 30
33782+ help
33783+ This option specifies the time the user must wait after attempting to
33784+ authorize to the RBAC system with the maximum number of invalid
33785+ passwords. The higher the number, the harder it will be to brute-force
33786+ a password.
33787+
33788+endmenu
33789+menu "Filesystem Protections"
33790+depends on GRKERNSEC
33791+
33792+config GRKERNSEC_PROC
33793+ bool "Proc restrictions"
33794+ help
33795+ If you say Y here, the permissions of the /proc filesystem
33796+ will be altered to enhance system security and privacy. You MUST
33797+ choose either a user only restriction or a user and group restriction.
33798+ Depending upon the option you choose, you can either restrict users to
33799+ see only the processes they themselves run, or choose a group that can
33800+ view all processes and files normally restricted to root if you choose
33801+ the "restrict to user only" option. NOTE: If you're running identd as
33802+ a non-root user, you will have to run it as the group you specify here.
33803+
33804+config GRKERNSEC_PROC_USER
33805+ bool "Restrict /proc to user only"
33806+ depends on GRKERNSEC_PROC
33807+ help
33808+ If you say Y here, non-root users will only be able to view their own
33809+ processes, and restricts them from viewing network-related information,
33810+ and viewing kernel symbol and module information.
33811+
33812+config GRKERNSEC_PROC_USERGROUP
33813+ bool "Allow special group"
33814+ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
33815+ help
33816+ If you say Y here, you will be able to select a group that will be
33817+ able to view all processes, network-related information, and
33818+ kernel and symbol information. This option is useful if you want
33819+ to run identd as a non-root user.
33820+
33821+config GRKERNSEC_PROC_GID
33822+ int "GID for special group"
33823+ depends on GRKERNSEC_PROC_USERGROUP
33824+ default 1001
33825+
33826+config GRKERNSEC_PROC_ADD
33827+ bool "Additional restrictions"
33828+ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
33829+ help
33830+ If you say Y here, additional restrictions will be placed on
33831+ /proc that keep normal users from viewing device information and
33832+ slabinfo information that could be useful for exploits.
33833+
33834+config GRKERNSEC_LINK
33835+ bool "Linking restrictions"
33836+ help
33837+ If you say Y here, /tmp race exploits will be prevented, since users
33838+ will no longer be able to follow symlinks owned by other users in
33839+ world-writable +t directories (i.e. /tmp), unless the owner of the
33840+ symlink is the owner of the directory. users will also not be
33841+ able to hardlink to files they do not own. If the sysctl option is
33842+ enabled, a sysctl option with name "linking_restrictions" is created.
33843+
33844+config GRKERNSEC_FIFO
33845+ bool "FIFO restrictions"
33846+ help
33847+ If you say Y here, users will not be able to write to FIFOs they don't
33848+ own in world-writable +t directories (i.e. /tmp), unless the owner of
33849+ the FIFO is the same owner of the directory it's held in. If the sysctl
33850+ option is enabled, a sysctl option with name "fifo_restrictions" is
33851+ created.
33852+
33853+config GRKERNSEC_CHROOT
33854+ bool "Chroot jail restrictions"
33855+ help
33856+ If you say Y here, you will be able to choose several options that will
33857+ make breaking out of a chrooted jail much more difficult. If you
33858+ encounter no software incompatibilities with the following options, it
33859+ is recommended that you enable each one.
33860+
33861+config GRKERNSEC_CHROOT_MOUNT
33862+ bool "Deny mounts"
33863+ depends on GRKERNSEC_CHROOT
33864+ help
33865+ If you say Y here, processes inside a chroot will not be able to
33866+ mount or remount filesystems. If the sysctl option is enabled, a
33867+ sysctl option with name "chroot_deny_mount" is created.
33868+
33869+config GRKERNSEC_CHROOT_DOUBLE
33870+ bool "Deny double-chroots"
33871+ depends on GRKERNSEC_CHROOT
33872+ help
33873+ If you say Y here, processes inside a chroot will not be able to chroot
33874+ again outside the chroot. This is a widely used method of breaking
33875+ out of a chroot jail and should not be allowed. If the sysctl
33876+ option is enabled, a sysctl option with name
33877+ "chroot_deny_chroot" is created.
33878+
33879+config GRKERNSEC_CHROOT_PIVOT
33880+ bool "Deny pivot_root in chroot"
33881+ depends on GRKERNSEC_CHROOT
33882+ help
33883+ If you say Y here, processes inside a chroot will not be able to use
33884+ a function called pivot_root() that was introduced in Linux 2.3.41. It
33885+ works similar to chroot in that it changes the root filesystem. This
33886+ function could be misused in a chrooted process to attempt to break out
33887+ of the chroot, and therefore should not be allowed. If the sysctl
33888+ option is enabled, a sysctl option with name "chroot_deny_pivot" is
33889+ created.
33890+
33891+config GRKERNSEC_CHROOT_CHDIR
33892+ bool "Enforce chdir(\"/\") on all chroots"
33893+ depends on GRKERNSEC_CHROOT
33894+ help
33895+ If you say Y here, the current working directory of all newly-chrooted
33896+ applications will be set to the the root directory of the chroot.
33897+ The man page on chroot(2) states:
33898+ Note that this call does not change the current working
33899+ directory, so that `.' can be outside the tree rooted at
33900+ `/'. In particular, the super-user can escape from a
33901+ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
33902+
33903+ It is recommended that you say Y here, since it's not known to break
33904+ any software. If the sysctl option is enabled, a sysctl option with
33905+ name "chroot_enforce_chdir" is created.
33906+
33907+config GRKERNSEC_CHROOT_CHMOD
33908+ bool "Deny (f)chmod +s"
33909+ depends on GRKERNSEC_CHROOT
33910+ help
33911+ If you say Y here, processes inside a chroot will not be able to chmod
33912+ or fchmod files to make them have suid or sgid bits. This protects
33913+ against another published method of breaking a chroot. If the sysctl
33914+ option is enabled, a sysctl option with name "chroot_deny_chmod" is
33915+ created.
33916+
33917+config GRKERNSEC_CHROOT_FCHDIR
33918+ bool "Deny fchdir out of chroot"
33919+ depends on GRKERNSEC_CHROOT
33920+ help
33921+ If you say Y here, a well-known method of breaking chroots by fchdir'ing
33922+ to a file descriptor of the chrooting process that points to a directory
33923+ outside the filesystem will be stopped. If the sysctl option
33924+ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
33925+
33926+config GRKERNSEC_CHROOT_MKNOD
33927+ bool "Deny mknod"
33928+ depends on GRKERNSEC_CHROOT
33929+ help
33930+ If you say Y here, processes inside a chroot will not be allowed to
33931+ mknod. The problem with using mknod inside a chroot is that it
33932+ would allow an attacker to create a device entry that is the same
33933+ as one on the physical root of your system, which could range from
33934+ anything from the console device to a device for your harddrive (which
33935+ they could then use to wipe the drive or steal data). It is recommended
33936+ that you say Y here, unless you run into software incompatibilities.
33937+ If the sysctl option is enabled, a sysctl option with name
33938+ "chroot_deny_mknod" is created.
33939+
33940+config GRKERNSEC_CHROOT_SHMAT
33941+ bool "Deny shmat() out of chroot"
33942+ depends on GRKERNSEC_CHROOT
33943+ help
33944+ If you say Y here, processes inside a chroot will not be able to attach
33945+ to shared memory segments that were created outside of the chroot jail.
33946+ It is recommended that you say Y here. If the sysctl option is enabled,
33947+ a sysctl option with name "chroot_deny_shmat" is created.
33948+
33949+config GRKERNSEC_CHROOT_UNIX
33950+ bool "Deny access to abstract AF_UNIX sockets out of chroot"
33951+ depends on GRKERNSEC_CHROOT
33952+ help
33953+ If you say Y here, processes inside a chroot will not be able to
33954+ connect to abstract (meaning not belonging to a filesystem) Unix
33955+ domain sockets that were bound outside of a chroot. It is recommended
33956+ that you say Y here. If the sysctl option is enabled, a sysctl option
33957+ with name "chroot_deny_unix" is created.
33958+
33959+config GRKERNSEC_CHROOT_FINDTASK
33960+ bool "Protect outside processes"
33961+ depends on GRKERNSEC_CHROOT
33962+ help
33963+ If you say Y here, processes inside a chroot will not be able to
017d2877
AM
33964+ kill, send signals with fcntl, ptrace, capget, getpgid, setpgid,
33965+ getsid, or view any process outside of the chroot. If the sysctl
2380c486
JR
33966+ option is enabled, a sysctl option with name "chroot_findtask" is
33967+ created.
33968+
33969+config GRKERNSEC_CHROOT_NICE
33970+ bool "Restrict priority changes"
33971+ depends on GRKERNSEC_CHROOT
33972+ help
33973+ If you say Y here, processes inside a chroot will not be able to raise
33974+ the priority of processes in the chroot, or alter the priority of
33975+ processes outside the chroot. This provides more security than simply
33976+ removing CAP_SYS_NICE from the process' capability set. If the
33977+ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
33978+ is created.
33979+
33980+config GRKERNSEC_CHROOT_SYSCTL
33981+ bool "Deny sysctl writes"
33982+ depends on GRKERNSEC_CHROOT
33983+ help
33984+ If you say Y here, an attacker in a chroot will not be able to
33985+ write to sysctl entries, either by sysctl(2) or through a /proc
33986+ interface. It is strongly recommended that you say Y here. If the
33987+ sysctl option is enabled, a sysctl option with name
33988+ "chroot_deny_sysctl" is created.
33989+
33990+config GRKERNSEC_CHROOT_CAPS
33991+ bool "Capability restrictions"
33992+ depends on GRKERNSEC_CHROOT
33993+ help
33994+ If you say Y here, the capabilities on all root processes within a
33995+ chroot jail will be lowered to stop module insertion, raw i/o,
33996+ system and net admin tasks, rebooting the system, modifying immutable
33997+ files, modifying IPC owned by another, and changing the system time.
33998+ This is left an option because it can break some apps. Disable this
33999+ if your chrooted apps are having problems performing those kinds of
34000+ tasks. If the sysctl option is enabled, a sysctl option with
34001+ name "chroot_caps" is created.
34002+
34003+endmenu
34004+menu "Kernel Auditing"
34005+depends on GRKERNSEC
34006+
34007+config GRKERNSEC_AUDIT_GROUP
34008+ bool "Single group for auditing"
34009+ help
34010+ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
34011+ will only operate on a group you specify. This option is recommended
34012+ if you only want to watch certain users instead of having a large
34013+ amount of logs from the entire system. If the sysctl option is enabled,
34014+ a sysctl option with name "audit_group" is created.
34015+
34016+config GRKERNSEC_AUDIT_GID
34017+ int "GID for auditing"
34018+ depends on GRKERNSEC_AUDIT_GROUP
34019+ default 1007
34020+
34021+config GRKERNSEC_EXECLOG
34022+ bool "Exec logging"
34023+ help
34024+ If you say Y here, all execve() calls will be logged (since the
34025+ other exec*() calls are frontends to execve(), all execution
34026+ will be logged). Useful for shell-servers that like to keep track
34027+ of their users. If the sysctl option is enabled, a sysctl option with
34028+ name "exec_logging" is created.
34029+ WARNING: This option when enabled will produce a LOT of logs, especially
34030+ on an active system.
34031+
34032+config GRKERNSEC_RESLOG
34033+ bool "Resource logging"
34034+ help
34035+ If you say Y here, all attempts to overstep resource limits will
34036+ be logged with the resource name, the requested size, and the current
34037+ limit. It is highly recommended that you say Y here. If the sysctl
34038+ option is enabled, a sysctl option with name "resource_logging" is
34039+ created. If the RBAC system is enabled, the sysctl value is ignored.
34040+
34041+config GRKERNSEC_CHROOT_EXECLOG
34042+ bool "Log execs within chroot"
34043+ help
34044+ If you say Y here, all executions inside a chroot jail will be logged
34045+ to syslog. This can cause a large amount of logs if certain
34046+ applications (eg. djb's daemontools) are installed on the system, and
34047+ is therefore left as an option. If the sysctl option is enabled, a
34048+ sysctl option with name "chroot_execlog" is created.
34049+
34050+config GRKERNSEC_AUDIT_CHDIR
34051+ bool "Chdir logging"
34052+ help
34053+ If you say Y here, all chdir() calls will be logged. If the sysctl
34054+ option is enabled, a sysctl option with name "audit_chdir" is created.
34055+
34056+config GRKERNSEC_AUDIT_MOUNT
34057+ bool "(Un)Mount logging"
34058+ help
34059+ If you say Y here, all mounts and unmounts will be logged. If the
34060+ sysctl option is enabled, a sysctl option with name "audit_mount" is
34061+ created.
34062+
34063+config GRKERNSEC_AUDIT_IPC
34064+ bool "IPC logging"
34065+ help
34066+ If you say Y here, creation and removal of message queues, semaphores,
34067+ and shared memory will be logged. If the sysctl option is enabled, a
34068+ sysctl option with name "audit_ipc" is created.
34069+
34070+config GRKERNSEC_SIGNAL
34071+ bool "Signal logging"
34072+ help
34073+ If you say Y here, certain important signals will be logged, such as
34074+ SIGSEGV, which will as a result inform you of when a error in a program
34075+ occurred, which in some cases could mean a possible exploit attempt.
34076+ If the sysctl option is enabled, a sysctl option with name
34077+ "signal_logging" is created.
34078+
34079+config GRKERNSEC_FORKFAIL
34080+ bool "Fork failure logging"
34081+ help
34082+ If you say Y here, all failed fork() attempts will be logged.
34083+ This could suggest a fork bomb, or someone attempting to overstep
34084+ their process limit. If the sysctl option is enabled, a sysctl option
34085+ with name "forkfail_logging" is created.
34086+
34087+config GRKERNSEC_TIME
34088+ bool "Time change logging"
34089+ help
34090+ If you say Y here, any changes of the system clock will be logged.
34091+ If the sysctl option is enabled, a sysctl option with name
34092+ "timechange_logging" is created.
34093+
34094+config GRKERNSEC_PROC_IPADDR
34095+ bool "/proc/<pid>/ipaddr support"
34096+ help
34097+ If you say Y here, a new entry will be added to each /proc/<pid>
34098+ directory that contains the IP address of the person using the task.
34099+ The IP is carried across local TCP and AF_UNIX stream sockets.
34100+ This information can be useful for IDS/IPSes to perform remote response
34101+ to a local attack. The entry is readable by only the owner of the
34102+ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
34103+ the RBAC system), and thus does not create privacy concerns.
34104+
34105+config GRKERNSEC_AUDIT_TEXTREL
34106+ bool 'ELF text relocations logging (READ HELP)'
34107+ depends on PAX_MPROTECT
34108+ help
34109+ If you say Y here, text relocations will be logged with the filename
34110+ of the offending library or binary. The purpose of the feature is
34111+ to help Linux distribution developers get rid of libraries and
34112+ binaries that need text relocations which hinder the future progress
34113+ of PaX. Only Linux distribution developers should say Y here, and
34114+ never on a production machine, as this option creates an information
34115+ leak that could aid an attacker in defeating the randomization of
34116+ a single memory region. If the sysctl option is enabled, a sysctl
34117+ option with name "audit_textrel" is created.
34118+
34119+endmenu
34120+
34121+menu "Executable Protections"
34122+depends on GRKERNSEC
34123+
34124+config GRKERNSEC_EXECVE
34125+ bool "Enforce RLIMIT_NPROC on execs"
34126+ help
34127+ If you say Y here, users with a resource limit on processes will
34128+ have the value checked during execve() calls. The current system
34129+ only checks the system limit during fork() calls. If the sysctl option
34130+ is enabled, a sysctl option with name "execve_limiting" is created.
34131+
34132+config GRKERNSEC_DMESG
34133+ bool "Dmesg(8) restriction"
34134+ help
34135+ If you say Y here, non-root users will not be able to use dmesg(8)
34136+ to view up to the last 4kb of messages in the kernel's log buffer.
34137+ If the sysctl option is enabled, a sysctl option with name "dmesg" is
34138+ created.
34139+
34140+config GRKERNSEC_TPE
34141+ bool "Trusted Path Execution (TPE)"
34142+ help
34143+ If you say Y here, you will be able to choose a gid to add to the
34144+ supplementary groups of users you want to mark as "untrusted."
34145+ These users will not be able to execute any files that are not in
34146+ root-owned directories writable only by root. If the sysctl option
34147+ is enabled, a sysctl option with name "tpe" is created.
34148+
34149+config GRKERNSEC_TPE_ALL
34150+ bool "Partially restrict non-root users"
34151+ depends on GRKERNSEC_TPE
34152+ help
34153+ If you say Y here, All non-root users other than the ones in the
34154+ group specified in the main TPE option will only be allowed to
34155+ execute files in directories they own that are not group or
34156+ world-writable, or in directories owned by root and writable only by
34157+ root. If the sysctl option is enabled, a sysctl option with name
34158+ "tpe_restrict_all" is created.
34159+
34160+config GRKERNSEC_TPE_INVERT
34161+ bool "Invert GID option"
34162+ depends on GRKERNSEC_TPE
34163+ help
34164+ If you say Y here, the group you specify in the TPE configuration will
34165+ decide what group TPE restrictions will be *disabled* for. This
34166+ option is useful if you want TPE restrictions to be applied to most
34167+ users on the system.
34168+
34169+config GRKERNSEC_TPE_GID
34170+ int "GID for untrusted users"
34171+ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
34172+ default 1005
34173+ help
34174+ If you have selected the "Invert GID option" above, setting this
34175+ GID determines what group TPE restrictions will be *disabled* for.
34176+ If you have not selected the "Invert GID option" above, setting this
34177+ GID determines what group TPE restrictions will be *enabled* for.
34178+ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
34179+ is created.
34180+
34181+config GRKERNSEC_TPE_GID
34182+ int "GID for trusted users"
34183+ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
34184+ default 1005
34185+ help
34186+ If you have selected the "Invert GID option" above, setting this
34187+ GID determines what group TPE restrictions will be *disabled* for.
34188+ If you have not selected the "Invert GID option" above, setting this
34189+ GID determines what group TPE restrictions will be *enabled* for.
34190+ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
34191+ is created.
34192+
34193+endmenu
34194+menu "Network Protections"
34195+depends on GRKERNSEC
34196+
34197+config GRKERNSEC_RANDNET
34198+ bool "Larger entropy pools"
34199+ help
34200+ If you say Y here, the entropy pools used for many features of Linux
34201+ and grsecurity will be doubled in size. Since several grsecurity
34202+ features use additional randomness, it is recommended that you say Y
34203+ here. Saying Y here has a similar effect as modifying
34204+ /proc/sys/kernel/random/poolsize.
34205+
de855c5d
AM
34206+config GRKERNSEC_BLACKHOLE
34207+ bool "TCP/UDP blackhole"
34208+ help
34209+ If you say Y here, neither TCP resets nor ICMP
34210+ destination-unreachable packets will be sent in response to packets
34211+ send to ports for which no associated listening process exists.
34212+ This feature supports both IPV4 and IPV6 and exempts the
34213+ loopback interface from blackholing. Enabling this feature
34214+ makes a host more resilient to DoS attacks and reduces network
34215+ visibility against scanners.
34216+
2380c486
JR
34217+config GRKERNSEC_SOCKET
34218+ bool "Socket restrictions"
34219+ help
34220+ If you say Y here, you will be able to choose from several options.
34221+ If you assign a GID on your system and add it to the supplementary
34222+ groups of users you want to restrict socket access to, this patch
34223+ will perform up to three things, based on the option(s) you choose.
34224+
34225+config GRKERNSEC_SOCKET_ALL
34226+ bool "Deny any sockets to group"
34227+ depends on GRKERNSEC_SOCKET
34228+ help
34229+ If you say Y here, you will be able to choose a GID of whose users will
34230+ be unable to connect to other hosts from your machine or run server
34231+ applications from your machine. If the sysctl option is enabled, a
34232+ sysctl option with name "socket_all" is created.
34233+
34234+config GRKERNSEC_SOCKET_ALL_GID
34235+ int "GID to deny all sockets for"
34236+ depends on GRKERNSEC_SOCKET_ALL
34237+ default 1004
34238+ help
34239+ Here you can choose the GID to disable socket access for. Remember to
34240+ add the users you want socket access disabled for to the GID
34241+ specified here. If the sysctl option is enabled, a sysctl option
34242+ with name "socket_all_gid" is created.
34243+
34244+config GRKERNSEC_SOCKET_CLIENT
34245+ bool "Deny client sockets to group"
34246+ depends on GRKERNSEC_SOCKET
34247+ help
34248+ If you say Y here, you will be able to choose a GID of whose users will
34249+ be unable to connect to other hosts from your machine, but will be
34250+ able to run servers. If this option is enabled, all users in the group
34251+ you specify will have to use passive mode when initiating ftp transfers
34252+ from the shell on your machine. If the sysctl option is enabled, a
34253+ sysctl option with name "socket_client" is created.
34254+
34255+config GRKERNSEC_SOCKET_CLIENT_GID
34256+ int "GID to deny client sockets for"
34257+ depends on GRKERNSEC_SOCKET_CLIENT
34258+ default 1003
34259+ help
34260+ Here you can choose the GID to disable client socket access for.
34261+ Remember to add the users you want client socket access disabled for to
34262+ the GID specified here. If the sysctl option is enabled, a sysctl
34263+ option with name "socket_client_gid" is created.
34264+
34265+config GRKERNSEC_SOCKET_SERVER
34266+ bool "Deny server sockets to group"
34267+ depends on GRKERNSEC_SOCKET
34268+ help
34269+ If you say Y here, you will be able to choose a GID of whose users will
34270+ be unable to run server applications from your machine. If the sysctl
34271+ option is enabled, a sysctl option with name "socket_server" is created.
34272+
34273+config GRKERNSEC_SOCKET_SERVER_GID
34274+ int "GID to deny server sockets for"
34275+ depends on GRKERNSEC_SOCKET_SERVER
34276+ default 1002
34277+ help
34278+ Here you can choose the GID to disable server socket access for.
34279+ Remember to add the users you want server socket access disabled for to
34280+ the GID specified here. If the sysctl option is enabled, a sysctl
34281+ option with name "socket_server_gid" is created.
34282+
34283+endmenu
34284+menu "Sysctl support"
34285+depends on GRKERNSEC && SYSCTL
34286+
34287+config GRKERNSEC_SYSCTL
34288+ bool "Sysctl support"
34289+ help
34290+ If you say Y here, you will be able to change the options that
34291+ grsecurity runs with at bootup, without having to recompile your
34292+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
34293+ to enable (1) or disable (0) various features. All the sysctl entries
34294+ are mutable until the "grsec_lock" entry is set to a non-zero value.
34295+ All features enabled in the kernel configuration are disabled at boot
34296+ if you do not say Y to the "Turn on features by default" option.
34297+ All options should be set at startup, and the grsec_lock entry should
34298+ be set to a non-zero value after all the options are set.
34299+ *THIS IS EXTREMELY IMPORTANT*
34300+
34301+config GRKERNSEC_SYSCTL_ON
34302+ bool "Turn on features by default"
34303+ depends on GRKERNSEC_SYSCTL
34304+ help
34305+ If you say Y here, instead of having all features enabled in the
34306+ kernel configuration disabled at boot time, the features will be
34307+ enabled at boot time. It is recommended you say Y here unless
34308+ there is some reason you would want all sysctl-tunable features to
34309+ be disabled by default. As mentioned elsewhere, it is important
34310+ to enable the grsec_lock entry once you have finished modifying
34311+ the sysctl entries.
34312+
34313+endmenu
34314+menu "Logging Options"
34315+depends on GRKERNSEC
34316+
34317+config GRKERNSEC_FLOODTIME
34318+ int "Seconds in between log messages (minimum)"
34319+ default 10
34320+ help
34321+ This option allows you to enforce the number of seconds between
34322+ grsecurity log messages. The default should be suitable for most
34323+ people, however, if you choose to change it, choose a value small enough
34324+ to allow informative logs to be produced, but large enough to
34325+ prevent flooding.
34326+
34327+config GRKERNSEC_FLOODBURST
34328+ int "Number of messages in a burst (maximum)"
34329+ default 4
34330+ help
34331+ This option allows you to choose the maximum number of messages allowed
34332+ within the flood time interval you chose in a separate option. The
34333+ default should be suitable for most people, however if you find that
34334+ many of your logs are being interpreted as flooding, you may want to
34335+ raise this value.
34336+
34337+endmenu
34338+
34339+endmenu
017d2877
AM
34340diff -urNp linux-2.6.30.4/grsecurity/Makefile linux-2.6.30.4/grsecurity/Makefile
34341--- linux-2.6.30.4/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
34342+++ linux-2.6.30.4/grsecurity/Makefile 2009-07-30 11:10:49.352668479 -0400
de855c5d 34343@@ -0,0 +1,21 @@
2380c486
JR
34344+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
34345+# during 2001-2005 it has been completely redesigned by Brad Spengler
34346+# into an RBAC system
34347+#
34348+# All code in this directory and various hooks inserted throughout the kernel
de855c5d
AM
34349+# are copyright Brad Spengler - Open Source Security, Inc., and released
34350+# under the GPL v2 or higher
2380c486
JR
34351+
34352+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
34353+ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
34354+ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
34355+
34356+obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
34357+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
34358+ gracl_learn.o grsec_log.o
34359+obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
34360+
34361+ifndef CONFIG_GRKERNSEC
34362+obj-y += grsec_disabled.o
34363+endif
34364+
017d2877
AM
34365diff -urNp linux-2.6.30.4/include/asm-generic/futex.h linux-2.6.30.4/include/asm-generic/futex.h
34366--- linux-2.6.30.4/include/asm-generic/futex.h 2009-07-24 17:47:51.000000000 -0400
34367+++ linux-2.6.30.4/include/asm-generic/futex.h 2009-07-30 09:48:10.105294791 -0400
2380c486
JR
34368@@ -6,7 +6,7 @@
34369 #include <asm/errno.h>
34370
34371 static inline int
34372-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
34373+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
34374 {
34375 int op = (encoded_op >> 28) & 7;
34376 int cmp = (encoded_op >> 24) & 15;
34377@@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
34378 }
34379
34380 static inline int
34381-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
34382+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
34383 {
34384 return -ENOSYS;
34385 }
017d2877
AM
34386diff -urNp linux-2.6.30.4/include/asm-generic/int-l64.h linux-2.6.30.4/include/asm-generic/int-l64.h
34387--- linux-2.6.30.4/include/asm-generic/int-l64.h 2009-07-24 17:47:51.000000000 -0400
34388+++ linux-2.6.30.4/include/asm-generic/int-l64.h 2009-07-30 09:48:10.105294791 -0400
de855c5d
AM
34389@@ -44,6 +44,8 @@ typedef unsigned int u32;
34390 typedef signed long s64;
34391 typedef unsigned long u64;
34392
34393+typedef unsigned int intoverflow_t __attribute__ ((mode(TI)));
34394+
34395 #define S8_C(x) x
34396 #define U8_C(x) x ## U
34397 #define S16_C(x) x
017d2877
AM
34398diff -urNp linux-2.6.30.4/include/asm-generic/int-ll64.h linux-2.6.30.4/include/asm-generic/int-ll64.h
34399--- linux-2.6.30.4/include/asm-generic/int-ll64.h 2009-07-24 17:47:51.000000000 -0400
34400+++ linux-2.6.30.4/include/asm-generic/int-ll64.h 2009-07-30 09:48:10.105294791 -0400
de855c5d
AM
34401@@ -49,6 +49,8 @@ typedef unsigned int u32;
34402 typedef signed long long s64;
34403 typedef unsigned long long u64;
34404
34405+typedef unsigned long long intoverflow_t;
34406+
34407 #define S8_C(x) x
34408 #define U8_C(x) x ## U
34409 #define S16_C(x) x
017d2877
AM
34410diff -urNp linux-2.6.30.4/include/asm-generic/sections.h linux-2.6.30.4/include/asm-generic/sections.h
34411--- linux-2.6.30.4/include/asm-generic/sections.h 2009-07-24 17:47:51.000000000 -0400
34412+++ linux-2.6.30.4/include/asm-generic/sections.h 2009-07-30 09:48:10.105294791 -0400
34413@@ -9,7 +9,7 @@ extern char __bss_start[], __bss_stop[];
34414 extern char __init_begin[], __init_end[];
34415 extern char _sinittext[], _einittext[];
34416 extern char _end[];
34417-extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
34418+extern char per_cpu_load[], __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
34419 extern char __kprobes_text_start[], __kprobes_text_end[];
34420 extern char __initdata_begin[], __initdata_end[];
34421 extern char __start_rodata[], __end_rodata[];
34422diff -urNp linux-2.6.30.4/include/asm-generic/vmlinux.lds.h linux-2.6.30.4/include/asm-generic/vmlinux.lds.h
34423--- linux-2.6.30.4/include/asm-generic/vmlinux.lds.h 2009-07-24 17:47:51.000000000 -0400
34424+++ linux-2.6.30.4/include/asm-generic/vmlinux.lds.h 2009-07-30 09:48:10.106233963 -0400
34425@@ -121,6 +121,7 @@
2380c486
JR
34426 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
34427 VMLINUX_SYMBOL(__start_rodata) = .; \
34428 *(.rodata) *(.rodata.*) \
34429+ *(.data.read_only) \
34430 *(__vermagic) /* Kernel version magic */ \
34431 *(__markers_strings) /* Markers: strings */ \
34432 *(__tracepoints_strings)/* Tracepoints: strings */ \
017d2877
AM
34433@@ -468,22 +469,24 @@
34434 * section in the linker script will go there too. @phdr should have
34435 * a leading colon.
34436 *
34437- * Note that this macros defines __per_cpu_load as an absolute symbol.
34438+ * Note that this macros defines per_cpu_load as an absolute symbol.
34439 * If there is no need to put the percpu section at a predetermined
34440 * address, use PERCPU().
34441 */
34442 #define PERCPU_VADDR(vaddr, phdr) \
34443- VMLINUX_SYMBOL(__per_cpu_load) = .; \
34444- .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
34445+ VMLINUX_SYMBOL(per_cpu_load) = .; \
34446+ .data.percpu vaddr : AT(VMLINUX_SYMBOL(per_cpu_load) \
34447 - LOAD_OFFSET) { \
34448+ VMLINUX_SYMBOL(__per_cpu_load) = . + per_cpu_load; \
34449 VMLINUX_SYMBOL(__per_cpu_start) = .; \
34450 *(.data.percpu.first) \
34451+ . = ALIGN(PAGE_SIZE); \
34452 *(.data.percpu.page_aligned) \
34453 *(.data.percpu) \
34454 *(.data.percpu.shared_aligned) \
34455 VMLINUX_SYMBOL(__per_cpu_end) = .; \
34456 } phdr \
34457- . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu);
34458+ . = VMLINUX_SYMBOL(per_cpu_load) + SIZEOF(.data.percpu);
2380c486 34459
017d2877
AM
34460 /**
34461 * PERCPU - define output section for percpu area, simple version
34462diff -urNp linux-2.6.30.4/include/drm/drm_pciids.h linux-2.6.30.4/include/drm/drm_pciids.h
34463--- linux-2.6.30.4/include/drm/drm_pciids.h 2009-07-24 17:47:51.000000000 -0400
34464+++ linux-2.6.30.4/include/drm/drm_pciids.h 2009-07-30 09:48:10.106233963 -0400
34465@@ -356,7 +356,7 @@
34466 {0x1002, 0x9614, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
34467 {0x1002, 0x9615, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
34468 {0x1002, 0x9616, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
2380c486
JR
34469- {0, 0, 0}
34470+ {0, 0, 0, 0, 0, 0}
34471
34472 #define r128_PCI_IDS \
34473 {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
017d2877 34474@@ -396,14 +396,14 @@
2380c486
JR
34475 {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34476 {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34477 {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34478- {0, 0, 0}
34479+ {0, 0, 0, 0, 0, 0}
34480
34481 #define mga_PCI_IDS \
34482 {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
34483 {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
34484 {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
34485 {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
34486- {0, 0, 0}
34487+ {0, 0, 0, 0, 0, 0}
34488
34489 #define mach64_PCI_IDS \
34490 {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
017d2877 34491@@ -426,7 +426,7 @@
2380c486
JR
34492 {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34493 {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34494 {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34495- {0, 0, 0}
34496+ {0, 0, 0, 0, 0, 0}
34497
34498 #define sisdrv_PCI_IDS \
34499 {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
017d2877 34500@@ -437,7 +437,7 @@
2380c486
JR
34501 {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34502 {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
34503 {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
34504- {0, 0, 0}
34505+ {0, 0, 0, 0, 0, 0}
34506
34507 #define tdfx_PCI_IDS \
34508 {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
017d2877 34509@@ -446,7 +446,7 @@
2380c486
JR
34510 {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34511 {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34512 {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34513- {0, 0, 0}
34514+ {0, 0, 0, 0, 0, 0}
34515
34516 #define viadrv_PCI_IDS \
34517 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
017d2877 34518@@ -458,14 +458,14 @@
2380c486
JR
34519 {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34520 {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
34521 {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
34522- {0, 0, 0}
34523+ {0, 0, 0, 0, 0, 0}
34524
34525 #define i810_PCI_IDS \
34526 {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34527 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34528 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34529 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34530- {0, 0, 0}
34531+ {0, 0, 0, 0, 0, 0}
34532
34533 #define i830_PCI_IDS \
34534 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
017d2877 34535@@ -473,11 +473,11 @@
2380c486
JR
34536 {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34537 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
017d2877 34538 {0x8086, 0x358e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
2380c486
JR
34539- {0, 0, 0}
34540+ {0, 0, 0, 0, 0, 0}
34541
34542 #define gamma_PCI_IDS \
34543 {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
34544- {0, 0, 0}
34545+ {0, 0, 0, 0, 0, 0}
34546
34547 #define savage_PCI_IDS \
34548 {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
017d2877 34549@@ -503,10 +503,10 @@
2380c486
JR
34550 {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
34551 {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
34552 {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
34553- {0, 0, 0}
34554+ {0, 0, 0, 0, 0, 0}
34555
34556 #define ffb_PCI_IDS \
34557- {0, 0, 0}
34558+ {0, 0, 0, 0, 0, 0}
34559
34560 #define i915_PCI_IDS \
34561 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
017d2877
AM
34562@@ -536,4 +536,4 @@
34563 {0x8086, 0xa001, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
34564 {0x8086, 0xa011, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
34565 {0x8086, 0x35e8, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
2380c486
JR
34566- {0, 0, 0}
34567+ {0, 0, 0, 0, 0, 0}
017d2877
AM
34568diff -urNp linux-2.6.30.4/include/drm/drmP.h linux-2.6.30.4/include/drm/drmP.h
34569--- linux-2.6.30.4/include/drm/drmP.h 2009-07-24 17:47:51.000000000 -0400
34570+++ linux-2.6.30.4/include/drm/drmP.h 2009-07-30 09:48:10.106233963 -0400
34571@@ -783,7 +783,7 @@ struct drm_driver {
34572 void (*gem_free_object) (struct drm_gem_object *obj);
34573
34574 /* Driver private ops for this object */
34575- struct vm_operations_struct *gem_vm_ops;
34576+ const struct vm_operations_struct *gem_vm_ops;
34577
34578 int major;
34579 int minor;
34580@@ -886,7 +886,7 @@ struct drm_device {
de855c5d
AM
34581
34582 /** \name Usage Counters */
34583 /*@{ */
34584- int open_count; /**< Outstanding files open */
34585+ atomic_t open_count; /**< Outstanding files open */
34586 atomic_t ioctl_count; /**< Outstanding IOCTLs pending */
34587 atomic_t vma_count; /**< Outstanding vma areas open */
34588 int buf_use; /**< Buffers in use -- cannot alloc */
017d2877 34589@@ -897,7 +897,7 @@ struct drm_device {
de855c5d
AM
34590 /*@{ */
34591 unsigned long counters;
34592 enum drm_stat_type types[15];
34593- atomic_t counts[15];
34594+ atomic_unchecked_t counts[15];
34595 /*@} */
34596
34597 struct list_head filelist;
017d2877
AM
34598diff -urNp linux-2.6.30.4/include/linux/a.out.h linux-2.6.30.4/include/linux/a.out.h
34599--- linux-2.6.30.4/include/linux/a.out.h 2009-07-24 17:47:51.000000000 -0400
34600+++ linux-2.6.30.4/include/linux/a.out.h 2009-07-30 09:48:10.107682096 -0400
2380c486
JR
34601@@ -39,6 +39,14 @@ enum machine_type {
34602 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
34603 };
34604
34605+/* Constants for the N_FLAGS field */
34606+#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
34607+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
34608+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
34609+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
34610+/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
34611+#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
34612+
34613 #if !defined (N_MAGIC)
34614 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
34615 #endif
017d2877
AM
34616diff -urNp linux-2.6.30.4/include/linux/atmdev.h linux-2.6.30.4/include/linux/atmdev.h
34617--- linux-2.6.30.4/include/linux/atmdev.h 2009-07-24 17:47:51.000000000 -0400
34618+++ linux-2.6.30.4/include/linux/atmdev.h 2009-07-30 09:48:10.107682096 -0400
de855c5d
AM
34619@@ -237,7 +237,7 @@ struct compat_atm_iobuf {
34620 #endif
34621
34622 struct k_atm_aal_stats {
34623-#define __HANDLE_ITEM(i) atomic_t i
34624+#define __HANDLE_ITEM(i) atomic_unchecked_t i
34625 __AAL_STAT_ITEMS
34626 #undef __HANDLE_ITEM
34627 };
017d2877
AM
34628diff -urNp linux-2.6.30.4/include/linux/binfmts.h linux-2.6.30.4/include/linux/binfmts.h
34629--- linux-2.6.30.4/include/linux/binfmts.h 2009-07-24 17:47:51.000000000 -0400
34630+++ linux-2.6.30.4/include/linux/binfmts.h 2009-07-30 09:48:10.107682096 -0400
34631@@ -78,6 +78,7 @@ struct linux_binfmt {
2380c486
JR
34632 int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
34633 int (*load_shlib)(struct file *);
34634 int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
34635+ void (*handle_mprotect)(struct vm_area_struct *vma, unsigned long newflags);
34636 unsigned long min_coredump; /* minimal dump size */
34637 int hasvdso;
34638 };
017d2877
AM
34639diff -urNp linux-2.6.30.4/include/linux/cache.h linux-2.6.30.4/include/linux/cache.h
34640--- linux-2.6.30.4/include/linux/cache.h 2009-07-24 17:47:51.000000000 -0400
34641+++ linux-2.6.30.4/include/linux/cache.h 2009-07-30 09:48:10.107682096 -0400
2380c486
JR
34642@@ -16,6 +16,10 @@
34643 #define __read_mostly
34644 #endif
34645
34646+#ifndef __read_only
34647+#define __read_only __read_mostly
34648+#endif
34649+
34650 #ifndef ____cacheline_aligned
34651 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
34652 #endif
017d2877
AM
34653diff -urNp linux-2.6.30.4/include/linux/capability.h linux-2.6.30.4/include/linux/capability.h
34654--- linux-2.6.30.4/include/linux/capability.h 2009-07-24 17:47:51.000000000 -0400
34655+++ linux-2.6.30.4/include/linux/capability.h 2009-07-30 11:10:49.423442785 -0400
de855c5d 34656@@ -563,6 +563,7 @@ extern const kernel_cap_t __cap_init_eff
2380c486
JR
34657 (security_real_capable_noaudit((t), (cap)) == 0)
34658
34659 extern int capable(int cap);
34660+int capable_nolog(int cap);
34661
34662 /* audit system wants to get cap info from files as well */
34663 struct dentry;
017d2877
AM
34664diff -urNp linux-2.6.30.4/include/linux/cgroup.h linux-2.6.30.4/include/linux/cgroup.h
34665--- linux-2.6.30.4/include/linux/cgroup.h 2009-07-24 17:47:51.000000000 -0400
34666+++ linux-2.6.30.4/include/linux/cgroup.h 2009-07-30 09:48:10.107682096 -0400
34667@@ -37,7 +37,7 @@ extern void cgroup_exit(struct task_stru
34668 extern int cgroupstats_build(struct cgroupstats *stats,
34669 struct dentry *dentry);
34670
34671-extern struct file_operations proc_cgroup_operations;
34672+extern const struct file_operations proc_cgroup_operations;
34673
34674 /* Define the enumeration of all cgroup subsystems */
34675 #define SUBSYS(_x) _x ## _subsys_id,
34676diff -urNp linux-2.6.30.4/include/linux/cpumask.h linux-2.6.30.4/include/linux/cpumask.h
34677--- linux-2.6.30.4/include/linux/cpumask.h 2009-07-24 17:47:51.000000000 -0400
34678+++ linux-2.6.30.4/include/linux/cpumask.h 2009-07-30 09:48:10.109008378 -0400
2380c486
JR
34679@@ -142,7 +142,6 @@
34680 #include <linux/bitmap.h>
34681
34682 typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
34683-extern cpumask_t _unused_cpumask_arg_;
34684
34685 #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS
34686 #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
017d2877
AM
34687diff -urNp linux-2.6.30.4/include/linux/elf.h linux-2.6.30.4/include/linux/elf.h
34688--- linux-2.6.30.4/include/linux/elf.h 2009-07-24 17:47:51.000000000 -0400
34689+++ linux-2.6.30.4/include/linux/elf.h 2009-07-30 09:48:10.109008378 -0400
2380c486
JR
34690@@ -49,6 +49,17 @@ typedef __s64 Elf64_Sxword;
34691 #define PT_GNU_EH_FRAME 0x6474e550
34692
34693 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
34694+#define PT_GNU_RELRO (PT_LOOS + 0x474e552)
34695+
34696+#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
34697+
34698+/* Constants for the e_flags field */
34699+#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
34700+#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
34701+#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
34702+#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
34703+/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
34704+#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
34705
34706 /* These constants define the different elf file types */
34707 #define ET_NONE 0
34708@@ -84,6 +95,8 @@ typedef __s64 Elf64_Sxword;
34709 #define DT_DEBUG 21
34710 #define DT_TEXTREL 22
34711 #define DT_JMPREL 23
34712+#define DT_FLAGS 30
34713+ #define DF_TEXTREL 0x00000004
34714 #define DT_ENCODING 32
34715 #define OLD_DT_LOOS 0x60000000
34716 #define DT_LOOS 0x6000000d
34717@@ -230,6 +243,19 @@ typedef struct elf64_hdr {
34718 #define PF_W 0x2
34719 #define PF_X 0x1
34720
34721+#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
34722+#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
34723+#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
34724+#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
34725+#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
34726+#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
34727+/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
34728+/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
34729+#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
34730+#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
34731+#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
34732+#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
34733+
34734 typedef struct elf32_phdr{
34735 Elf32_Word p_type;
34736 Elf32_Off p_offset;
34737@@ -322,6 +348,8 @@ typedef struct elf64_shdr {
34738 #define EI_OSABI 7
34739 #define EI_PAD 8
34740
34741+#define EI_PAX 14
34742+
34743 #define ELFMAG0 0x7f /* EI_MAG */
34744 #define ELFMAG1 'E'
34745 #define ELFMAG2 'L'
34746@@ -385,6 +413,7 @@ extern Elf32_Dyn _DYNAMIC [];
34747 #define elf_phdr elf32_phdr
34748 #define elf_note elf32_note
34749 #define elf_addr_t Elf32_Off
34750+#define elf_dyn Elf32_Dyn
34751
34752 #else
34753
34754@@ -393,6 +422,7 @@ extern Elf64_Dyn _DYNAMIC [];
34755 #define elf_phdr elf64_phdr
34756 #define elf_note elf64_note
34757 #define elf_addr_t Elf64_Off
34758+#define elf_dyn Elf64_Dyn
34759
34760 #endif
34761
017d2877
AM
34762diff -urNp linux-2.6.30.4/include/linux/fs.h linux-2.6.30.4/include/linux/fs.h
34763--- linux-2.6.30.4/include/linux/fs.h 2009-07-24 17:47:51.000000000 -0400
34764+++ linux-2.6.30.4/include/linux/fs.h 2009-07-30 09:48:10.109883773 -0400
34765@@ -2423,7 +2423,7 @@ static int __fops ## _open(struct inode
34766 __simple_attr_check_format(__fmt, 0ull); \
34767 return simple_attr_open(inode, file, __get, __set, __fmt); \
34768 } \
34769-static struct file_operations __fops = { \
34770+static const struct file_operations __fops = { \
34771 .owner = THIS_MODULE, \
34772 .open = __fops ## _open, \
34773 .release = simple_attr_release, \
34774diff -urNp linux-2.6.30.4/include/linux/fs_struct.h linux-2.6.30.4/include/linux/fs_struct.h
34775--- linux-2.6.30.4/include/linux/fs_struct.h 2009-07-24 17:47:51.000000000 -0400
34776+++ linux-2.6.30.4/include/linux/fs_struct.h 2009-07-30 09:48:10.109883773 -0400
de855c5d
AM
34777@@ -4,7 +4,7 @@
34778 #include <linux/path.h>
34779
34780 struct fs_struct {
34781- int users;
34782+ atomic_t users;
34783 rwlock_t lock;
34784 int umask;
34785 int in_exec;
017d2877
AM
34786diff -urNp linux-2.6.30.4/include/linux/genhd.h linux-2.6.30.4/include/linux/genhd.h
34787--- linux-2.6.30.4/include/linux/genhd.h 2009-07-24 17:47:51.000000000 -0400
34788+++ linux-2.6.30.4/include/linux/genhd.h 2009-07-30 09:48:10.109883773 -0400
de855c5d
AM
34789@@ -159,7 +159,7 @@ struct gendisk {
34790
34791 struct timer_rand_state *random;
34792
34793- atomic_t sync_io; /* RAID */
34794+ atomic_unchecked_t sync_io; /* RAID */
34795 struct work_struct async_notify;
34796 #ifdef CONFIG_BLK_DEV_INTEGRITY
34797 struct blk_integrity *integrity;
017d2877
AM
34798diff -urNp linux-2.6.30.4/include/linux/gracl.h linux-2.6.30.4/include/linux/gracl.h
34799--- linux-2.6.30.4/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
34800+++ linux-2.6.30.4/include/linux/gracl.h 2009-07-30 11:10:49.440849797 -0400
2380c486
JR
34801@@ -0,0 +1,318 @@
34802+#ifndef GR_ACL_H
34803+#define GR_ACL_H
34804+
34805+#include <linux/grdefs.h>
34806+#include <linux/resource.h>
34807+#include <linux/capability.h>
34808+#include <linux/dcache.h>
34809+#include <asm/resource.h>
34810+
34811+/* Major status information */
34812+
34813+#define GR_VERSION "grsecurity 2.1.14"
34814+#define GRSECURITY_VERSION 0x2114
34815+
34816+enum {
34817+ GR_SHUTDOWN = 0,
34818+ GR_ENABLE = 1,
34819+ GR_SPROLE = 2,
34820+ GR_RELOAD = 3,
34821+ GR_SEGVMOD = 4,
34822+ GR_STATUS = 5,
34823+ GR_UNSPROLE = 6,
34824+ GR_PASSSET = 7,
34825+ GR_SPROLEPAM = 8,
34826+};
34827+
34828+/* Password setup definitions
34829+ * kernel/grhash.c */
34830+enum {
34831+ GR_PW_LEN = 128,
34832+ GR_SALT_LEN = 16,
34833+ GR_SHA_LEN = 32,
34834+};
34835+
34836+enum {
34837+ GR_SPROLE_LEN = 64,
34838+};
34839+
34840+#define GR_NLIMITS 32
34841+
34842+/* Begin Data Structures */
34843+
34844+struct sprole_pw {
34845+ unsigned char *rolename;
34846+ unsigned char salt[GR_SALT_LEN];
34847+ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
34848+};
34849+
34850+struct name_entry {
34851+ __u32 key;
34852+ ino_t inode;
34853+ dev_t device;
34854+ char *name;
34855+ __u16 len;
34856+ __u8 deleted;
34857+ struct name_entry *prev;
34858+ struct name_entry *next;
34859+};
34860+
34861+struct inodev_entry {
34862+ struct name_entry *nentry;
34863+ struct inodev_entry *prev;
34864+ struct inodev_entry *next;
34865+};
34866+
34867+struct acl_role_db {
34868+ struct acl_role_label **r_hash;
34869+ __u32 r_size;
34870+};
34871+
34872+struct inodev_db {
34873+ struct inodev_entry **i_hash;
34874+ __u32 i_size;
34875+};
34876+
34877+struct name_db {
34878+ struct name_entry **n_hash;
34879+ __u32 n_size;
34880+};
34881+
34882+struct crash_uid {
34883+ uid_t uid;
34884+ unsigned long expires;
34885+};
34886+
34887+struct gr_hash_struct {
34888+ void **table;
34889+ void **nametable;
34890+ void *first;
34891+ __u32 table_size;
34892+ __u32 used_size;
34893+ int type;
34894+};
34895+
34896+/* Userspace Grsecurity ACL data structures */
34897+
34898+struct acl_subject_label {
34899+ char *filename;
34900+ ino_t inode;
34901+ dev_t device;
34902+ __u32 mode;
34903+ kernel_cap_t cap_mask;
34904+ kernel_cap_t cap_lower;
34905+
34906+ struct rlimit res[GR_NLIMITS];
34907+ __u32 resmask;
34908+
34909+ __u8 user_trans_type;
34910+ __u8 group_trans_type;
34911+ uid_t *user_transitions;
34912+ gid_t *group_transitions;
34913+ __u16 user_trans_num;
34914+ __u16 group_trans_num;
34915+
34916+ __u32 ip_proto[8];
34917+ __u32 ip_type;
34918+ struct acl_ip_label **ips;
34919+ __u32 ip_num;
34920+ __u32 inaddr_any_override;
34921+
34922+ __u32 crashes;
34923+ unsigned long expires;
34924+
34925+ struct acl_subject_label *parent_subject;
34926+ struct gr_hash_struct *hash;
34927+ struct acl_subject_label *prev;
34928+ struct acl_subject_label *next;
34929+
34930+ struct acl_object_label **obj_hash;
34931+ __u32 obj_hash_size;
34932+ __u16 pax_flags;
34933+};
34934+
34935+struct role_allowed_ip {
34936+ __u32 addr;
34937+ __u32 netmask;
34938+
34939+ struct role_allowed_ip *prev;
34940+ struct role_allowed_ip *next;
34941+};
34942+
34943+struct role_transition {
34944+ char *rolename;
34945+
34946+ struct role_transition *prev;
34947+ struct role_transition *next;
34948+};
34949+
34950+struct acl_role_label {
34951+ char *rolename;
34952+ uid_t uidgid;
34953+ __u16 roletype;
34954+
34955+ __u16 auth_attempts;
34956+ unsigned long expires;
34957+
34958+ struct acl_subject_label *root_label;
34959+ struct gr_hash_struct *hash;
34960+
34961+ struct acl_role_label *prev;
34962+ struct acl_role_label *next;
34963+
34964+ struct role_transition *transitions;
34965+ struct role_allowed_ip *allowed_ips;
34966+ uid_t *domain_children;
34967+ __u16 domain_child_num;
34968+
34969+ struct acl_subject_label **subj_hash;
34970+ __u32 subj_hash_size;
34971+};
34972+
34973+struct user_acl_role_db {
34974+ struct acl_role_label **r_table;
34975+ __u32 num_pointers; /* Number of allocations to track */
34976+ __u32 num_roles; /* Number of roles */
34977+ __u32 num_domain_children; /* Number of domain children */
34978+ __u32 num_subjects; /* Number of subjects */
34979+ __u32 num_objects; /* Number of objects */
34980+};
34981+
34982+struct acl_object_label {
34983+ char *filename;
34984+ ino_t inode;
34985+ dev_t device;
34986+ __u32 mode;
34987+
34988+ struct acl_subject_label *nested;
34989+ struct acl_object_label *globbed;
34990+
34991+ /* next two structures not used */
34992+
34993+ struct acl_object_label *prev;
34994+ struct acl_object_label *next;
34995+};
34996+
34997+struct acl_ip_label {
34998+ char *iface;
34999+ __u32 addr;
35000+ __u32 netmask;
35001+ __u16 low, high;
35002+ __u8 mode;
35003+ __u32 type;
35004+ __u32 proto[8];
35005+
35006+ /* next two structures not used */
35007+
35008+ struct acl_ip_label *prev;
35009+ struct acl_ip_label *next;
35010+};
35011+
35012+struct gr_arg {
35013+ struct user_acl_role_db role_db;
35014+ unsigned char pw[GR_PW_LEN];
35015+ unsigned char salt[GR_SALT_LEN];
35016+ unsigned char sum[GR_SHA_LEN];
35017+ unsigned char sp_role[GR_SPROLE_LEN];
35018+ struct sprole_pw *sprole_pws;
35019+ dev_t segv_device;
35020+ ino_t segv_inode;
35021+ uid_t segv_uid;
35022+ __u16 num_sprole_pws;
35023+ __u16 mode;
35024+};
35025+
35026+struct gr_arg_wrapper {
35027+ struct gr_arg *arg;
35028+ __u32 version;
35029+ __u32 size;
35030+};
35031+
35032+struct subject_map {
35033+ struct acl_subject_label *user;
35034+ struct acl_subject_label *kernel;
35035+ struct subject_map *prev;
35036+ struct subject_map *next;
35037+};
35038+
35039+struct acl_subj_map_db {
35040+ struct subject_map **s_hash;
35041+ __u32 s_size;
35042+};
35043+
35044+/* End Data Structures Section */
35045+
35046+/* Hash functions generated by empirical testing by Brad Spengler
35047+ Makes good use of the low bits of the inode. Generally 0-1 times
35048+ in loop for successful match. 0-3 for unsuccessful match.
35049+ Shift/add algorithm with modulus of table size and an XOR*/
35050+
35051+static __inline__ unsigned int
35052+rhash(const uid_t uid, const __u16 type, const unsigned int sz)
35053+{
35054+ return (((uid << type) + (uid ^ type)) % sz);
35055+}
35056+
35057+ static __inline__ unsigned int
35058+shash(const struct acl_subject_label *userp, const unsigned int sz)
35059+{
35060+ return ((const unsigned long)userp % sz);
35061+}
35062+
35063+static __inline__ unsigned int
35064+fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
35065+{
35066+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
35067+}
35068+
35069+static __inline__ unsigned int
35070+nhash(const char *name, const __u16 len, const unsigned int sz)
35071+{
35072+ return full_name_hash(name, len) % sz;
35073+}
35074+
35075+#define FOR_EACH_ROLE_START(role,iter) \
35076+ role = NULL; \
35077+ iter = 0; \
35078+ while (iter < acl_role_set.r_size) { \
35079+ if (role == NULL) \
35080+ role = acl_role_set.r_hash[iter]; \
35081+ if (role == NULL) { \
35082+ iter++; \
35083+ continue; \
35084+ }
35085+
35086+#define FOR_EACH_ROLE_END(role,iter) \
35087+ role = role->next; \
35088+ if (role == NULL) \
35089+ iter++; \
35090+ }
35091+
35092+#define FOR_EACH_SUBJECT_START(role,subj,iter) \
35093+ subj = NULL; \
35094+ iter = 0; \
35095+ while (iter < role->subj_hash_size) { \
35096+ if (subj == NULL) \
35097+ subj = role->subj_hash[iter]; \
35098+ if (subj == NULL) { \
35099+ iter++; \
35100+ continue; \
35101+ }
35102+
35103+#define FOR_EACH_SUBJECT_END(subj,iter) \
35104+ subj = subj->next; \
35105+ if (subj == NULL) \
35106+ iter++; \
35107+ }
35108+
35109+
35110+#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
35111+ subj = role->hash->first; \
35112+ while (subj != NULL) {
35113+
35114+#define FOR_EACH_NESTED_SUBJECT_END(subj) \
35115+ subj = subj->next; \
35116+ }
35117+
35118+#endif
35119+
017d2877
AM
35120diff -urNp linux-2.6.30.4/include/linux/gralloc.h linux-2.6.30.4/include/linux/gralloc.h
35121--- linux-2.6.30.4/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
35122+++ linux-2.6.30.4/include/linux/gralloc.h 2009-07-30 11:10:49.444477054 -0400
de855c5d 35123@@ -0,0 +1,9 @@
2380c486
JR
35124+#ifndef __GRALLOC_H
35125+#define __GRALLOC_H
35126+
35127+void acl_free_all(void);
35128+int acl_alloc_stack_init(unsigned long size);
35129+void *acl_alloc(unsigned long len);
de855c5d 35130+void *acl_alloc_num(unsigned long num, unsigned long len);
2380c486
JR
35131+
35132+#endif
017d2877
AM
35133diff -urNp linux-2.6.30.4/include/linux/grdefs.h linux-2.6.30.4/include/linux/grdefs.h
35134--- linux-2.6.30.4/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
35135+++ linux-2.6.30.4/include/linux/grdefs.h 2009-07-30 11:10:49.454486092 -0400
2380c486
JR
35136@@ -0,0 +1,136 @@
35137+#ifndef GRDEFS_H
35138+#define GRDEFS_H
35139+
35140+/* Begin grsecurity status declarations */
35141+
35142+enum {
35143+ GR_READY = 0x01,
35144+ GR_STATUS_INIT = 0x00 // disabled state
35145+};
35146+
35147+/* Begin ACL declarations */
35148+
35149+/* Role flags */
35150+
35151+enum {
35152+ GR_ROLE_USER = 0x0001,
35153+ GR_ROLE_GROUP = 0x0002,
35154+ GR_ROLE_DEFAULT = 0x0004,
35155+ GR_ROLE_SPECIAL = 0x0008,
35156+ GR_ROLE_AUTH = 0x0010,
35157+ GR_ROLE_NOPW = 0x0020,
35158+ GR_ROLE_GOD = 0x0040,
35159+ GR_ROLE_LEARN = 0x0080,
35160+ GR_ROLE_TPE = 0x0100,
35161+ GR_ROLE_DOMAIN = 0x0200,
35162+ GR_ROLE_PAM = 0x0400
35163+};
35164+
35165+/* ACL Subject and Object mode flags */
35166+enum {
35167+ GR_DELETED = 0x80000000
35168+};
35169+
35170+/* ACL Object-only mode flags */
35171+enum {
35172+ GR_READ = 0x00000001,
35173+ GR_APPEND = 0x00000002,
35174+ GR_WRITE = 0x00000004,
35175+ GR_EXEC = 0x00000008,
35176+ GR_FIND = 0x00000010,
35177+ GR_INHERIT = 0x00000020,
35178+ GR_SETID = 0x00000040,
35179+ GR_CREATE = 0x00000080,
35180+ GR_DELETE = 0x00000100,
35181+ GR_LINK = 0x00000200,
35182+ GR_AUDIT_READ = 0x00000400,
35183+ GR_AUDIT_APPEND = 0x00000800,
35184+ GR_AUDIT_WRITE = 0x00001000,
35185+ GR_AUDIT_EXEC = 0x00002000,
35186+ GR_AUDIT_FIND = 0x00004000,
35187+ GR_AUDIT_INHERIT= 0x00008000,
35188+ GR_AUDIT_SETID = 0x00010000,
35189+ GR_AUDIT_CREATE = 0x00020000,
35190+ GR_AUDIT_DELETE = 0x00040000,
35191+ GR_AUDIT_LINK = 0x00080000,
35192+ GR_PTRACERD = 0x00100000,
35193+ GR_NOPTRACE = 0x00200000,
35194+ GR_SUPPRESS = 0x00400000,
35195+ GR_NOLEARN = 0x00800000
35196+};
35197+
35198+#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
35199+ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
35200+ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
35201+
35202+/* ACL subject-only mode flags */
35203+enum {
35204+ GR_KILL = 0x00000001,
35205+ GR_VIEW = 0x00000002,
35206+ GR_PROTECTED = 0x00000004,
35207+ GR_LEARN = 0x00000008,
35208+ GR_OVERRIDE = 0x00000010,
35209+ /* just a placeholder, this mode is only used in userspace */
35210+ GR_DUMMY = 0x00000020,
35211+ GR_PROTSHM = 0x00000040,
35212+ GR_KILLPROC = 0x00000080,
35213+ GR_KILLIPPROC = 0x00000100,
35214+ /* just a placeholder, this mode is only used in userspace */
35215+ GR_NOTROJAN = 0x00000200,
35216+ GR_PROTPROCFD = 0x00000400,
35217+ GR_PROCACCT = 0x00000800,
35218+ GR_RELAXPTRACE = 0x00001000,
35219+ GR_NESTED = 0x00002000,
35220+ GR_INHERITLEARN = 0x00004000,
35221+ GR_PROCFIND = 0x00008000,
35222+ GR_POVERRIDE = 0x00010000,
35223+ GR_KERNELAUTH = 0x00020000,
35224+};
35225+
35226+enum {
35227+ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
35228+ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
35229+ GR_PAX_ENABLE_MPROTECT = 0x0004,
35230+ GR_PAX_ENABLE_RANDMMAP = 0x0008,
35231+ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
35232+ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
35233+ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
35234+ GR_PAX_DISABLE_MPROTECT = 0x0400,
35235+ GR_PAX_DISABLE_RANDMMAP = 0x0800,
35236+ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
35237+};
35238+
35239+enum {
35240+ GR_ID_USER = 0x01,
35241+ GR_ID_GROUP = 0x02,
35242+};
35243+
35244+enum {
35245+ GR_ID_ALLOW = 0x01,
35246+ GR_ID_DENY = 0x02,
35247+};
35248+
35249+#define GR_CRASH_RES 31
35250+#define GR_UIDTABLE_MAX 500
35251+
35252+/* begin resource learning section */
35253+enum {
35254+ GR_RLIM_CPU_BUMP = 60,
35255+ GR_RLIM_FSIZE_BUMP = 50000,
35256+ GR_RLIM_DATA_BUMP = 10000,
35257+ GR_RLIM_STACK_BUMP = 1000,
35258+ GR_RLIM_CORE_BUMP = 10000,
35259+ GR_RLIM_RSS_BUMP = 500000,
35260+ GR_RLIM_NPROC_BUMP = 1,
35261+ GR_RLIM_NOFILE_BUMP = 5,
35262+ GR_RLIM_MEMLOCK_BUMP = 50000,
35263+ GR_RLIM_AS_BUMP = 500000,
35264+ GR_RLIM_LOCKS_BUMP = 2,
35265+ GR_RLIM_SIGPENDING_BUMP = 5,
35266+ GR_RLIM_MSGQUEUE_BUMP = 10000,
35267+ GR_RLIM_NICE_BUMP = 1,
35268+ GR_RLIM_RTPRIO_BUMP = 1,
35269+ GR_RLIM_RTTIME_BUMP = 1000000
35270+};
35271+
35272+#endif
017d2877
AM
35273diff -urNp linux-2.6.30.4/include/linux/grinternal.h linux-2.6.30.4/include/linux/grinternal.h
35274--- linux-2.6.30.4/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
35275+++ linux-2.6.30.4/include/linux/grinternal.h 2009-07-30 11:10:49.454486092 -0400
de855c5d 35276@@ -0,0 +1,211 @@
2380c486
JR
35277+#ifndef __GRINTERNAL_H
35278+#define __GRINTERNAL_H
35279+
35280+#ifdef CONFIG_GRKERNSEC
35281+
35282+#include <linux/fs.h>
35283+#include <linux/gracl.h>
35284+#include <linux/grdefs.h>
35285+#include <linux/grmsg.h>
35286+
de855c5d
AM
35287+void gr_add_learn_entry(const char *fmt, ...)
35288+ __attribute__ ((format (printf, 1, 2)));
2380c486
JR
35289+__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
35290+ const struct vfsmount *mnt);
35291+__u32 gr_check_create(const struct dentry *new_dentry,
35292+ const struct dentry *parent,
35293+ const struct vfsmount *mnt, const __u32 mode);
35294+int gr_check_protected_task(const struct task_struct *task);
35295+__u32 to_gr_audit(const __u32 reqmode);
35296+int gr_set_acls(const int type);
35297+
35298+int gr_acl_is_enabled(void);
35299+char gr_roletype_to_char(void);
35300+
35301+void gr_handle_alertkill(struct task_struct *task);
35302+char *gr_to_filename(const struct dentry *dentry,
35303+ const struct vfsmount *mnt);
35304+char *gr_to_filename1(const struct dentry *dentry,
35305+ const struct vfsmount *mnt);
35306+char *gr_to_filename2(const struct dentry *dentry,
35307+ const struct vfsmount *mnt);
35308+char *gr_to_filename3(const struct dentry *dentry,
35309+ const struct vfsmount *mnt);
35310+
35311+extern int grsec_enable_link;
35312+extern int grsec_enable_fifo;
35313+extern int grsec_enable_execve;
35314+extern int grsec_enable_shm;
35315+extern int grsec_enable_execlog;
35316+extern int grsec_enable_signal;
35317+extern int grsec_enable_forkfail;
35318+extern int grsec_enable_time;
35319+extern int grsec_enable_chroot_shmat;
35320+extern int grsec_enable_chroot_findtask;
35321+extern int grsec_enable_chroot_mount;
35322+extern int grsec_enable_chroot_double;
35323+extern int grsec_enable_chroot_pivot;
35324+extern int grsec_enable_chroot_chdir;
35325+extern int grsec_enable_chroot_chmod;
35326+extern int grsec_enable_chroot_mknod;
35327+extern int grsec_enable_chroot_fchdir;
35328+extern int grsec_enable_chroot_nice;
35329+extern int grsec_enable_chroot_execlog;
35330+extern int grsec_enable_chroot_caps;
35331+extern int grsec_enable_chroot_sysctl;
35332+extern int grsec_enable_chroot_unix;
35333+extern int grsec_enable_tpe;
35334+extern int grsec_tpe_gid;
35335+extern int grsec_enable_tpe_all;
35336+extern int grsec_enable_sidcaps;
35337+extern int grsec_enable_socket_all;
35338+extern int grsec_socket_all_gid;
35339+extern int grsec_enable_socket_client;
35340+extern int grsec_socket_client_gid;
35341+extern int grsec_enable_socket_server;
35342+extern int grsec_socket_server_gid;
35343+extern int grsec_audit_gid;
35344+extern int grsec_enable_group;
35345+extern int grsec_enable_audit_ipc;
35346+extern int grsec_enable_audit_textrel;
35347+extern int grsec_enable_mount;
35348+extern int grsec_enable_chdir;
35349+extern int grsec_resource_logging;
35350+extern int grsec_lock;
35351+
35352+extern spinlock_t grsec_alert_lock;
35353+extern unsigned long grsec_alert_wtime;
35354+extern unsigned long grsec_alert_fyet;
35355+
35356+extern spinlock_t grsec_audit_lock;
35357+
35358+extern rwlock_t grsec_exec_file_lock;
35359+
35360+#define gr_task_fullpath(tsk) (tsk->exec_file ? \
35361+ gr_to_filename2(tsk->exec_file->f_path.dentry, \
35362+ tsk->exec_file->f_vfsmnt) : "/")
35363+
35364+#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
35365+ gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
35366+ tsk->parent->exec_file->f_vfsmnt) : "/")
35367+
35368+#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
35369+ gr_to_filename(tsk->exec_file->f_path.dentry, \
35370+ tsk->exec_file->f_vfsmnt) : "/")
35371+
35372+#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
35373+ gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
35374+ tsk->parent->exec_file->f_vfsmnt) : "/")
35375+
35376+#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
35377+ ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
35378+ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
35379+ (tsk_a->fs->root.dentry->d_inode->i_ino != \
35380+ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
35381+
35382+#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
35383+ (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
35384+ tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
35385+ (tsk_a->fs->root.dentry->d_inode->i_ino == \
35386+ tsk_b->fs->root.dentry->d_inode->i_ino))
35387+
35388+#define DEFAULTSECARGS(task, cred, pcred) gr_task_fullpath(task), task->comm, \
35389+ task->pid, cred->uid, \
35390+ cred->euid, cred->gid, cred->egid, \
35391+ gr_parent_task_fullpath(task), \
35392+ task->parent->comm, task->parent->pid, \
35393+ pcred->uid, pcred->euid, \
35394+ pcred->gid, pcred->egid
35395+
35396+#define GR_CHROOT_CAPS {{ \
35397+ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
35398+ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
35399+ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
35400+ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
35401+ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
35402+ CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
35403+
35404+#define security_learn(normal_msg,args...) \
35405+({ \
35406+ read_lock(&grsec_exec_file_lock); \
35407+ gr_add_learn_entry(normal_msg "\n", ## args); \
35408+ read_unlock(&grsec_exec_file_lock); \
35409+})
35410+
35411+enum {
35412+ GR_DO_AUDIT,
35413+ GR_DONT_AUDIT,
35414+ GR_DONT_AUDIT_GOOD
35415+};
35416+
35417+enum {
35418+ GR_TTYSNIFF,
35419+ GR_RBAC,
35420+ GR_RBAC_STR,
35421+ GR_STR_RBAC,
35422+ GR_RBAC_MODE2,
35423+ GR_RBAC_MODE3,
35424+ GR_FILENAME,
35425+ GR_SYSCTL_HIDDEN,
35426+ GR_NOARGS,
35427+ GR_ONE_INT,
35428+ GR_ONE_INT_TWO_STR,
35429+ GR_ONE_STR,
35430+ GR_STR_INT,
35431+ GR_TWO_INT,
35432+ GR_THREE_INT,
35433+ GR_FIVE_INT_TWO_STR,
35434+ GR_TWO_STR,
35435+ GR_THREE_STR,
35436+ GR_FOUR_STR,
35437+ GR_STR_FILENAME,
35438+ GR_FILENAME_STR,
35439+ GR_FILENAME_TWO_INT,
35440+ GR_FILENAME_TWO_INT_STR,
35441+ GR_TEXTREL,
35442+ GR_PTRACE,
35443+ GR_RESOURCE,
35444+ GR_CAP,
35445+ GR_SIG,
35446+ GR_CRASH1,
35447+ GR_CRASH2,
35448+ GR_PSACCT
35449+};
35450+
35451+#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
35452+#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
35453+#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
35454+#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
35455+#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
35456+#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
35457+#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)
35458+#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
35459+#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
35460+#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
35461+#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
35462+#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
35463+#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
35464+#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
35465+#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
35466+#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)
35467+#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
35468+#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
35469+#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
35470+#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
35471+#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
35472+#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
35473+#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)
35474+#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
35475+#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
35476+#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
35477+#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
35478+#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
35479+#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
35480+#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
35481+#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)
35482+
35483+void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
35484+
35485+#endif
35486+
35487+#endif
017d2877
AM
35488diff -urNp linux-2.6.30.4/include/linux/grmsg.h linux-2.6.30.4/include/linux/grmsg.h
35489--- linux-2.6.30.4/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
35490+++ linux-2.6.30.4/include/linux/grmsg.h 2009-07-30 11:10:49.454486092 -0400
2380c486
JR
35491@@ -0,0 +1,108 @@
35492+#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"
35493+#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"
35494+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
35495+#define GR_STOPMOD_MSG "denied modification of module state by "
35496+#define GR_IOPERM_MSG "denied use of ioperm() by "
35497+#define GR_IOPL_MSG "denied use of iopl() by "
35498+#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
35499+#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
35500+#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
35501+#define GR_KMEM_MSG "denied write of /dev/kmem by "
35502+#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
35503+#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
35504+#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
35505+#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
35506+#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"
35507+#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"
35508+#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
35509+#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
35510+#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
35511+#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
35512+#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
35513+#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
35514+#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
35515+#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
35516+#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
35517+#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
35518+#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
35519+#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
35520+#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
35521+#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
35522+#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
35523+#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
35524+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
35525+#define GR_NPROC_MSG "denied overstep of process limit by "
35526+#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
35527+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
35528+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
35529+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
35530+#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
35531+#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
35532+#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
35533+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
35534+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
35535+#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
35536+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
35537+#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
35538+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
35539+#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
35540+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
35541+#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
35542+#define GR_INITF_ACL_MSG "init_variables() failed %s by "
35543+#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"
35544+#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
35545+#define GR_SHUTS_ACL_MSG "shutdown auth success for "
35546+#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
35547+#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
35548+#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
35549+#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
35550+#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
35551+#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
35552+#define GR_ENABLEF_ACL_MSG "unable to load %s for "
35553+#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
35554+#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
35555+#define GR_RELOADF_ACL_MSG "failed reload of %s for "
35556+#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
35557+#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
35558+#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
35559+#define GR_SPROLEF_ACL_MSG "special role %s failure for "
35560+#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
35561+#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
35562+#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
35563+#define GR_INVMODE_ACL_MSG "invalid mode %d by "
35564+#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
35565+#define GR_FAILFORK_MSG "failed fork with errno %d by "
35566+#define GR_NICE_CHROOT_MSG "denied priority change by "
35567+#define GR_UNISIGLOG_MSG "signal %d sent to "
35568+#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
35569+#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
35570+#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
35571+#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
35572+#define GR_TIME_MSG "time set by "
35573+#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
35574+#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
35575+#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
35576+#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
35577+#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
35578+#define GR_BIND_MSG "denied bind() by "
35579+#define GR_CONNECT_MSG "denied connect() by "
35580+#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
35581+#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
35582+#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"
35583+#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
35584+#define GR_CAP_ACL_MSG "use of %s denied for "
35585+#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
35586+#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
35587+#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
35588+#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
35589+#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
35590+#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
35591+#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
35592+#define GR_MSGQ_AUDIT_MSG "message queue created by "
35593+#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
35594+#define GR_SEM_AUDIT_MSG "semaphore created by "
35595+#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
35596+#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
35597+#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
35598+#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
35599+#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
017d2877
AM
35600diff -urNp linux-2.6.30.4/include/linux/grsecurity.h linux-2.6.30.4/include/linux/grsecurity.h
35601--- linux-2.6.30.4/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
35602+++ linux-2.6.30.4/include/linux/grsecurity.h 2009-07-30 11:54:10.952982697 -0400
35603@@ -0,0 +1,202 @@
2380c486
JR
35604+#ifndef GR_SECURITY_H
35605+#define GR_SECURITY_H
35606+#include <linux/fs.h>
017d2877 35607+#include <linux/fs_struct.h>
2380c486
JR
35608+#include <linux/binfmts.h>
35609+#include <linux/gracl.h>
35610+
35611+/* notify of brain-dead configs */
35612+#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
35613+#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
35614+#endif
35615+#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
35616+#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
35617+#endif
35618+#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
35619+#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
35620+#endif
35621+#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
35622+#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
35623+#endif
35624+#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
35625+#error "CONFIG_PAX enabled, but no PaX options are enabled."
35626+#endif
35627+
35628+void gr_handle_brute_attach(struct task_struct *p);
35629+void gr_handle_brute_check(void);
35630+
35631+char gr_roletype_to_char(void);
35632+
35633+int gr_check_user_change(int real, int effective, int fs);
35634+int gr_check_group_change(int real, int effective, int fs);
35635+
35636+void gr_del_task_from_ip_table(struct task_struct *p);
35637+
35638+int gr_pid_is_chrooted(struct task_struct *p);
35639+int gr_handle_chroot_nice(void);
35640+int gr_handle_chroot_sysctl(const int op);
35641+int gr_handle_chroot_setpriority(struct task_struct *p,
35642+ const int niceval);
35643+int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
35644+int gr_handle_chroot_chroot(const struct dentry *dentry,
35645+ const struct vfsmount *mnt);
35646+int gr_handle_chroot_caps(struct path *path);
35647+void gr_handle_chroot_chdir(struct path *path);
35648+int gr_handle_chroot_chmod(const struct dentry *dentry,
35649+ const struct vfsmount *mnt, const int mode);
35650+int gr_handle_chroot_mknod(const struct dentry *dentry,
35651+ const struct vfsmount *mnt, const int mode);
35652+int gr_handle_chroot_mount(const struct dentry *dentry,
35653+ const struct vfsmount *mnt,
35654+ const char *dev_name);
35655+int gr_handle_chroot_pivot(void);
35656+int gr_handle_chroot_unix(const pid_t pid);
35657+
35658+int gr_handle_rawio(const struct inode *inode);
35659+int gr_handle_nproc(void);
35660+
35661+void gr_handle_ioperm(void);
35662+void gr_handle_iopl(void);
35663+
35664+int gr_tpe_allow(const struct file *file);
35665+
35666+int gr_random_pid(void);
35667+
35668+void gr_log_forkfail(const int retval);
35669+void gr_log_timechange(void);
35670+void gr_log_signal(const int sig, const struct task_struct *t);
35671+void gr_log_chdir(const struct dentry *dentry,
35672+ const struct vfsmount *mnt);
35673+void gr_log_chroot_exec(const struct dentry *dentry,
35674+ const struct vfsmount *mnt);
35675+void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
35676+void gr_log_remount(const char *devname, const int retval);
35677+void gr_log_unmount(const char *devname, const int retval);
35678+void gr_log_mount(const char *from, const char *to, const int retval);
35679+void gr_log_msgget(const int ret, const int msgflg);
35680+void gr_log_msgrm(const uid_t uid, const uid_t cuid);
35681+void gr_log_semget(const int err, const int semflg);
35682+void gr_log_semrm(const uid_t uid, const uid_t cuid);
35683+void gr_log_shmget(const int err, const int shmflg, const size_t size);
35684+void gr_log_shmrm(const uid_t uid, const uid_t cuid);
35685+void gr_log_textrel(struct vm_area_struct *vma);
35686+
35687+int gr_handle_follow_link(const struct inode *parent,
35688+ const struct inode *inode,
35689+ const struct dentry *dentry,
35690+ const struct vfsmount *mnt);
35691+int gr_handle_fifo(const struct dentry *dentry,
35692+ const struct vfsmount *mnt,
35693+ const struct dentry *dir, const int flag,
35694+ const int acc_mode);
35695+int gr_handle_hardlink(const struct dentry *dentry,
35696+ const struct vfsmount *mnt,
35697+ struct inode *inode,
35698+ const int mode, const char *to);
35699+
35700+int gr_is_capable(const int cap);
35701+int gr_is_capable_nolog(const int cap);
35702+void gr_learn_resource(const struct task_struct *task, const int limit,
35703+ const unsigned long wanted, const int gt);
35704+void gr_copy_label(struct task_struct *tsk);
35705+void gr_handle_crash(struct task_struct *task, const int sig);
35706+int gr_handle_signal(const struct task_struct *p, const int sig);
35707+int gr_check_crash_uid(const uid_t uid);
35708+int gr_check_protected_task(const struct task_struct *task);
35709+int gr_acl_handle_mmap(const struct file *file,
35710+ const unsigned long prot);
35711+int gr_acl_handle_mprotect(const struct file *file,
35712+ const unsigned long prot);
35713+int gr_check_hidden_task(const struct task_struct *tsk);
35714+__u32 gr_acl_handle_truncate(const struct dentry *dentry,
35715+ const struct vfsmount *mnt);
35716+__u32 gr_acl_handle_utime(const struct dentry *dentry,
35717+ const struct vfsmount *mnt);
35718+__u32 gr_acl_handle_access(const struct dentry *dentry,
35719+ const struct vfsmount *mnt, const int fmode);
35720+__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
35721+ const struct vfsmount *mnt, mode_t mode);
35722+__u32 gr_acl_handle_chmod(const struct dentry *dentry,
35723+ const struct vfsmount *mnt, mode_t mode);
35724+__u32 gr_acl_handle_chown(const struct dentry *dentry,
35725+ const struct vfsmount *mnt);
35726+int gr_handle_ptrace(struct task_struct *task, const long request);
35727+int gr_handle_proc_ptrace(struct task_struct *task);
35728+__u32 gr_acl_handle_execve(const struct dentry *dentry,
35729+ const struct vfsmount *mnt);
35730+int gr_check_crash_exec(const struct file *filp);
35731+int gr_acl_is_enabled(void);
35732+void gr_set_kernel_label(struct task_struct *task);
35733+void gr_set_role_label(struct task_struct *task, const uid_t uid,
35734+ const gid_t gid);
35735+int gr_set_proc_label(const struct dentry *dentry,
de855c5d
AM
35736+ const struct vfsmount *mnt,
35737+ const int unsafe_share);
2380c486 35738+__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
de855c5d 35739+ const struct vfsmount *mnt);
2380c486
JR
35740+__u32 gr_acl_handle_open(const struct dentry *dentry,
35741+ const struct vfsmount *mnt, const int fmode);
35742+__u32 gr_acl_handle_creat(const struct dentry *dentry,
35743+ const struct dentry *p_dentry,
35744+ const struct vfsmount *p_mnt, const int fmode,
35745+ const int imode);
35746+void gr_handle_create(const struct dentry *dentry,
35747+ const struct vfsmount *mnt);
35748+__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
35749+ const struct dentry *parent_dentry,
35750+ const struct vfsmount *parent_mnt,
35751+ const int mode);
35752+__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
35753+ const struct dentry *parent_dentry,
35754+ const struct vfsmount *parent_mnt);
35755+__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
35756+ const struct vfsmount *mnt);
35757+void gr_handle_delete(const ino_t ino, const dev_t dev);
35758+__u32 gr_acl_handle_unlink(const struct dentry *dentry,
35759+ const struct vfsmount *mnt);
35760+__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
35761+ const struct dentry *parent_dentry,
35762+ const struct vfsmount *parent_mnt,
35763+ const char *from);
35764+__u32 gr_acl_handle_link(const struct dentry *new_dentry,
35765+ const struct dentry *parent_dentry,
35766+ const struct vfsmount *parent_mnt,
35767+ const struct dentry *old_dentry,
35768+ const struct vfsmount *old_mnt, const char *to);
35769+int gr_acl_handle_rename(struct dentry *new_dentry,
35770+ struct dentry *parent_dentry,
35771+ const struct vfsmount *parent_mnt,
35772+ struct dentry *old_dentry,
35773+ struct inode *old_parent_inode,
35774+ struct vfsmount *old_mnt, const char *newname);
35775+void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
35776+ struct dentry *old_dentry,
35777+ struct dentry *new_dentry,
35778+ struct vfsmount *mnt, const __u8 replace);
35779+__u32 gr_check_link(const struct dentry *new_dentry,
35780+ const struct dentry *parent_dentry,
35781+ const struct vfsmount *parent_mnt,
35782+ const struct dentry *old_dentry,
35783+ const struct vfsmount *old_mnt);
35784+int gr_acl_handle_filldir(const struct file *file, const char *name,
35785+ const unsigned int namelen, const ino_t ino);
35786+
35787+__u32 gr_acl_handle_unix(const struct dentry *dentry,
35788+ const struct vfsmount *mnt);
35789+void gr_acl_handle_exit(void);
35790+void gr_acl_handle_psacct(struct task_struct *task, const long code);
35791+int gr_acl_handle_procpidmem(const struct task_struct *task);
35792+
35793+#ifdef CONFIG_GRKERNSEC
35794+void gr_handle_mem_write(void);
35795+void gr_handle_kmem_write(void);
35796+void gr_handle_open_port(void);
35797+int gr_handle_mem_mmap(const unsigned long offset,
35798+ struct vm_area_struct *vma);
35799+
35800+extern int grsec_enable_dmesg;
35801+extern int grsec_enable_randsrc;
35802+extern int grsec_enable_shm;
35803+#endif
35804+
35805+#endif
017d2877
AM
35806diff -urNp linux-2.6.30.4/include/linux/highmem.h linux-2.6.30.4/include/linux/highmem.h
35807--- linux-2.6.30.4/include/linux/highmem.h 2009-07-24 17:47:51.000000000 -0400
35808+++ linux-2.6.30.4/include/linux/highmem.h 2009-07-30 09:48:10.109883773 -0400
35809@@ -135,6 +135,18 @@ static inline void clear_highpage(struct
2380c486
JR
35810 kunmap_atomic(kaddr, KM_USER0);
35811 }
35812
35813+static inline void sanitize_highpage(struct page *page)
35814+{
35815+ void *kaddr;
35816+ unsigned long flags;
35817+
35818+ local_irq_save(flags);
35819+ kaddr = kmap_atomic(page, KM_CLEARPAGE);
35820+ clear_page(kaddr);
35821+ kunmap_atomic(kaddr, KM_CLEARPAGE);
35822+ local_irq_restore(flags);
35823+}
35824+
35825 static inline void zero_user_segments(struct page *page,
35826 unsigned start1, unsigned end1,
35827 unsigned start2, unsigned end2)
017d2877
AM
35828diff -urNp linux-2.6.30.4/include/linux/hugetlb.h linux-2.6.30.4/include/linux/hugetlb.h
35829--- linux-2.6.30.4/include/linux/hugetlb.h 2009-07-24 17:47:51.000000000 -0400
35830+++ linux-2.6.30.4/include/linux/hugetlb.h 2009-07-30 09:48:10.109883773 -0400
35831@@ -138,7 +138,7 @@ static inline struct hugetlbfs_sb_info *
35832 }
35833
35834 extern const struct file_operations hugetlbfs_file_operations;
35835-extern struct vm_operations_struct hugetlb_vm_ops;
35836+extern const struct vm_operations_struct hugetlb_vm_ops;
35837 struct file *hugetlb_file_setup(const char *name, size_t, int);
35838 int hugetlb_get_quota(struct address_space *mapping, long delta);
35839 void hugetlb_put_quota(struct address_space *mapping, long delta);
35840diff -urNp linux-2.6.30.4/include/linux/jbd2.h linux-2.6.30.4/include/linux/jbd2.h
35841--- linux-2.6.30.4/include/linux/jbd2.h 2009-07-24 17:47:51.000000000 -0400
35842+++ linux-2.6.30.4/include/linux/jbd2.h 2009-07-30 09:48:10.111182036 -0400
2380c486
JR
35843@@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
35844 } \
35845 } while (0)
35846 #else
35847-#define jbd_debug(f, a...) /**/
35848+#define jbd_debug(f, a...) do {} while (0)
35849 #endif
35850
35851 static inline void *jbd2_alloc(size_t size, gfp_t flags)
017d2877
AM
35852diff -urNp linux-2.6.30.4/include/linux/jbd.h linux-2.6.30.4/include/linux/jbd.h
35853--- linux-2.6.30.4/include/linux/jbd.h 2009-07-24 17:47:51.000000000 -0400
35854+++ linux-2.6.30.4/include/linux/jbd.h 2009-07-30 09:48:10.111182036 -0400
2380c486
JR
35855@@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
35856 } \
35857 } while (0)
35858 #else
35859-#define jbd_debug(f, a...) /**/
35860+#define jbd_debug(f, a...) do {} while (0)
35861 #endif
35862
35863 static inline void *jbd_alloc(size_t size, gfp_t flags)
017d2877
AM
35864diff -urNp linux-2.6.30.4/include/linux/kvm_host.h linux-2.6.30.4/include/linux/kvm_host.h
35865--- linux-2.6.30.4/include/linux/kvm_host.h 2009-07-24 17:47:51.000000000 -0400
35866+++ linux-2.6.30.4/include/linux/kvm_host.h 2009-07-30 09:48:10.112173628 -0400
35867@@ -172,7 +172,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vc
2380c486
JR
35868 void vcpu_load(struct kvm_vcpu *vcpu);
35869 void vcpu_put(struct kvm_vcpu *vcpu);
35870
35871-int kvm_init(void *opaque, unsigned int vcpu_size,
35872+int kvm_init(const void *opaque, unsigned int vcpu_size,
35873 struct module *module);
35874 void kvm_exit(void);
35875
017d2877
AM
35876@@ -279,7 +279,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(
35877 struct kvm_guest_debug *dbg);
2380c486
JR
35878 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
35879
35880-int kvm_arch_init(void *opaque);
35881+int kvm_arch_init(const void *opaque);
35882 void kvm_arch_exit(void);
35883
35884 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu);
017d2877
AM
35885diff -urNp linux-2.6.30.4/include/linux/libata.h linux-2.6.30.4/include/linux/libata.h
35886--- linux-2.6.30.4/include/linux/libata.h 2009-07-24 17:47:51.000000000 -0400
35887+++ linux-2.6.30.4/include/linux/libata.h 2009-07-30 09:48:10.113041063 -0400
2380c486
JR
35888@@ -64,11 +64,11 @@
35889 #ifdef ATA_VERBOSE_DEBUG
35890 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
35891 #else
35892-#define VPRINTK(fmt, args...)
35893+#define VPRINTK(fmt, args...) do {} while (0)
35894 #endif /* ATA_VERBOSE_DEBUG */
35895 #else
35896-#define DPRINTK(fmt, args...)
35897-#define VPRINTK(fmt, args...)
35898+#define DPRINTK(fmt, args...) do {} while (0)
35899+#define VPRINTK(fmt, args...) do {} while (0)
35900 #endif /* ATA_DEBUG */
35901
35902 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
017d2877
AM
35903diff -urNp linux-2.6.30.4/include/linux/mm.h linux-2.6.30.4/include/linux/mm.h
35904--- linux-2.6.30.4/include/linux/mm.h 2009-07-24 17:47:51.000000000 -0400
35905+++ linux-2.6.30.4/include/linux/mm.h 2009-07-30 09:48:10.113041063 -0400
2380c486
JR
35906@@ -39,6 +39,7 @@ extern unsigned long mmap_min_addr;
35907 #include <asm/page.h>
35908 #include <asm/pgtable.h>
35909 #include <asm/processor.h>
35910+#include <asm/mman.h>
35911
35912 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
35913
017d2877 35914@@ -106,6 +107,10 @@ extern unsigned int kobjsize(const void
2380c486 35915 #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */
017d2877 35916 #define VM_PFN_AT_MMAP 0x40000000 /* PFNMAP vma that is fully mapped at mmap time */
2380c486
JR
35917
35918+#ifdef CONFIG_PAX_PAGEEXEC
017d2877 35919+#define VM_PAGEEXEC 0x80000000 /* vma->vm_page_prot needs special handling */
2380c486
JR
35920+#endif
35921+
35922 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
35923 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
35924 #endif
017d2877 35925@@ -888,6 +893,8 @@ struct shrinker {
2380c486
JR
35926 extern void register_shrinker(struct shrinker *);
35927 extern void unregister_shrinker(struct shrinker *);
35928
35929+pgprot_t vm_get_page_prot(unsigned long vm_flags);
35930+
35931 int vma_wants_writenotify(struct vm_area_struct *vma);
35932
35933 extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
017d2877 35934@@ -1159,6 +1166,7 @@ out:
2380c486
JR
35935 }
35936
35937 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
35938+extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
35939
35940 extern unsigned long do_brk(unsigned long, unsigned long);
35941
017d2877 35942@@ -1212,6 +1220,10 @@ extern struct vm_area_struct * find_vma(
2380c486
JR
35943 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
35944 struct vm_area_struct **pprev);
35945
35946+extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
35947+extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
35948+extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
35949+
35950 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
35951 NULL if none. Assume start_addr < end_addr. */
35952 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
017d2877 35953@@ -1228,7 +1240,6 @@ static inline unsigned long vma_pages(st
2380c486
JR
35954 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
35955 }
35956
35957-pgprot_t vm_get_page_prot(unsigned long vm_flags);
35958 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
35959 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
35960 unsigned long pfn, unsigned long size, pgprot_t);
017d2877 35961@@ -1320,5 +1331,12 @@ void vmemmap_populate_print_last(void);
2380c486
JR
35962 extern void *alloc_locked_buffer(size_t size);
35963 extern void free_locked_buffer(void *buffer, size_t size);
35964 extern void release_locked_buffer(void *buffer, size_t size);
35965+
35966+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35967+extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
35968+#else
35969+static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
35970+#endif
35971+
35972 #endif /* __KERNEL__ */
35973 #endif /* _LINUX_MM_H */
017d2877
AM
35974diff -urNp linux-2.6.30.4/include/linux/mm_types.h linux-2.6.30.4/include/linux/mm_types.h
35975--- linux-2.6.30.4/include/linux/mm_types.h 2009-07-24 17:47:51.000000000 -0400
35976+++ linux-2.6.30.4/include/linux/mm_types.h 2009-07-30 09:48:10.114071629 -0400
35977@@ -163,7 +163,7 @@ struct vm_area_struct {
35978 struct anon_vma *anon_vma; /* Serialized by page_table_lock */
35979
35980 /* Function pointers to deal with this struct. */
35981- struct vm_operations_struct * vm_ops;
35982+ const struct vm_operations_struct * vm_ops;
35983
35984 /* Information about our backing store: */
35985 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
35986@@ -178,6 +178,8 @@ struct vm_area_struct {
2380c486
JR
35987 #ifdef CONFIG_NUMA
35988 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
35989 #endif
35990+
35991+ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
35992 };
35993
35994 struct core_thread {
017d2877 35995@@ -278,6 +280,24 @@ struct mm_struct {
2380c486
JR
35996 #ifdef CONFIG_MMU_NOTIFIER
35997 struct mmu_notifier_mm *mmu_notifier_mm;
35998 #endif
35999+
36000+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
36001+ unsigned long pax_flags;
36002+#endif
36003+
36004+#ifdef CONFIG_PAX_DLRESOLVE
36005+ unsigned long call_dl_resolve;
36006+#endif
36007+
36008+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
36009+ unsigned long call_syscall;
36010+#endif
36011+
36012+#ifdef CONFIG_PAX_ASLR
36013+ unsigned long delta_mmap; /* randomized offset */
36014+ unsigned long delta_stack; /* randomized offset */
36015+#endif
36016+
36017 };
36018
36019 /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */
017d2877
AM
36020diff -urNp linux-2.6.30.4/include/linux/module.h linux-2.6.30.4/include/linux/module.h
36021--- linux-2.6.30.4/include/linux/module.h 2009-07-24 17:47:51.000000000 -0400
36022+++ linux-2.6.30.4/include/linux/module.h 2009-07-30 09:48:10.114071629 -0400
36023@@ -282,16 +282,16 @@ struct module
2380c486
JR
36024 int (*init)(void);
36025
36026 /* If this is non-NULL, vfree after init() returns */
36027- void *module_init;
36028+ void *module_init_rx, *module_init_rw;
36029
36030 /* Here is the actual code + data, vfree'd on unload. */
36031- void *module_core;
36032+ void *module_core_rx, *module_core_rw;
36033
36034 /* Here are the sizes of the init and core sections */
36035- unsigned int init_size, core_size;
36036+ unsigned int init_size_rw, core_size_rw;
36037
36038 /* The size of the executable code in each section. */
36039- unsigned int init_text_size, core_text_size;
36040+ unsigned int init_size_rx, core_size_rx;
36041
36042 /* Arch-specific module values */
36043 struct mod_arch_specific arch;
017d2877
AM
36044@@ -374,16 +374,46 @@ struct module *__module_address(unsigned
36045 bool is_module_address(unsigned long addr);
36046 bool is_module_text_address(unsigned long addr);
2380c486
JR
36047
36048+static inline int within_module_range(unsigned long addr, void *start, unsigned long size)
36049+{
36050+
36051+#ifdef CONFIG_PAX_KERNEXEC
36052+ if (ktla_ktva(addr) >= (unsigned long)start &&
36053+ ktla_ktva(addr) < (unsigned long)start + size)
36054+ return 1;
36055+#endif
36056+
36057+ return ((void *)addr >= start && (void *)addr < start + size);
36058+}
36059+
36060+static inline int within_module_core_rx(unsigned long addr, struct module *mod)
36061+{
36062+ return within_module_range(addr, mod->module_core_rx, mod->core_size_rx);
36063+}
36064+
36065+static inline int within_module_core_rw(unsigned long addr, struct module *mod)
36066+{
36067+ return within_module_range(addr, mod->module_core_rw, mod->core_size_rw);
36068+}
36069+
36070+static inline int within_module_init_rx(unsigned long addr, struct module *mod)
36071+{
36072+ return within_module_range(addr, mod->module_init_rx, mod->init_size_rx);
36073+}
36074+
36075+static inline int within_module_init_rw(unsigned long addr, struct module *mod)
36076+{
36077+ return within_module_range(addr, mod->module_init_rw, mod->init_size_rw);
36078+}
36079+
36080 static inline int within_module_core(unsigned long addr, struct module *mod)
36081 {
36082- return (unsigned long)mod->module_core <= addr &&
36083- addr < (unsigned long)mod->module_core + mod->core_size;
36084+ return within_module_core_rx(addr, mod) || within_module_core_rw(addr, mod);
36085 }
36086
36087 static inline int within_module_init(unsigned long addr, struct module *mod)
36088 {
36089- return (unsigned long)mod->module_init <= addr &&
36090- addr < (unsigned long)mod->module_init + mod->init_size;
36091+ return within_module_init_rx(addr, mod) || within_module_init_rw(addr, mod);
36092 }
36093
017d2877
AM
36094 /* Search for module by name: must hold module_mutex. */
36095@@ -436,7 +466,11 @@ void symbol_put_addr(void *addr);
2380c486
JR
36096 static inline local_t *__module_ref_addr(struct module *mod, int cpu)
36097 {
36098 #ifdef CONFIG_SMP
36099+#ifdef CONFIG_X86_32
36100+ return (local_t *) (mod->refptr + __per_cpu_offset[cpu]);
36101+#else
36102 return (local_t *) (mod->refptr + per_cpu_offset(cpu));
36103+#endif
36104 #else
36105 return &mod->ref;
36106 #endif
017d2877
AM
36107diff -urNp linux-2.6.30.4/include/linux/moduleloader.h linux-2.6.30.4/include/linux/moduleloader.h
36108--- linux-2.6.30.4/include/linux/moduleloader.h 2009-07-24 17:47:51.000000000 -0400
36109+++ linux-2.6.30.4/include/linux/moduleloader.h 2009-07-30 09:48:10.114071629 -0400
2380c486
JR
36110@@ -20,9 +20,21 @@ unsigned int arch_mod_section_prepend(st
36111 sections. Returns NULL on failure. */
36112 void *module_alloc(unsigned long size);
36113
36114+#ifdef CONFIG_PAX_KERNEXEC
36115+void *module_alloc_exec(unsigned long size);
36116+#else
36117+#define module_alloc_exec(x) module_alloc(x)
36118+#endif
36119+
36120 /* Free memory returned from module_alloc. */
36121 void module_free(struct module *mod, void *module_region);
36122
36123+#ifdef CONFIG_PAX_KERNEXEC
36124+void module_free_exec(struct module *mod, void *module_region);
36125+#else
36126+#define module_free_exec(x, y) module_free(x, y)
36127+#endif
36128+
36129 /* Apply the given relocation to the (simplified) ELF. Return -error
36130 or 0. */
36131 int apply_relocate(Elf_Shdr *sechdrs,
017d2877
AM
36132diff -urNp linux-2.6.30.4/include/linux/namei.h linux-2.6.30.4/include/linux/namei.h
36133--- linux-2.6.30.4/include/linux/namei.h 2009-07-24 17:47:51.000000000 -0400
36134+++ linux-2.6.30.4/include/linux/namei.h 2009-07-30 09:48:10.115035001 -0400
2380c486
JR
36135@@ -21,7 +21,7 @@ struct nameidata {
36136 unsigned int flags;
36137 int last_type;
36138 unsigned depth;
36139- char *saved_names[MAX_NESTED_LINKS + 1];
36140+ const char *saved_names[MAX_NESTED_LINKS + 1];
36141
36142 /* Intent data */
36143 union {
017d2877 36144@@ -83,12 +83,12 @@ extern int follow_up(struct vfsmount **,
2380c486
JR
36145 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
36146 extern void unlock_rename(struct dentry *, struct dentry *);
36147
36148-static inline void nd_set_link(struct nameidata *nd, char *path)
36149+static inline void nd_set_link(struct nameidata *nd, const char *path)
36150 {
36151 nd->saved_names[nd->depth] = path;
36152 }
36153
36154-static inline char *nd_get_link(struct nameidata *nd)
36155+static inline const char *nd_get_link(struct nameidata *nd)
36156 {
36157 return nd->saved_names[nd->depth];
36158 }
017d2877
AM
36159diff -urNp linux-2.6.30.4/include/linux/nfsd/nfsd.h linux-2.6.30.4/include/linux/nfsd/nfsd.h
36160--- linux-2.6.30.4/include/linux/nfsd/nfsd.h 2009-07-24 17:47:51.000000000 -0400
36161+++ linux-2.6.30.4/include/linux/nfsd/nfsd.h 2009-07-30 09:48:10.115035001 -0400
36162@@ -57,7 +57,7 @@ extern u32 nfsd_supported_minorversion
36163 extern struct mutex nfsd_mutex;
36164 extern struct svc_serv *nfsd_serv;
36165
36166-extern struct seq_operations nfs_exports_op;
36167+extern const struct seq_operations nfs_exports_op;
36168
36169 /*
36170 * Function prototypes.
36171diff -urNp linux-2.6.30.4/include/linux/nodemask.h linux-2.6.30.4/include/linux/nodemask.h
36172--- linux-2.6.30.4/include/linux/nodemask.h 2009-07-24 17:47:51.000000000 -0400
36173+++ linux-2.6.30.4/include/linux/nodemask.h 2009-07-30 09:48:10.115035001 -0400
2380c486
JR
36174@@ -442,11 +442,11 @@ static inline int num_node_state(enum no
36175
36176 #define any_online_node(mask) \
36177 ({ \
36178- int node; \
36179- for_each_node_mask(node, (mask)) \
36180- if (node_online(node)) \
36181+ int __node; \
36182+ for_each_node_mask(__node, (mask)) \
36183+ if (node_online(__node)) \
36184 break; \
36185- node; \
36186+ __node; \
36187 })
36188
36189 #define num_online_nodes() num_node_state(N_ONLINE)
017d2877
AM
36190diff -urNp linux-2.6.30.4/include/linux/oprofile.h linux-2.6.30.4/include/linux/oprofile.h
36191--- linux-2.6.30.4/include/linux/oprofile.h 2009-07-24 17:47:51.000000000 -0400
36192+++ linux-2.6.30.4/include/linux/oprofile.h 2009-07-30 09:48:10.116076362 -0400
de855c5d
AM
36193@@ -128,7 +128,7 @@ int oprofilefs_create_ro_ulong(struct su
36194
36195 /** Create a file for read-only access to an atomic_t. */
36196 int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root,
36197- char const * name, atomic_t * val);
36198+ char const * name, atomic_unchecked_t * val);
36199
36200 /** create a directory */
36201 struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root,
017d2877
AM
36202diff -urNp linux-2.6.30.4/include/linux/poison.h linux-2.6.30.4/include/linux/poison.h
36203--- linux-2.6.30.4/include/linux/poison.h 2009-07-24 17:47:51.000000000 -0400
36204+++ linux-2.6.30.4/include/linux/poison.h 2009-07-30 09:48:10.116076362 -0400
2380c486
JR
36205@@ -7,8 +7,8 @@
36206 * under normal circumstances, used to verify that nobody uses
36207 * non-initialized list entries.
36208 */
36209-#define LIST_POISON1 ((void *) 0x00100100)
36210-#define LIST_POISON2 ((void *) 0x00200200)
36211+#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
36212+#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
36213
36214 /********** include/linux/timer.h **********/
36215 /*
017d2877
AM
36216diff -urNp linux-2.6.30.4/include/linux/proc_fs.h linux-2.6.30.4/include/linux/proc_fs.h
36217--- linux-2.6.30.4/include/linux/proc_fs.h 2009-07-24 17:47:51.000000000 -0400
36218+++ linux-2.6.30.4/include/linux/proc_fs.h 2009-07-30 11:10:49.495569147 -0400
36219@@ -170,6 +170,19 @@ static inline struct proc_dir_entry *pro
2380c486
JR
36220 return proc_create_data(name, mode, parent, proc_fops, NULL);
36221 }
36222
36223+static inline struct proc_dir_entry *proc_create_grsec(const char *name, mode_t mode,
36224+ struct proc_dir_entry *parent, const struct file_operations *proc_fops)
36225+{
36226+#ifdef CONFIG_GRKERNSEC_PROC_USER
36227+ return proc_create_data(name, S_IRUSR, parent, proc_fops, NULL);
36228+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36229+ return proc_create_data(name, S_IRUSR | S_IRGRP, parent, proc_fops, NULL);
36230+#else
36231+ return proc_create_data(name, mode, parent, proc_fops, NULL);
36232+#endif
36233+}
36234+
36235+
36236 static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
36237 mode_t mode, struct proc_dir_entry *base,
36238 read_proc_t *read_proc, void * data)
017d2877
AM
36239diff -urNp linux-2.6.30.4/include/linux/random.h linux-2.6.30.4/include/linux/random.h
36240--- linux-2.6.30.4/include/linux/random.h 2009-07-24 17:47:51.000000000 -0400
36241+++ linux-2.6.30.4/include/linux/random.h 2009-07-30 09:48:10.116076362 -0400
2380c486
JR
36242@@ -74,6 +74,11 @@ unsigned long randomize_range(unsigned l
36243 u32 random32(void);
36244 void srandom32(u32 seed);
36245
36246+static inline unsigned long pax_get_random_long(void)
36247+{
36248+ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
36249+}
36250+
36251 #endif /* __KERNEL___ */
36252
36253 #endif /* _LINUX_RANDOM_H */
017d2877
AM
36254diff -urNp linux-2.6.30.4/include/linux/reiserfs_fs_sb.h linux-2.6.30.4/include/linux/reiserfs_fs_sb.h
36255--- linux-2.6.30.4/include/linux/reiserfs_fs_sb.h 2009-07-24 17:47:51.000000000 -0400
36256+++ linux-2.6.30.4/include/linux/reiserfs_fs_sb.h 2009-07-30 09:48:10.116076362 -0400
36257@@ -377,7 +377,7 @@ struct reiserfs_sb_info {
de855c5d
AM
36258 /* Comment? -Hans */
36259 wait_queue_head_t s_wait;
36260 /* To be obsoleted soon by per buffer seals.. -Hans */
36261- atomic_t s_generation_counter; // increased by one every time the
36262+ atomic_unchecked_t s_generation_counter; // increased by one every time the
36263 // tree gets re-balanced
36264 unsigned long s_properties; /* File system properties. Currently holds
36265 on-disk FS format */
017d2877
AM
36266diff -urNp linux-2.6.30.4/include/linux/sched.h linux-2.6.30.4/include/linux/sched.h
36267--- linux-2.6.30.4/include/linux/sched.h 2009-07-30 20:32:40.547619620 -0400
36268+++ linux-2.6.30.4/include/linux/sched.h 2009-07-30 20:32:48.019825232 -0400
36269@@ -98,6 +98,7 @@ struct robust_list_head;
2380c486
JR
36270 struct bio;
36271 struct bts_tracer;
017d2877 36272 struct fs_struct;
2380c486
JR
36273+struct linux_binprm;
36274
36275 /*
36276 * List of flags we want to share for kernel threads,
017d2877 36277@@ -604,6 +605,15 @@ struct signal_struct {
2380c486
JR
36278 unsigned audit_tty;
36279 struct tty_audit_buf *tty_audit_buf;
36280 #endif
36281+
36282+#ifdef CONFIG_GRKERNSEC
36283+ u32 curr_ip;
36284+ u32 gr_saddr;
36285+ u32 gr_daddr;
36286+ u16 gr_sport;
36287+ u16 gr_dport;
36288+ u8 used_accept:1;
36289+#endif
36290 };
36291
36292 /* Context switch must be unlocked if interrupts are to be enabled */
017d2877 36293@@ -1116,7 +1126,7 @@ struct sched_rt_entity {
2380c486
JR
36294
36295 struct task_struct {
36296 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
36297- void *stack;
36298+ struct thread_info *stack;
36299 atomic_t usage;
36300 unsigned int flags; /* per process flags, defined below */
36301 unsigned int ptrace;
017d2877 36302@@ -1227,8 +1237,8 @@ struct task_struct {
2380c486
JR
36303 struct list_head thread_group;
36304
36305 struct completion *vfork_done; /* for vfork() */
36306- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
36307- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
36308+ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
36309+ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
36310
36311 cputime_t utime, stime, utimescaled, stimescaled;
36312 cputime_t gtime;
017d2877 36313@@ -1429,8 +1439,66 @@ struct task_struct {
2380c486
JR
36314 /* state flags for use by tracers */
36315 unsigned long trace;
36316 #endif
36317+
36318+#ifdef CONFIG_GRKERNSEC
36319+ /* grsecurity */
36320+ struct acl_subject_label *acl;
36321+ struct acl_role_label *role;
36322+ struct file *exec_file;
36323+ u16 acl_role_id;
36324+ u8 acl_sp_role;
36325+ u8 is_writable;
36326+ u8 brute;
36327+#endif
36328+
36329 };
36330
36331+#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
36332+#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
36333+#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
36334+#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
36335+/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
36336+#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
36337+
36338+#ifdef CONFIG_PAX_SOFTMODE
36339+extern unsigned int pax_softmode;
36340+#endif
36341+
36342+extern int pax_check_flags(unsigned long *);
36343+
36344+/* if tsk != current then task_lock must be held on it */
36345+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
36346+static inline unsigned long pax_get_flags(struct task_struct *tsk)
36347+{
36348+ if (likely(tsk->mm))
36349+ return tsk->mm->pax_flags;
36350+ else
36351+ return 0UL;
36352+}
36353+
36354+/* if tsk != current then task_lock must be held on it */
36355+static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
36356+{
36357+ if (likely(tsk->mm)) {
36358+ tsk->mm->pax_flags = flags;
36359+ return 0;
36360+ }
36361+ return -EINVAL;
36362+}
36363+#endif
36364+
36365+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
36366+extern void pax_set_initial_flags(struct linux_binprm *bprm);
36367+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
36368+extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
36369+#endif
36370+
36371+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
36372+void pax_report_insns(void *pc, void *sp);
36373+void pax_report_refcount_overflow(struct pt_regs *regs);
de855c5d
AM
36374+void pax_report_leak_to_user(const void *ptr, unsigned long len);
36375+void pax_report_overflow_from_user(const void *ptr, unsigned long len);
2380c486
JR
36376+
36377 /* Future-safe accessor for struct task_struct's cpus_allowed. */
36378 #define tsk_cpumask(tsk) (&(tsk)->cpus_allowed)
36379
017d2877 36380@@ -1988,7 +2056,7 @@ extern void __cleanup_sighand(struct sig
2380c486
JR
36381 extern void exit_itimers(struct signal_struct *);
36382 extern void flush_itimer_signals(void);
36383
36384-extern NORET_TYPE void do_group_exit(int);
36385+extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
36386
36387 extern void daemonize(const char *, ...);
36388 extern int allow_signal(int);
017d2877 36389@@ -2098,8 +2166,8 @@ static inline void unlock_task_sighand(s
2380c486
JR
36390
36391 #ifndef __HAVE_THREAD_FUNCTIONS
36392
36393-#define task_thread_info(task) ((struct thread_info *)(task)->stack)
36394-#define task_stack_page(task) ((task)->stack)
36395+#define task_thread_info(task) ((task)->stack)
36396+#define task_stack_page(task) ((void *)(task)->stack)
36397
36398 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
36399 {
017d2877
AM
36400@@ -2114,7 +2182,7 @@ static inline unsigned long *end_of_stac
36401
36402 #endif
36403
36404-static inline int object_is_on_stack(void *obj)
36405+static inline int object_is_on_stack(const void *obj)
36406 {
36407 void *stack = task_stack_page(current);
36408
36409diff -urNp linux-2.6.30.4/include/linux/screen_info.h linux-2.6.30.4/include/linux/screen_info.h
36410--- linux-2.6.30.4/include/linux/screen_info.h 2009-07-24 17:47:51.000000000 -0400
36411+++ linux-2.6.30.4/include/linux/screen_info.h 2009-07-30 09:48:10.117039309 -0400
2380c486
JR
36412@@ -42,7 +42,8 @@ struct screen_info {
36413 __u16 pages; /* 0x32 */
36414 __u16 vesa_attributes; /* 0x34 */
36415 __u32 capabilities; /* 0x36 */
36416- __u8 _reserved[6]; /* 0x3a */
36417+ __u16 vesapm_size; /* 0x3a */
36418+ __u8 _reserved[4]; /* 0x3c */
36419 } __attribute__((packed));
36420
36421 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
017d2877
AM
36422diff -urNp linux-2.6.30.4/include/linux/security.h linux-2.6.30.4/include/linux/security.h
36423--- linux-2.6.30.4/include/linux/security.h 2009-07-24 17:47:51.000000000 -0400
36424+++ linux-2.6.30.4/include/linux/security.h 2009-07-30 11:22:42.449401037 -0400
36425@@ -33,6 +33,7 @@
2380c486
JR
36426 #include <linux/key.h>
36427 #include <linux/xfrm.h>
017d2877 36428 #include <linux/gfp.h>
2380c486
JR
36429+#include <linux/grsecurity.h>
36430 #include <net/flow.h>
36431
36432 /* Maximum number of letters for an LSM name string */
017d2877
AM
36433diff -urNp linux-2.6.30.4/include/linux/shm.h linux-2.6.30.4/include/linux/shm.h
36434--- linux-2.6.30.4/include/linux/shm.h 2009-07-24 17:47:51.000000000 -0400
36435+++ linux-2.6.30.4/include/linux/shm.h 2009-07-30 11:10:49.530519651 -0400
2380c486
JR
36436@@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
36437 pid_t shm_cprid;
36438 pid_t shm_lprid;
36439 struct user_struct *mlock_user;
36440+#ifdef CONFIG_GRKERNSEC
36441+ time_t shm_createtime;
36442+ pid_t shm_lapid;
36443+#endif
36444 };
36445
36446 /* shm_mode upper byte flags */
017d2877
AM
36447diff -urNp linux-2.6.30.4/include/linux/slab.h linux-2.6.30.4/include/linux/slab.h
36448--- linux-2.6.30.4/include/linux/slab.h 2009-07-24 17:47:51.000000000 -0400
36449+++ linux-2.6.30.4/include/linux/slab.h 2009-07-30 09:48:10.117976173 -0400
2380c486
JR
36450@@ -73,10 +73,9 @@
36451 * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
36452 * Both make kfree a no-op.
36453 */
36454-#define ZERO_SIZE_PTR ((void *)16)
36455+#define ZERO_SIZE_PTR ((void *)-1024L)
36456
36457-#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
36458- (unsigned long)ZERO_SIZE_PTR)
36459+#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
36460
36461 /*
36462 * struct kmem_cache related prototypes
de855c5d
AM
36463@@ -129,6 +128,7 @@ void * __must_check krealloc(const void
36464 void kfree(const void *);
36465 void kzfree(const void *);
36466 size_t ksize(const void *);
36467+void check_object_size(const void *ptr, unsigned long n, bool to);
36468
36469 /*
36470 * Allocator specific definitions. These are mainly used to establish optimized
017d2877 36471@@ -317,4 +317,37 @@ static inline void *kzalloc_node(size_t
de855c5d
AM
36472 return kmalloc_node(size, flags | __GFP_ZERO, node);
36473 }
36474
017d2877
AM
36475+#define kmalloc(x, y) \
36476+({ \
36477+ void *___retval; \
36478+ intoverflow_t ___x = (intoverflow_t)x; \
36479+ if (WARN(___x > ULONG_MAX, "kmalloc size overflow\n"))\
36480+ ___retval = NULL; \
36481+ else \
36482+ ___retval = kmalloc((size_t)___x, (y)); \
36483+ ___retval; \
36484+})
36485+
36486+#define kmalloc_node(x, y, z) \
36487+({ \
36488+ void *___retval; \
36489+ intoverflow_t ___x = (intoverflow_t)x; \
36490+ if (WARN(___x > ULONG_MAX, "kmalloc_node size overflow\n"))\
36491+ ___retval = NULL; \
36492+ else \
36493+ ___retval = kmalloc_node((size_t)___x, (y), (z));\
36494+ ___retval; \
36495+})
36496+
36497+#define kzalloc(x, y) \
36498+({ \
36499+ void *___retval; \
36500+ intoverflow_t ___x = (intoverflow_t)x; \
36501+ if (WARN(___x > ULONG_MAX, "kzalloc size overflow\n"))\
36502+ ___retval = NULL; \
36503+ else \
36504+ ___retval = kzalloc((size_t)___x, (y)); \
36505+ ___retval; \
36506+})
de855c5d
AM
36507+
36508 #endif /* _LINUX_SLAB_H */
017d2877
AM
36509diff -urNp linux-2.6.30.4/include/linux/slub_def.h linux-2.6.30.4/include/linux/slub_def.h
36510--- linux-2.6.30.4/include/linux/slub_def.h 2009-07-24 17:47:51.000000000 -0400
36511+++ linux-2.6.30.4/include/linux/slub_def.h 2009-07-30 09:48:10.117976173 -0400
2380c486
JR
36512@@ -85,7 +85,7 @@ struct kmem_cache {
36513 struct kmem_cache_order_objects max;
36514 struct kmem_cache_order_objects min;
36515 gfp_t allocflags; /* gfp flags to use on each alloc */
36516- int refcount; /* Refcount for slab cache destroy */
36517+ atomic_t refcount; /* Refcount for slab cache destroy */
36518 void (*ctor)(void *);
36519 int inuse; /* Offset to metadata */
36520 int align; /* Alignment */
017d2877
AM
36521diff -urNp linux-2.6.30.4/include/linux/sonet.h linux-2.6.30.4/include/linux/sonet.h
36522--- linux-2.6.30.4/include/linux/sonet.h 2009-07-24 17:47:51.000000000 -0400
36523+++ linux-2.6.30.4/include/linux/sonet.h 2009-07-30 09:48:10.118663996 -0400
36524@@ -61,7 +61,7 @@ struct sonet_stats {
36525 #include <asm/atomic.h>
36526
36527 struct k_sonet_stats {
36528-#define __HANDLE_ITEM(i) atomic_t i
36529+#define __HANDLE_ITEM(i) atomic_unchecked_t i
36530 __SONET_ITEMS
36531 #undef __HANDLE_ITEM
36532 };
36533diff -urNp linux-2.6.30.4/include/linux/sysctl.h linux-2.6.30.4/include/linux/sysctl.h
36534--- linux-2.6.30.4/include/linux/sysctl.h 2009-07-24 17:47:51.000000000 -0400
36535+++ linux-2.6.30.4/include/linux/sysctl.h 2009-07-30 09:48:10.118663996 -0400
2380c486
JR
36536@@ -165,7 +165,11 @@ enum
36537 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
36538 };
36539
36540-
36541+#ifdef CONFIG_PAX_SOFTMODE
36542+enum {
36543+ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
36544+};
36545+#endif
36546
36547 /* CTL_VM names: */
36548 enum
017d2877
AM
36549diff -urNp linux-2.6.30.4/include/linux/thread_info.h linux-2.6.30.4/include/linux/thread_info.h
36550--- linux-2.6.30.4/include/linux/thread_info.h 2009-07-24 17:47:51.000000000 -0400
36551+++ linux-2.6.30.4/include/linux/thread_info.h 2009-07-30 09:48:10.118663996 -0400
2380c486
JR
36552@@ -23,7 +23,7 @@ struct restart_block {
36553 };
36554 /* For futex_wait */
36555 struct {
36556- u32 *uaddr;
36557+ u32 __user *uaddr;
36558 u32 val;
36559 u32 flags;
36560 u32 bitset;
017d2877
AM
36561diff -urNp linux-2.6.30.4/include/linux/tty_ldisc.h linux-2.6.30.4/include/linux/tty_ldisc.h
36562--- linux-2.6.30.4/include/linux/tty_ldisc.h 2009-07-24 17:47:51.000000000 -0400
36563+++ linux-2.6.30.4/include/linux/tty_ldisc.h 2009-07-30 09:48:10.118663996 -0400
2380c486
JR
36564@@ -139,12 +139,12 @@ struct tty_ldisc_ops {
36565
36566 struct module *owner;
36567
36568- int refcount;
36569+ atomic_t refcount;
36570 };
36571
36572 struct tty_ldisc {
36573 struct tty_ldisc_ops *ops;
36574- int refcount;
36575+ atomic_t refcount;
36576 };
36577
36578 #define TTY_LDISC_MAGIC 0x5403
017d2877
AM
36579diff -urNp linux-2.6.30.4/include/linux/types.h linux-2.6.30.4/include/linux/types.h
36580--- linux-2.6.30.4/include/linux/types.h 2009-07-24 17:47:51.000000000 -0400
36581+++ linux-2.6.30.4/include/linux/types.h 2009-07-30 09:48:10.118663996 -0400
36582@@ -191,10 +191,26 @@ typedef struct {
de855c5d
AM
36583 volatile int counter;
36584 } atomic_t;
36585
36586+#ifdef CONFIG_PAX_REFCOUNT
36587+typedef struct {
36588+ volatile int counter;
36589+} atomic_unchecked_t;
36590+#else
36591+typedef atomic_t atomic_unchecked_t;
36592+#endif
36593+
36594 #ifdef CONFIG_64BIT
36595 typedef struct {
36596 volatile long counter;
36597 } atomic64_t;
36598+
36599+#ifdef CONFIG_PAX_REFCOUNT
36600+typedef struct {
36601+ volatile long counter;
36602+} atomic64_unchecked_t;
36603+#else
36604+typedef atomic64_t atomic64_unchecked_t;
36605+#endif
36606 #endif
36607
36608 struct ustat {
017d2877
AM
36609diff -urNp linux-2.6.30.4/include/linux/uaccess.h linux-2.6.30.4/include/linux/uaccess.h
36610--- linux-2.6.30.4/include/linux/uaccess.h 2009-07-24 17:47:51.000000000 -0400
36611+++ linux-2.6.30.4/include/linux/uaccess.h 2009-07-30 09:48:10.118663996 -0400
2380c486
JR
36612@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
36613 long ret; \
36614 mm_segment_t old_fs = get_fs(); \
36615 \
36616- set_fs(KERNEL_DS); \
36617 pagefault_disable(); \
36618+ set_fs(KERNEL_DS); \
36619 ret = __copy_from_user_inatomic(&(retval), (__force typeof(retval) __user *)(addr), sizeof(retval)); \
36620- pagefault_enable(); \
36621 set_fs(old_fs); \
36622+ pagefault_enable(); \
36623 ret; \
36624 })
36625
017d2877
AM
36626diff -urNp linux-2.6.30.4/include/linux/vmalloc.h linux-2.6.30.4/include/linux/vmalloc.h
36627--- linux-2.6.30.4/include/linux/vmalloc.h 2009-07-24 17:47:51.000000000 -0400
36628+++ linux-2.6.30.4/include/linux/vmalloc.h 2009-07-30 09:48:10.119975963 -0400
2380c486
JR
36629@@ -13,6 +13,11 @@ struct vm_area_struct; /* vma defining
36630 #define VM_MAP 0x00000004 /* vmap()ed pages */
36631 #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
36632 #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
36633+
36634+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
36635+#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */
36636+#endif
36637+
36638 /* bits [20..32] reserved for arch specific ioremap internals */
36639
36640 /*
017d2877 36641@@ -115,4 +120,81 @@ extern rwlock_t vmlist_lock;
de855c5d 36642 extern struct vm_struct *vmlist;
017d2877
AM
36643 extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
36644
36645+#define vmalloc(x) \
36646+({ \
36647+ void *___retval; \
36648+ intoverflow_t ___x = (intoverflow_t)x; \
36649+ if (WARN(___x > ULONG_MAX, "vmalloc size overflow\n")) \
36650+ ___retval = NULL; \
36651+ else \
36652+ ___retval = vmalloc((unsigned long)___x); \
36653+ ___retval; \
36654+})
36655+
36656+#define __vmalloc(x, y, z) \
36657+({ \
36658+ void *___retval; \
36659+ intoverflow_t ___x = (intoverflow_t)x; \
36660+ if (WARN(___x > ULONG_MAX, "__vmalloc size overflow\n"))\
36661+ ___retval = NULL; \
36662+ else \
36663+ ___retval = __vmalloc((unsigned long)___x, (y), (z));\
36664+ ___retval; \
36665+})
36666+
36667+#define vmalloc_user(x) \
36668+({ \
36669+ void *___retval; \
36670+ intoverflow_t ___x = (intoverflow_t)x; \
36671+ if (WARN(___x > ULONG_MAX, "vmalloc_user size overflow\n"))\
36672+ ___retval = NULL; \
36673+ else \
36674+ ___retval = vmalloc_user((unsigned long)___x); \
36675+ ___retval; \
36676+})
36677+
36678+#define vmalloc_exec(x) \
36679+({ \
36680+ void *___retval; \
36681+ intoverflow_t ___x = (intoverflow_t)x; \
36682+ if (WARN(___x > ULONG_MAX, "vmalloc_exec size overflow\n"))\
36683+ ___retval = NULL; \
36684+ else \
36685+ ___retval = vmalloc_exec((unsigned long)___x); \
36686+ ___retval; \
36687+})
36688+
36689+#define vmalloc_node(x, y) \
36690+({ \
36691+ void *___retval; \
36692+ intoverflow_t ___x = (intoverflow_t)x; \
36693+ if (WARN(___x > ULONG_MAX, "vmalloc_node size overflow\n"))\
36694+ ___retval = NULL; \
36695+ else \
36696+ ___retval = vmalloc_node((unsigned long)___x, (y));\
36697+ ___retval; \
36698+})
36699+
36700+#define vmalloc_32(x) \
36701+({ \
36702+ void *___retval; \
36703+ intoverflow_t ___x = (intoverflow_t)x; \
36704+ if (WARN(___x > ULONG_MAX, "vmalloc_32 size overflow\n"))\
36705+ ___retval = NULL; \
36706+ else \
36707+ ___retval = vmalloc_32((unsigned long)___x); \
36708+ ___retval; \
36709+})
36710+
36711+#define vmalloc_32_user(x) \
36712+({ \
36713+ void *___retval; \
36714+ intoverflow_t ___x = (intoverflow_t)x; \
36715+ if (WARN(___x > ULONG_MAX, "vmalloc_32_user size overflow\n"))\
36716+ ___retval = NULL; \
36717+ else \
36718+ ___retval = vmalloc_32_user((unsigned long)___x);\
36719+ ___retval; \
36720+})
de855c5d
AM
36721+
36722 #endif /* _LINUX_VMALLOC_H */
017d2877
AM
36723diff -urNp linux-2.6.30.4/include/net/sctp/sctp.h linux-2.6.30.4/include/net/sctp/sctp.h
36724--- linux-2.6.30.4/include/net/sctp/sctp.h 2009-07-24 17:47:51.000000000 -0400
36725+++ linux-2.6.30.4/include/net/sctp/sctp.h 2009-07-30 09:48:10.119975963 -0400
36726@@ -305,8 +305,8 @@ extern int sctp_debug_flag;
2380c486
JR
36727
36728 #else /* SCTP_DEBUG */
36729
36730-#define SCTP_DEBUG_PRINTK(whatever...)
36731-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
36732+#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
36733+#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
36734 #define SCTP_ENABLE_DEBUG
36735 #define SCTP_DISABLE_DEBUG
36736 #define SCTP_ASSERT(expr, str, func)
017d2877
AM
36737diff -urNp linux-2.6.30.4/include/sound/core.h linux-2.6.30.4/include/sound/core.h
36738--- linux-2.6.30.4/include/sound/core.h 2009-07-24 17:47:51.000000000 -0400
36739+++ linux-2.6.30.4/include/sound/core.h 2009-07-30 09:48:10.119975963 -0400
36740@@ -439,7 +439,7 @@ static inline int __snd_bug_on(int cond)
2380c486
JR
36741 */
36742 #define snd_printdd(format, args...) snd_printk(format, ##args)
36743 #else
36744-#define snd_printdd(format, args...) /* nothing */
36745+#define snd_printdd(format, args...) do {} while (0)
36746 #endif
36747
36748
017d2877
AM
36749diff -urNp linux-2.6.30.4/include/video/uvesafb.h linux-2.6.30.4/include/video/uvesafb.h
36750--- linux-2.6.30.4/include/video/uvesafb.h 2009-07-24 17:47:51.000000000 -0400
36751+++ linux-2.6.30.4/include/video/uvesafb.h 2009-07-30 09:48:10.120938150 -0400
2380c486
JR
36752@@ -177,6 +177,7 @@ struct uvesafb_par {
36753 u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
36754 u8 pmi_setpal; /* PMI for palette changes */
36755 u16 *pmi_base; /* protected mode interface location */
36756+ u8 *pmi_code; /* protected mode code location */
36757 void *pmi_start;
36758 void *pmi_pal;
36759 u8 *vbe_state_orig; /*
017d2877
AM
36760diff -urNp linux-2.6.30.4/init/do_mounts.c linux-2.6.30.4/init/do_mounts.c
36761--- linux-2.6.30.4/init/do_mounts.c 2009-07-24 17:47:51.000000000 -0400
36762+++ linux-2.6.30.4/init/do_mounts.c 2009-07-30 09:48:10.121806882 -0400
36763@@ -216,11 +216,11 @@ static void __init get_fs_names(char *pa
2380c486
JR
36764
36765 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
36766 {
36767- int err = sys_mount(name, "/root", fs, flags, data);
36768+ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
36769 if (err)
36770 return err;
36771
36772- sys_chdir("/root");
36773+ sys_chdir((char __user *)"/root");
36774 ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
36775 printk("VFS: Mounted root (%s filesystem)%s on device %u:%u.\n",
36776 current->fs->pwd.mnt->mnt_sb->s_type->name,
017d2877 36777@@ -310,18 +310,18 @@ void __init change_floppy(char *fmt, ...
2380c486
JR
36778 va_start(args, fmt);
36779 vsprintf(buf, fmt, args);
36780 va_end(args);
36781- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
36782+ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
36783 if (fd >= 0) {
36784 sys_ioctl(fd, FDEJECT, 0);
36785 sys_close(fd);
36786 }
36787 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
36788- fd = sys_open("/dev/console", O_RDWR, 0);
36789+ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
36790 if (fd >= 0) {
36791 sys_ioctl(fd, TCGETS, (long)&termios);
36792 termios.c_lflag &= ~ICANON;
36793 sys_ioctl(fd, TCSETSF, (long)&termios);
36794- sys_read(fd, &c, 1);
36795+ sys_read(fd, (char __user *)&c, 1);
36796 termios.c_lflag |= ICANON;
36797 sys_ioctl(fd, TCSETSF, (long)&termios);
36798 sys_close(fd);
017d2877 36799@@ -414,7 +414,7 @@ void __init prepare_namespace(void)
2380c486
JR
36800
36801 mount_root();
36802 out:
36803- sys_mount(".", "/", NULL, MS_MOVE, NULL);
36804- sys_chroot(".");
36805+ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
36806+ sys_chroot((char __user *)".");
36807 }
36808
017d2877
AM
36809diff -urNp linux-2.6.30.4/init/do_mounts.h linux-2.6.30.4/init/do_mounts.h
36810--- linux-2.6.30.4/init/do_mounts.h 2009-07-24 17:47:51.000000000 -0400
36811+++ linux-2.6.30.4/init/do_mounts.h 2009-07-30 09:48:10.121806882 -0400
36812@@ -15,15 +15,15 @@ extern int root_mountflags;
2380c486
JR
36813
36814 static inline int create_dev(char *name, dev_t dev)
36815 {
36816- sys_unlink(name);
36817- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
36818+ sys_unlink((char __user *)name);
36819+ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
36820 }
36821
36822 #if BITS_PER_LONG == 32
36823 static inline u32 bstat(char *name)
36824 {
36825 struct stat64 stat;
36826- if (sys_stat64(name, &stat) != 0)
36827+ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
36828 return 0;
36829 if (!S_ISBLK(stat.st_mode))
36830 return 0;
017d2877
AM
36831diff -urNp linux-2.6.30.4/init/do_mounts_initrd.c linux-2.6.30.4/init/do_mounts_initrd.c
36832--- linux-2.6.30.4/init/do_mounts_initrd.c 2009-07-24 17:47:51.000000000 -0400
36833+++ linux-2.6.30.4/init/do_mounts_initrd.c 2009-07-30 09:48:10.121806882 -0400
2380c486
JR
36834@@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
36835 sys_close(old_fd);sys_close(root_fd);
36836 sys_close(0);sys_close(1);sys_close(2);
36837 sys_setsid();
36838- (void) sys_open("/dev/console",O_RDWR,0);
36839+ (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
36840 (void) sys_dup(0);
36841 (void) sys_dup(0);
36842 return kernel_execve(shell, argv, envp_init);
36843@@ -47,13 +47,13 @@ static void __init handle_initrd(void)
36844 create_dev("/dev/root.old", Root_RAM0);
36845 /* mount initrd on rootfs' /root */
36846 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
36847- sys_mkdir("/old", 0700);
36848- root_fd = sys_open("/", 0, 0);
36849- old_fd = sys_open("/old", 0, 0);
36850+ sys_mkdir((const char __user *)"/old", 0700);
36851+ root_fd = sys_open((const char __user *)"/", 0, 0);
36852+ old_fd = sys_open((const char __user *)"/old", 0, 0);
36853 /* move initrd over / and chdir/chroot in initrd root */
36854- sys_chdir("/root");
36855- sys_mount(".", "/", NULL, MS_MOVE, NULL);
36856- sys_chroot(".");
36857+ sys_chdir((const char __user *)"/root");
36858+ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
36859+ sys_chroot((const char __user *)".");
36860
36861 /*
36862 * In case that a resume from disk is carried out by linuxrc or one of
36863@@ -70,15 +70,15 @@ static void __init handle_initrd(void)
36864
36865 /* move initrd to rootfs' /old */
36866 sys_fchdir(old_fd);
36867- sys_mount("/", ".", NULL, MS_MOVE, NULL);
36868+ sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
36869 /* switch root and cwd back to / of rootfs */
36870 sys_fchdir(root_fd);
36871- sys_chroot(".");
36872+ sys_chroot((const char __user *)".");
36873 sys_close(old_fd);
36874 sys_close(root_fd);
36875
36876 if (new_decode_dev(real_root_dev) == Root_RAM0) {
36877- sys_chdir("/old");
36878+ sys_chdir((const char __user *)"/old");
36879 return;
36880 }
36881
36882@@ -86,17 +86,17 @@ static void __init handle_initrd(void)
36883 mount_root();
36884
36885 printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
36886- error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
36887+ error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
36888 if (!error)
36889 printk("okay\n");
36890 else {
36891- int fd = sys_open("/dev/root.old", O_RDWR, 0);
36892+ int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
36893 if (error == -ENOENT)
36894 printk("/initrd does not exist. Ignored.\n");
36895 else
36896 printk("failed\n");
36897 printk(KERN_NOTICE "Unmounting old root\n");
36898- sys_umount("/old", MNT_DETACH);
36899+ sys_umount((char __user *)"/old", MNT_DETACH);
36900 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
36901 if (fd < 0) {
36902 error = fd;
36903@@ -119,11 +119,11 @@ int __init initrd_load(void)
36904 * mounted in the normal path.
36905 */
36906 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
36907- sys_unlink("/initrd.image");
36908+ sys_unlink((const char __user *)"/initrd.image");
36909 handle_initrd();
36910 return 1;
36911 }
36912 }
36913- sys_unlink("/initrd.image");
36914+ sys_unlink((const char __user *)"/initrd.image");
36915 return 0;
36916 }
017d2877
AM
36917diff -urNp linux-2.6.30.4/init/do_mounts_md.c linux-2.6.30.4/init/do_mounts_md.c
36918--- linux-2.6.30.4/init/do_mounts_md.c 2009-07-24 17:47:51.000000000 -0400
36919+++ linux-2.6.30.4/init/do_mounts_md.c 2009-07-30 09:48:10.121806882 -0400
36920@@ -170,7 +170,7 @@ static void __init md_setup_drive(void)
2380c486
JR
36921 partitioned ? "_d" : "", minor,
36922 md_setup_args[ent].device_names);
36923
36924- fd = sys_open(name, 0, 0);
36925+ fd = sys_open((char __user *)name, 0, 0);
36926 if (fd < 0) {
36927 printk(KERN_ERR "md: open failed - cannot start "
36928 "array %s\n", name);
017d2877 36929@@ -233,7 +233,7 @@ static void __init md_setup_drive(void)
2380c486
JR
36930 * array without it
36931 */
36932 sys_close(fd);
36933- fd = sys_open(name, 0, 0);
36934+ fd = sys_open((char __user *)name, 0, 0);
36935 sys_ioctl(fd, BLKRRPART, 0);
36936 }
36937 sys_close(fd);
017d2877 36938@@ -283,7 +283,7 @@ static void __init autodetect_raid(void)
2380c486
JR
36939
36940 wait_for_device_probe();
36941
36942- fd = sys_open("/dev/md0", 0, 0);
36943+ fd = sys_open((char __user *)"/dev/md0", 0, 0);
36944 if (fd >= 0) {
36945 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
36946 sys_close(fd);
017d2877
AM
36947diff -urNp linux-2.6.30.4/init/initramfs.c linux-2.6.30.4/init/initramfs.c
36948--- linux-2.6.30.4/init/initramfs.c 2009-07-24 17:47:51.000000000 -0400
36949+++ linux-2.6.30.4/init/initramfs.c 2009-07-30 09:48:10.121806882 -0400
36950@@ -271,7 +271,7 @@ static int __init maybe_link(void)
2380c486
JR
36951 if (nlink >= 2) {
36952 char *old = find_link(major, minor, ino, mode, collected);
36953 if (old)
36954- return (sys_link(old, collected) < 0) ? -1 : 1;
36955+ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
36956 }
36957 return 0;
36958 }
017d2877 36959@@ -280,11 +280,11 @@ static void __init clean_path(char *path
2380c486
JR
36960 {
36961 struct stat st;
36962
36963- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
36964+ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
36965 if (S_ISDIR(st.st_mode))
36966- sys_rmdir(path);
36967+ sys_rmdir((char __user *)path);
36968 else
36969- sys_unlink(path);
36970+ sys_unlink((char __user *)path);
36971 }
36972 }
36973
017d2877 36974@@ -305,7 +305,7 @@ static int __init do_name(void)
2380c486
JR
36975 int openflags = O_WRONLY|O_CREAT;
36976 if (ml != 1)
36977 openflags |= O_TRUNC;
36978- wfd = sys_open(collected, openflags, mode);
36979+ wfd = sys_open((char __user *)collected, openflags, mode);
36980
36981 if (wfd >= 0) {
36982 sys_fchown(wfd, uid, gid);
017d2877 36983@@ -317,16 +317,16 @@ static int __init do_name(void)
2380c486
JR
36984 }
36985 }
36986 } else if (S_ISDIR(mode)) {
36987- sys_mkdir(collected, mode);
36988- sys_chown(collected, uid, gid);
36989- sys_chmod(collected, mode);
36990+ sys_mkdir((char __user *)collected, mode);
36991+ sys_chown((char __user *)collected, uid, gid);
36992+ sys_chmod((char __user *)collected, mode);
36993 dir_add(collected, mtime);
36994 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
36995 S_ISFIFO(mode) || S_ISSOCK(mode)) {
36996 if (maybe_link() == 0) {
36997- sys_mknod(collected, mode, rdev);
36998- sys_chown(collected, uid, gid);
36999- sys_chmod(collected, mode);
37000+ sys_mknod((char __user *)collected, mode, rdev);
37001+ sys_chown((char __user *)collected, uid, gid);
37002+ sys_chmod((char __user *)collected, mode);
37003 do_utime(collected, mtime);
37004 }
37005 }
017d2877 37006@@ -336,7 +336,7 @@ static int __init do_name(void)
2380c486
JR
37007 static int __init do_copy(void)
37008 {
37009 if (count >= body_len) {
37010- sys_write(wfd, victim, body_len);
37011+ sys_write(wfd, (char __user *)victim, body_len);
37012 sys_close(wfd);
37013 do_utime(vcollected, mtime);
37014 kfree(vcollected);
017d2877 37015@@ -344,7 +344,7 @@ static int __init do_copy(void)
2380c486
JR
37016 state = SkipIt;
37017 return 0;
37018 } else {
37019- sys_write(wfd, victim, count);
37020+ sys_write(wfd, (char __user *)victim, count);
37021 body_len -= count;
37022 eat(count);
37023 return 1;
017d2877 37024@@ -355,8 +355,8 @@ static int __init do_symlink(void)
2380c486
JR
37025 {
37026 collected[N_ALIGN(name_len) + body_len] = '\0';
37027 clean_path(collected, 0);
37028- sys_symlink(collected + N_ALIGN(name_len), collected);
37029- sys_lchown(collected, uid, gid);
37030+ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
37031+ sys_lchown((char __user *)collected, uid, gid);
37032 do_utime(collected, mtime);
37033 state = SkipIt;
37034 next_state = Reset;
017d2877
AM
37035diff -urNp linux-2.6.30.4/init/Kconfig linux-2.6.30.4/init/Kconfig
37036--- linux-2.6.30.4/init/Kconfig 2009-07-24 17:47:51.000000000 -0400
37037+++ linux-2.6.30.4/init/Kconfig 2009-07-30 11:10:49.547309962 -0400
37038@@ -780,6 +780,7 @@ config SYSCTL_SYSCALL
2380c486
JR
37039 config KALLSYMS
37040 bool "Load all symbols for debugging/ksymoops" if EMBEDDED
37041 default y
37042+ depends on !GRKERNSEC_HIDESYM
37043 help
37044 Say Y here to let the kernel print out symbolic crash information and
37045 symbolic stack backtraces. This increases the size of the kernel
017d2877 37046@@ -963,7 +964,7 @@ config SLUB_DEBUG
de855c5d
AM
37047
37048 config COMPAT_BRK
37049 bool "Disable heap randomization"
37050- default y
37051+ default n
37052 help
37053 Randomizing heap placement makes heap exploits harder, but it
37054 also breaks ancient binaries (including anything libc5 based).
017d2877 37055@@ -1050,9 +1051,9 @@ config HAVE_GENERIC_DMA_COHERENT
2380c486
JR
37056
37057 config SLABINFO
37058 bool
37059- depends on PROC_FS
37060+ depends on PROC_FS && !GRKERNSEC_PROC_ADD
37061 depends on SLAB || SLUB_DEBUG
37062- default y
37063+ default n
37064
37065 config RT_MUTEXES
37066 boolean
017d2877
AM
37067diff -urNp linux-2.6.30.4/init/main.c linux-2.6.30.4/init/main.c
37068--- linux-2.6.30.4/init/main.c 2009-07-24 17:47:51.000000000 -0400
37069+++ linux-2.6.30.4/init/main.c 2009-07-30 11:10:49.548504780 -0400
37070@@ -98,6 +98,7 @@ static inline void mark_rodata_ro(void)
2380c486
JR
37071 #ifdef CONFIG_TC
37072 extern void tc_init(void);
37073 #endif
37074+extern void grsecurity_init(void);
37075
37076 enum system_states system_state __read_mostly;
37077 EXPORT_SYMBOL(system_state);
017d2877 37078@@ -184,6 +185,40 @@ static int __init set_reset_devices(char
2380c486
JR
37079
37080 __setup("reset_devices", set_reset_devices);
37081
37082+#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
37083+static int __init setup_pax_nouderef(char *str)
37084+{
37085+ unsigned int cpu;
37086+
37087+#ifdef CONFIG_PAX_KERNEXEC
37088+ unsigned long cr0;
37089+
37090+ pax_open_kernel(cr0);
37091+#endif
37092+
37093+ for (cpu = 0; cpu < NR_CPUS; cpu++)
37094+ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
37095+
37096+#ifdef CONFIG_PAX_KERNEXEC
37097+ pax_close_kernel(cr0);
37098+#endif
37099+
37100+ return 1;
37101+}
37102+__setup("pax_nouderef", setup_pax_nouderef);
37103+#endif
37104+
37105+#ifdef CONFIG_PAX_SOFTMODE
37106+unsigned int pax_softmode;
37107+
37108+static int __init setup_pax_softmode(char *str)
37109+{
37110+ get_option(&str, &pax_softmode);
37111+ return 1;
37112+}
37113+__setup("pax_softmode=", setup_pax_softmode);
37114+#endif
37115+
37116 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
37117 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
37118 static const char *panic_later, *panic_param;
017d2877 37119@@ -377,7 +412,7 @@ static void __init setup_nr_cpu_ids(void
2380c486
JR
37120 }
37121
37122 #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
37123-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
37124+unsigned long __per_cpu_offset[NR_CPUS] __read_only;
37125
37126 EXPORT_SYMBOL(__per_cpu_offset);
37127
017d2877 37128@@ -706,6 +741,7 @@ int do_one_initcall(initcall_t fn)
2380c486
JR
37129 {
37130 int count = preempt_count();
37131 ktime_t calltime, delta, rettime;
37132+ const char *msg1 = "", *msg2 = "";
37133 char msgbuf[64];
37134 struct boot_trace_call call;
37135 struct boot_trace_ret ret;
017d2877 37136@@ -736,15 +772,15 @@ int do_one_initcall(initcall_t fn)
2380c486
JR
37137 sprintf(msgbuf, "error code %d ", ret.result);
37138
37139 if (preempt_count() != count) {
37140- strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
37141+ msg1 = " preemption imbalance";
37142 preempt_count() = count;
37143 }
37144 if (irqs_disabled()) {
37145- strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
37146+ msg2 = " disabled interrupts";
37147 local_irq_enable();
37148 }
37149- if (msgbuf[0]) {
37150- printk("initcall %pF returned with %s\n", fn, msgbuf);
37151+ if (msgbuf[0] || *msg1 || *msg2) {
37152+ printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
37153 }
37154
37155 return ret.result;
017d2877 37156@@ -885,6 +921,8 @@ static int __init kernel_init(void * unu
2380c486
JR
37157 prepare_namespace();
37158 }
37159
37160+ grsecurity_init();
37161+
37162 /*
37163 * Ok, we have completed the initial bootup, and
37164 * we're essentially up and running. Get rid of the
017d2877
AM
37165diff -urNp linux-2.6.30.4/init/noinitramfs.c linux-2.6.30.4/init/noinitramfs.c
37166--- linux-2.6.30.4/init/noinitramfs.c 2009-07-24 17:47:51.000000000 -0400
37167+++ linux-2.6.30.4/init/noinitramfs.c 2009-07-30 09:48:10.122895747 -0400
2380c486
JR
37168@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
37169 {
37170 int err;
37171
37172- err = sys_mkdir("/dev", 0755);
37173+ err = sys_mkdir((const char __user *)"/dev", 0755);
37174 if (err < 0)
37175 goto out;
37176
37177@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
37178 if (err < 0)
37179 goto out;
37180
37181- err = sys_mkdir("/root", 0700);
37182+ err = sys_mkdir((const char __user *)"/root", 0700);
37183 if (err < 0)
37184 goto out;
37185
017d2877
AM
37186diff -urNp linux-2.6.30.4/ipc/ipc_sysctl.c linux-2.6.30.4/ipc/ipc_sysctl.c
37187--- linux-2.6.30.4/ipc/ipc_sysctl.c 2009-07-24 17:47:51.000000000 -0400
37188+++ linux-2.6.30.4/ipc/ipc_sysctl.c 2009-07-30 09:48:10.122895747 -0400
2380c486
JR
37189@@ -267,7 +267,7 @@ static struct ctl_table ipc_kern_table[]
37190 .extra1 = &zero,
37191 .extra2 = &one,
37192 },
37193- {}
37194+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37195 };
37196
37197 static struct ctl_table ipc_root_table[] = {
37198@@ -277,7 +277,7 @@ static struct ctl_table ipc_root_table[]
37199 .mode = 0555,
37200 .child = ipc_kern_table,
37201 },
37202- {}
37203+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37204 };
37205
37206 static int __init ipc_sysctl_init(void)
017d2877
AM
37207diff -urNp linux-2.6.30.4/ipc/mqueue.c linux-2.6.30.4/ipc/mqueue.c
37208--- linux-2.6.30.4/ipc/mqueue.c 2009-07-24 17:47:51.000000000 -0400
37209+++ linux-2.6.30.4/ipc/mqueue.c 2009-07-30 11:10:49.559299006 -0400
37210@@ -76,7 +76,7 @@ struct mqueue_inode_info {
37211
37212 static const struct inode_operations mqueue_dir_inode_operations;
37213 static const struct file_operations mqueue_file_operations;
37214-static struct super_operations mqueue_super_ops;
37215+static const struct super_operations mqueue_super_ops;
37216 static void remove_notification(struct mqueue_inode_info *info);
37217
37218 static struct kmem_cache *mqueue_inode_cachep;
37219@@ -149,6 +149,7 @@ static struct inode *mqueue_get_inode(st
2380c486
JR
37220 mq_bytes = (mq_msg_tblsz +
37221 (info->attr.mq_maxmsg * info->attr.mq_msgsize));
37222
37223+ gr_learn_resource(current, RLIMIT_MSGQUEUE, u->mq_bytes + mq_bytes, 1);
37224 spin_lock(&mq_lock);
37225 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
37226 u->mq_bytes + mq_bytes >
017d2877
AM
37227@@ -1222,7 +1223,7 @@ static const struct file_operations mque
37228 .read = mqueue_read_file,
37229 };
37230
37231-static struct super_operations mqueue_super_ops = {
37232+static const struct super_operations mqueue_super_ops = {
37233 .alloc_inode = mqueue_alloc_inode,
37234 .destroy_inode = mqueue_destroy_inode,
37235 .statfs = simple_statfs,
37236diff -urNp linux-2.6.30.4/ipc/msg.c linux-2.6.30.4/ipc/msg.c
37237--- linux-2.6.30.4/ipc/msg.c 2009-07-24 17:47:51.000000000 -0400
37238+++ linux-2.6.30.4/ipc/msg.c 2009-07-30 11:10:49.568315799 -0400
2380c486
JR
37239@@ -314,6 +314,7 @@ SYSCALL_DEFINE2(msgget, key_t, key, int,
37240 struct ipc_namespace *ns;
37241 struct ipc_ops msg_ops;
37242 struct ipc_params msg_params;
37243+ long err;
37244
37245 ns = current->nsproxy->ipc_ns;
37246
37247@@ -324,7 +325,11 @@ SYSCALL_DEFINE2(msgget, key_t, key, int,
37248 msg_params.key = key;
37249 msg_params.flg = msgflg;
37250
37251- return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
37252+ err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
37253+
37254+ gr_log_msgget(err, msgflg);
37255+
37256+ return err;
37257 }
37258
37259 static inline unsigned long
37260@@ -434,6 +439,7 @@ static int msgctl_down(struct ipc_namesp
37261
37262 switch (cmd) {
37263 case IPC_RMID:
37264+ gr_log_msgrm(ipcp->uid, ipcp->cuid);
37265 freeque(ns, ipcp);
37266 goto out_up;
37267 case IPC_SET:
017d2877
AM
37268diff -urNp linux-2.6.30.4/ipc/sem.c linux-2.6.30.4/ipc/sem.c
37269--- linux-2.6.30.4/ipc/sem.c 2009-07-24 17:47:51.000000000 -0400
37270+++ linux-2.6.30.4/ipc/sem.c 2009-07-30 11:10:49.579322291 -0400
2380c486
JR
37271@@ -313,6 +313,7 @@ SYSCALL_DEFINE3(semget, key_t, key, int,
37272 struct ipc_namespace *ns;
37273 struct ipc_ops sem_ops;
37274 struct ipc_params sem_params;
37275+ long err;
37276
37277 ns = current->nsproxy->ipc_ns;
37278
37279@@ -327,7 +328,11 @@ SYSCALL_DEFINE3(semget, key_t, key, int,
37280 sem_params.flg = semflg;
37281 sem_params.u.nsems = nsems;
37282
37283- return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
37284+ err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
37285+
37286+ gr_log_semget(err, semflg);
37287+
37288+ return err;
37289 }
37290
37291 /*
37292@@ -870,6 +875,7 @@ static int semctl_down(struct ipc_namesp
37293
37294 switch(cmd){
37295 case IPC_RMID:
37296+ gr_log_semrm(ipcp->uid, ipcp->cuid);
37297 freeary(ns, ipcp);
37298 goto out_up;
37299 case IPC_SET:
017d2877
AM
37300diff -urNp linux-2.6.30.4/ipc/shm.c linux-2.6.30.4/ipc/shm.c
37301--- linux-2.6.30.4/ipc/shm.c 2009-07-24 17:47:51.000000000 -0400
37302+++ linux-2.6.30.4/ipc/shm.c 2009-07-30 11:10:49.582310282 -0400
37303@@ -55,7 +55,7 @@ struct shm_file_data {
37304 #define shm_file_data(file) (*((struct shm_file_data **)&(file)->private_data))
37305
37306 static const struct file_operations shm_file_operations;
37307-static struct vm_operations_struct shm_vm_ops;
37308+static const struct vm_operations_struct shm_vm_ops;
37309
37310 #define shm_ids(ns) ((ns)->ids[IPC_SHM_IDS])
37311
37312@@ -70,6 +70,14 @@ static void shm_destroy (struct ipc_name
2380c486
JR
37313 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
37314 #endif
37315
37316+#ifdef CONFIG_GRKERNSEC
37317+extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
37318+ const time_t shm_createtime, const uid_t cuid,
37319+ const int shmid);
37320+extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
37321+ const time_t shm_createtime);
37322+#endif
37323+
37324 void shm_init_ns(struct ipc_namespace *ns)
37325 {
37326 ns->shm_ctlmax = SHMMAX;
017d2877 37327@@ -88,6 +96,8 @@ static void do_shm_rmid(struct ipc_names
2380c486
JR
37328 struct shmid_kernel *shp;
37329 shp = container_of(ipcp, struct shmid_kernel, shm_perm);
37330
37331+ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
37332+
37333 if (shp->shm_nattch){
37334 shp->shm_perm.mode |= SHM_DEST;
37335 /* Do not find it any more */
017d2877
AM
37336@@ -312,7 +322,7 @@ static const struct file_operations shm_
37337 .get_unmapped_area = shm_get_unmapped_area,
37338 };
37339
37340-static struct vm_operations_struct shm_vm_ops = {
37341+static const struct vm_operations_struct shm_vm_ops = {
37342 .open = shm_open, /* callback for a new vm-area open */
37343 .close = shm_close, /* callback for when the vm-area is released */
37344 .fault = shm_fault,
37345@@ -396,6 +406,14 @@ static int newseg(struct ipc_namespace *
2380c486
JR
37346 shp->shm_lprid = 0;
37347 shp->shm_atim = shp->shm_dtim = 0;
37348 shp->shm_ctim = get_seconds();
37349+#ifdef CONFIG_GRKERNSEC
37350+ {
37351+ struct timespec timeval;
37352+ do_posix_clock_monotonic_gettime(&timeval);
37353+
37354+ shp->shm_createtime = timeval.tv_sec;
37355+ }
37356+#endif
37357 shp->shm_segsz = size;
37358 shp->shm_nattch = 0;
37359 shp->shm_file = file;
017d2877 37360@@ -449,6 +467,7 @@ SYSCALL_DEFINE3(shmget, key_t, key, size
2380c486
JR
37361 struct ipc_namespace *ns;
37362 struct ipc_ops shm_ops;
37363 struct ipc_params shm_params;
37364+ long err;
37365
37366 ns = current->nsproxy->ipc_ns;
37367
017d2877 37368@@ -460,7 +479,11 @@ SYSCALL_DEFINE3(shmget, key_t, key, size
2380c486
JR
37369 shm_params.flg = shmflg;
37370 shm_params.u.size = size;
37371
37372- return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
37373+ err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
37374+
37375+ gr_log_shmget(err, shmflg, size);
37376+
37377+ return err;
37378 }
37379
37380 static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
017d2877 37381@@ -877,9 +900,21 @@ long do_shmat(int shmid, char __user *sh
2380c486
JR
37382 if (err)
37383 goto out_unlock;
37384
37385+#ifdef CONFIG_GRKERNSEC
37386+ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
37387+ shp->shm_perm.cuid, shmid) ||
37388+ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
37389+ err = -EACCES;
37390+ goto out_unlock;
37391+ }
37392+#endif
37393+
37394 path.dentry = dget(shp->shm_file->f_path.dentry);
37395 path.mnt = shp->shm_file->f_path.mnt;
37396 shp->shm_nattch++;
37397+#ifdef CONFIG_GRKERNSEC
37398+ shp->shm_lapid = current->pid;
37399+#endif
37400 size = i_size_read(path.dentry->d_inode);
37401 shm_unlock(shp);
37402
017d2877
AM
37403diff -urNp linux-2.6.30.4/ipc/util.c linux-2.6.30.4/ipc/util.c
37404--- linux-2.6.30.4/ipc/util.c 2009-07-24 17:47:51.000000000 -0400
37405+++ linux-2.6.30.4/ipc/util.c 2009-07-30 09:48:10.123853712 -0400
37406@@ -942,7 +942,7 @@ static int sysvipc_proc_show(struct seq_
37407 return iface->show(s, it);
37408 }
37409
37410-static struct seq_operations sysvipc_proc_seqops = {
37411+static const struct seq_operations sysvipc_proc_seqops = {
37412 .start = sysvipc_proc_start,
37413 .stop = sysvipc_proc_stop,
37414 .next = sysvipc_proc_next,
37415diff -urNp linux-2.6.30.4/kernel/acct.c linux-2.6.30.4/kernel/acct.c
37416--- linux-2.6.30.4/kernel/acct.c 2009-07-24 17:47:51.000000000 -0400
37417+++ linux-2.6.30.4/kernel/acct.c 2009-07-30 09:48:10.124859675 -0400
de855c5d 37418@@ -574,7 +574,7 @@ static void do_acct_process(struct bsd_a
2380c486
JR
37419 */
37420 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
37421 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
37422- file->f_op->write(file, (char *)&ac,
37423+ file->f_op->write(file, (char __user *)&ac,
37424 sizeof(acct_t), &file->f_pos);
37425 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
37426 set_fs(fs);
017d2877
AM
37427diff -urNp linux-2.6.30.4/kernel/capability.c linux-2.6.30.4/kernel/capability.c
37428--- linux-2.6.30.4/kernel/capability.c 2009-07-24 17:47:51.000000000 -0400
37429+++ linux-2.6.30.4/kernel/capability.c 2009-07-30 11:10:49.599076288 -0400
2380c486
JR
37430@@ -306,10 +306,21 @@ int capable(int cap)
37431 BUG();
37432 }
37433
37434- if (security_capable(cap) == 0) {
37435+ if (security_capable(cap) == 0 && gr_is_capable(cap)) {
37436 current->flags |= PF_SUPERPRIV;
37437 return 1;
37438 }
37439 return 0;
37440 }
37441+
37442+int capable_nolog(int cap)
37443+{
37444+ if (security_capable(cap) == 0 && gr_is_capable_nolog(cap)) {
37445+ current->flags |= PF_SUPERPRIV;
37446+ return 1;
37447+ }
37448+ return 0;
37449+}
37450+
37451 EXPORT_SYMBOL(capable);
37452+EXPORT_SYMBOL(capable_nolog);
017d2877
AM
37453diff -urNp linux-2.6.30.4/kernel/cgroup.c linux-2.6.30.4/kernel/cgroup.c
37454--- linux-2.6.30.4/kernel/cgroup.c 2009-07-24 17:47:51.000000000 -0400
37455+++ linux-2.6.30.4/kernel/cgroup.c 2009-07-30 09:48:10.125699437 -0400
37456@@ -594,8 +594,8 @@ void cgroup_unlock(void)
37457 static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
37458 static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
37459 static int cgroup_populate_dir(struct cgroup *cgrp);
37460-static struct inode_operations cgroup_dir_inode_operations;
37461-static struct file_operations proc_cgroupstats_operations;
37462+static const struct inode_operations cgroup_dir_inode_operations;
37463+static const struct file_operations proc_cgroupstats_operations;
37464
37465 static struct backing_dev_info cgroup_backing_dev_info = {
37466 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
37467@@ -930,7 +930,7 @@ static int cgroup_remount(struct super_b
37468 return ret;
37469 }
37470
37471-static struct super_operations cgroup_ops = {
37472+static const struct super_operations cgroup_ops = {
37473 .statfs = simple_statfs,
37474 .drop_inode = generic_delete_inode,
37475 .show_options = cgroup_show_options,
37476@@ -1612,7 +1612,7 @@ static int cgroup_seqfile_release(struct
37477 return single_release(inode, file);
37478 }
37479
37480-static struct file_operations cgroup_seqfile_operations = {
37481+static const struct file_operations cgroup_seqfile_operations = {
37482 .read = seq_read,
37483 .write = cgroup_file_write,
37484 .llseek = seq_lseek,
37485@@ -1671,7 +1671,7 @@ static int cgroup_rename(struct inode *o
37486 return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
37487 }
37488
37489-static struct file_operations cgroup_file_operations = {
37490+static const struct file_operations cgroup_file_operations = {
37491 .read = cgroup_file_read,
37492 .write = cgroup_file_write,
37493 .llseek = generic_file_llseek,
37494@@ -1679,7 +1679,7 @@ static struct file_operations cgroup_fil
37495 .release = cgroup_file_release,
37496 };
37497
37498-static struct inode_operations cgroup_dir_inode_operations = {
37499+static const struct inode_operations cgroup_dir_inode_operations = {
37500 .lookup = simple_lookup,
37501 .mkdir = cgroup_mkdir,
37502 .rmdir = cgroup_rmdir,
37503@@ -2262,7 +2262,7 @@ static int cgroup_tasks_show(struct seq_
37504 return seq_printf(s, "%d\n", *(int *)v);
37505 }
37506
37507-static struct seq_operations cgroup_tasks_seq_operations = {
37508+static const struct seq_operations cgroup_tasks_seq_operations = {
37509 .start = cgroup_tasks_start,
37510 .stop = cgroup_tasks_stop,
37511 .next = cgroup_tasks_next,
37512@@ -2292,7 +2292,7 @@ static int cgroup_tasks_release(struct i
37513 return seq_release(inode, file);
37514 }
37515
37516-static struct file_operations cgroup_tasks_operations = {
37517+static const struct file_operations cgroup_tasks_operations = {
37518 .read = seq_read,
37519 .llseek = seq_lseek,
37520 .write = cgroup_file_write,
37521@@ -2930,7 +2930,7 @@ static int cgroup_open(struct inode *ino
37522 return single_open(file, proc_cgroup_show, pid);
37523 }
37524
37525-struct file_operations proc_cgroup_operations = {
37526+const struct file_operations proc_cgroup_operations = {
37527 .open = cgroup_open,
37528 .read = seq_read,
37529 .llseek = seq_lseek,
37530@@ -2959,7 +2959,7 @@ static int cgroupstats_open(struct inode
37531 return single_open(file, proc_cgroupstats_show, NULL);
37532 }
37533
37534-static struct file_operations proc_cgroupstats_operations = {
37535+static const struct file_operations proc_cgroupstats_operations = {
37536 .open = cgroupstats_open,
37537 .read = seq_read,
37538 .llseek = seq_lseek,
37539diff -urNp linux-2.6.30.4/kernel/configs.c linux-2.6.30.4/kernel/configs.c
37540--- linux-2.6.30.4/kernel/configs.c 2009-07-24 17:47:51.000000000 -0400
37541+++ linux-2.6.30.4/kernel/configs.c 2009-07-30 11:10:49.609950770 -0400
2380c486
JR
37542@@ -73,8 +73,19 @@ static int __init ikconfig_init(void)
37543 struct proc_dir_entry *entry;
37544
37545 /* create the current config file */
37546+#ifdef CONFIG_GRKERNSEC_PROC_ADD
37547+#ifdef CONFIG_GRKERNSEC_PROC_USER
37548+ entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
37549+ &ikconfig_file_ops);
37550+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
37551+ entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
37552+ &ikconfig_file_ops);
37553+#endif
37554+#else
37555 entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
37556 &ikconfig_file_ops);
37557+#endif
37558+
37559 if (!entry)
37560 return -ENOMEM;
37561
017d2877
AM
37562diff -urNp linux-2.6.30.4/kernel/cpu.c linux-2.6.30.4/kernel/cpu.c
37563--- linux-2.6.30.4/kernel/cpu.c 2009-07-24 17:47:51.000000000 -0400
37564+++ linux-2.6.30.4/kernel/cpu.c 2009-07-30 09:48:10.125699437 -0400
2380c486
JR
37565@@ -19,7 +19,7 @@
37566 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
37567 static DEFINE_MUTEX(cpu_add_remove_lock);
37568
37569-static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
37570+static RAW_NOTIFIER_HEAD(cpu_chain);
37571
37572 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
37573 * Should always be manipulated under cpu_add_remove_lock
017d2877
AM
37574diff -urNp linux-2.6.30.4/kernel/cred.c linux-2.6.30.4/kernel/cred.c
37575--- linux-2.6.30.4/kernel/cred.c 2009-07-24 17:47:51.000000000 -0400
37576+++ linux-2.6.30.4/kernel/cred.c 2009-07-30 11:10:49.610408907 -0400
2380c486
JR
37577@@ -366,6 +366,8 @@ int commit_creds(struct cred *new)
37578
37579 get_cred(new); /* we will require a ref for the subj creds too */
37580
37581+ gr_set_role_label(task, new->uid, new->gid);
37582+
37583 /* dumpability changes */
37584 if (old->euid != new->euid ||
37585 old->egid != new->egid ||
017d2877
AM
37586diff -urNp linux-2.6.30.4/kernel/exit.c linux-2.6.30.4/kernel/exit.c
37587--- linux-2.6.30.4/kernel/exit.c 2009-07-24 17:47:51.000000000 -0400
37588+++ linux-2.6.30.4/kernel/exit.c 2009-07-30 11:10:49.617311944 -0400
37589@@ -60,6 +60,10 @@ DEFINE_TRACE(sched_process_free);
2380c486
JR
37590 DEFINE_TRACE(sched_process_exit);
37591 DEFINE_TRACE(sched_process_wait);
37592
37593+#ifdef CONFIG_GRKERNSEC
37594+extern rwlock_t grsec_exec_file_lock;
37595+#endif
37596+
37597 static void exit_mm(struct task_struct * tsk);
37598
017d2877
AM
37599 static void __unhash_process(struct task_struct *p)
37600@@ -168,6 +172,8 @@ void release_task(struct task_struct * p
2380c486
JR
37601 struct task_struct *leader;
37602 int zap_leader;
37603 repeat:
37604+ gr_del_task_from_ip_table(p);
37605+
37606 tracehook_prepare_release_task(p);
37607 /* don't need to get the RCU readlock here - the process is dead and
37608 * can't be modifying its own credentials */
017d2877 37609@@ -334,11 +340,22 @@ static void reparent_to_kthreadd(void)
2380c486
JR
37610 {
37611 write_lock_irq(&tasklist_lock);
37612
37613+#ifdef CONFIG_GRKERNSEC
37614+ write_lock(&grsec_exec_file_lock);
37615+ if (current->exec_file) {
37616+ fput(current->exec_file);
37617+ current->exec_file = NULL;
37618+ }
37619+ write_unlock(&grsec_exec_file_lock);
37620+#endif
37621+
37622 ptrace_unlink(current);
37623 /* Reparent to init */
37624 current->real_parent = current->parent = kthreadd_task;
37625 list_move_tail(&current->sibling, &current->real_parent->children);
37626
37627+ gr_set_kernel_label(current);
37628+
37629 /* Set the exit signal to SIGCHLD so we signal init on exit */
37630 current->exit_signal = SIGCHLD;
37631
017d2877 37632@@ -427,6 +444,17 @@ void daemonize(const char *name, ...)
2380c486
JR
37633 vsnprintf(current->comm, sizeof(current->comm), name, args);
37634 va_end(args);
37635
37636+#ifdef CONFIG_GRKERNSEC
37637+ write_lock(&grsec_exec_file_lock);
37638+ if (current->exec_file) {
37639+ fput(current->exec_file);
37640+ current->exec_file = NULL;
37641+ }
37642+ write_unlock(&grsec_exec_file_lock);
37643+#endif
37644+
37645+ gr_set_kernel_label(current);
37646+
37647 /*
37648 * If we were started as result of loading a module, close all of the
37649 * user space pages. We don't need them, and if we didn't close them
017d2877 37650@@ -954,6 +982,9 @@ NORET_TYPE void do_exit(long code)
2380c486
JR
37651 tsk->exit_code = code;
37652 taskstats_exit(tsk, group_dead);
37653
37654+ gr_acl_handle_psacct(tsk, code);
37655+ gr_acl_handle_exit();
37656+
37657 exit_mm(tsk);
37658
37659 if (group_dead)
017d2877 37660@@ -1158,7 +1189,7 @@ static int wait_task_zombie(struct task_
2380c486
JR
37661
37662 if (unlikely(options & WNOWAIT)) {
37663 int exit_code = p->exit_code;
37664- int why, status;
37665+ int why;
37666
37667 get_task_struct(p);
37668 read_unlock(&tasklist_lock);
017d2877
AM
37669diff -urNp linux-2.6.30.4/kernel/fork.c linux-2.6.30.4/kernel/fork.c
37670--- linux-2.6.30.4/kernel/fork.c 2009-07-24 17:47:51.000000000 -0400
37671+++ linux-2.6.30.4/kernel/fork.c 2009-07-30 11:10:49.618406568 -0400
37672@@ -245,7 +245,7 @@ static struct task_struct *dup_task_stru
37673 *stackend = STACK_END_MAGIC; /* for overflow detection */
2380c486
JR
37674
37675 #ifdef CONFIG_CC_STACKPROTECTOR
37676- tsk->stack_canary = get_random_int();
37677+ tsk->stack_canary = pax_get_random_long();
37678 #endif
37679
37680 /* One for us, one for whoever does the "release_task()" (usually parent) */
017d2877 37681@@ -282,8 +282,8 @@ static int dup_mmap(struct mm_struct *mm
2380c486
JR
37682 mm->locked_vm = 0;
37683 mm->mmap = NULL;
37684 mm->mmap_cache = NULL;
37685- mm->free_area_cache = oldmm->mmap_base;
37686- mm->cached_hole_size = ~0UL;
37687+ mm->free_area_cache = oldmm->free_area_cache;
37688+ mm->cached_hole_size = oldmm->cached_hole_size;
37689 mm->map_count = 0;
017d2877 37690 cpumask_clear(mm_cpumask(mm));
2380c486 37691 mm->mm_rb = RB_ROOT;
017d2877 37692@@ -320,6 +320,7 @@ static int dup_mmap(struct mm_struct *mm
2380c486
JR
37693 tmp->vm_flags &= ~VM_LOCKED;
37694 tmp->vm_mm = mm;
37695 tmp->vm_next = NULL;
37696+ tmp->vm_mirror = NULL;
37697 anon_vma_link(tmp);
37698 file = tmp->vm_file;
37699 if (file) {
017d2877 37700@@ -367,6 +368,31 @@ static int dup_mmap(struct mm_struct *mm
2380c486
JR
37701 if (retval)
37702 goto out;
37703 }
37704+
37705+#ifdef CONFIG_PAX_SEGMEXEC
37706+ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
37707+ struct vm_area_struct *mpnt_m;
37708+
37709+ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
37710+ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
37711+
37712+ if (!mpnt->vm_mirror)
37713+ continue;
37714+
37715+ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
37716+ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
37717+ mpnt->vm_mirror = mpnt_m;
37718+ } else {
37719+ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
37720+ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
37721+ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
37722+ mpnt->vm_mirror->vm_mirror = mpnt;
37723+ }
37724+ }
37725+ BUG_ON(mpnt_m);
37726+ }
37727+#endif
37728+
37729 /* a new mm has just been created */
37730 arch_dup_mmap(oldmm, mm);
37731 retval = 0;
017d2877 37732@@ -547,9 +573,11 @@ void mm_release(struct task_struct *tsk,
2380c486
JR
37733 #ifdef CONFIG_FUTEX
37734 if (unlikely(tsk->robust_list))
37735 exit_robust_list(tsk);
37736+ tsk->robust_list = NULL;
37737 #ifdef CONFIG_COMPAT
37738 if (unlikely(tsk->compat_robust_list))
37739 compat_exit_robust_list(tsk);
37740+ tsk->compat_robust_list = NULL;
37741 #endif
37742 #endif
37743
017d2877 37744@@ -571,7 +599,7 @@ void mm_release(struct task_struct *tsk,
2380c486
JR
37745 if (tsk->clear_child_tid
37746 && !(tsk->flags & PF_SIGNALED)
37747 && atomic_read(&mm->mm_users) > 1) {
37748- u32 __user * tidptr = tsk->clear_child_tid;
37749+ pid_t __user * tidptr = tsk->clear_child_tid;
37750 tsk->clear_child_tid = NULL;
37751
37752 /*
017d2877 37753@@ -579,7 +607,7 @@ void mm_release(struct task_struct *tsk,
2380c486
JR
37754 * not set up a proper pointer then tough luck.
37755 */
37756 put_user(0, tidptr);
37757- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
37758+ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
37759 }
37760 }
37761
017d2877 37762@@ -695,7 +723,7 @@ static int copy_fs(unsigned long clone_f
de855c5d
AM
37763 write_unlock(&fs->lock);
37764 return -EAGAIN;
37765 }
37766- fs->users++;
37767+ atomic_inc(&fs->users);
37768 write_unlock(&fs->lock);
37769 return 0;
37770 }
017d2877 37771@@ -1048,6 +1048,9 @@
2380c486 37772 retval = -EAGAIN;
017d2877
AM
37773 if (!vx_nproc_avail(1))
37774 goto bad_fork_cleanup_vm;
de855c5d 37775+
2380c486 37776+ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->real_cred->user->processes), 0);
de855c5d 37777+
2380c486
JR
37778 if (atomic_read(&p->real_cred->user->processes) >=
37779 p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
37780 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
017d2877 37781@@ -1144,6 +1175,8 @@ static struct task_struct *copy_process(
2380c486
JR
37782 goto bad_fork_free_graph;
37783 }
37784
37785+ gr_copy_label(p);
37786+
37787 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
37788 /*
37789 * Clear TID on mm_release()?
017d2877 37790@@ -1310,6 +1343,8 @@ bad_fork_cleanup_count:
2380c486
JR
37791 bad_fork_free:
37792 free_task(p);
37793 fork_out:
37794+ gr_log_forkfail(retval);
37795+
37796 return ERR_PTR(retval);
37797 }
37798
017d2877 37799@@ -1403,6 +1438,8 @@ long do_fork(unsigned long clone_flags,
2380c486
JR
37800 if (clone_flags & CLONE_PARENT_SETTID)
37801 put_user(nr, parent_tidptr);
37802
37803+ gr_handle_brute_check();
37804+
37805 if (clone_flags & CLONE_VFORK) {
37806 p->vfork_done = &vfork;
37807 init_completion(&vfork);
017d2877 37808@@ -1535,7 +1572,7 @@ static int unshare_fs(unsigned long unsh
de855c5d
AM
37809 return 0;
37810
37811 /* don't need lock here; in the worst case we'll do useless copy */
37812- if (fs->users == 1)
37813+ if (atomic_read(&fs->users) == 1)
37814 return 0;
37815
37816 *new_fsp = copy_fs_struct(fs);
017d2877 37817@@ -1658,7 +1695,7 @@ SYSCALL_DEFINE1(unshare, unsigned long,
de855c5d
AM
37818 fs = current->fs;
37819 write_lock(&fs->lock);
37820 current->fs = new_fs;
37821- if (--fs->users)
37822+ if (atomic_dec_return(&fs->users))
37823 new_fs = NULL;
37824 else
37825 new_fs = fs;
017d2877
AM
37826diff -urNp linux-2.6.30.4/kernel/futex.c linux-2.6.30.4/kernel/futex.c
37827--- linux-2.6.30.4/kernel/futex.c 2009-07-24 17:47:51.000000000 -0400
37828+++ linux-2.6.30.4/kernel/futex.c 2009-07-30 09:48:10.127681569 -0400
37829@@ -212,6 +212,11 @@ get_futex_key(u32 __user *uaddr, int fsh
2380c486
JR
37830 struct page *page;
37831 int err;
37832
37833+#ifdef CONFIG_PAX_SEGMEXEC
37834+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
37835+ return -EFAULT;
37836+#endif
37837+
37838 /*
37839 * The futex address must be "naturally" aligned.
37840 */
017d2877 37841@@ -1285,7 +1290,7 @@ retry_private:
2380c486
JR
37842
37843 restart = &current_thread_info()->restart_block;
37844 restart->fn = futex_wait_restart;
37845- restart->futex.uaddr = (u32 *)uaddr;
37846+ restart->futex.uaddr = uaddr;
37847 restart->futex.val = val;
37848 restart->futex.time = abs_time->tv64;
37849 restart->futex.bitset = bitset;
017d2877 37850@@ -1809,7 +1814,7 @@ retry:
2380c486
JR
37851 */
37852 static inline int fetch_robust_entry(struct robust_list __user **entry,
37853 struct robust_list __user * __user *head,
37854- int *pi)
37855+ unsigned int *pi)
37856 {
37857 unsigned long uentry;
37858
017d2877
AM
37859diff -urNp linux-2.6.30.4/kernel/kallsyms.c linux-2.6.30.4/kernel/kallsyms.c
37860--- linux-2.6.30.4/kernel/kallsyms.c 2009-07-24 17:47:51.000000000 -0400
37861+++ linux-2.6.30.4/kernel/kallsyms.c 2009-07-30 11:10:49.619428708 -0400
2380c486
JR
37862@@ -62,6 +62,18 @@ static inline int is_kernel_text(unsigne
37863
37864 static inline int is_kernel(unsigned long addr)
37865 {
37866+
37867+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
37868+ if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
37869+ ktla_ktva(addr) < (unsigned long)MODULES_END)
37870+ return 0;
37871+#endif
37872+
37873+#ifdef CONFIG_X86_32
37874+ if (is_kernel_inittext(addr))
37875+ return 1;
37876+#endif
37877+
37878 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
37879 return 1;
37880 return in_gate_area_no_task(addr);
017d2877 37881@@ -391,7 +403,6 @@ static unsigned long get_ksymbol_core(st
2380c486
JR
37882
37883 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
37884 {
37885- iter->name[0] = '\0';
37886 iter->nameoff = get_symbol_offset(new_pos);
37887 iter->pos = new_pos;
37888 }
017d2877 37889@@ -475,7 +486,7 @@ static int kallsyms_open(struct inode *i
2380c486
JR
37890 struct kallsym_iter *iter;
37891 int ret;
37892
37893- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
37894+ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
37895 if (!iter)
37896 return -ENOMEM;
37897 reset_iter(iter, 0);
017d2877 37898@@ -497,7 +508,15 @@ static const struct file_operations kall
2380c486
JR
37899
37900 static int __init kallsyms_init(void)
37901 {
37902+#ifdef CONFIG_GRKERNSEC_PROC_ADD
37903+#ifdef CONFIG_GRKERNSEC_PROC_USER
37904+ proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
37905+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
37906+ proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
37907+#endif
37908+#else
37909 proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
37910+#endif
37911 return 0;
37912 }
37913 __initcall(kallsyms_init);
017d2877
AM
37914diff -urNp linux-2.6.30.4/kernel/kprobes.c linux-2.6.30.4/kernel/kprobes.c
37915--- linux-2.6.30.4/kernel/kprobes.c 2009-07-24 17:47:51.000000000 -0400
37916+++ linux-2.6.30.4/kernel/kprobes.c 2009-07-30 09:48:10.128762672 -0400
37917@@ -184,7 +184,7 @@ static kprobe_opcode_t __kprobes *__get_
2380c486
JR
37918 * kernel image and loaded module images reside. This is required
37919 * so x86_64 can correctly handle the %rip-relative fixups.
37920 */
37921- kip->insns = module_alloc(PAGE_SIZE);
37922+ kip->insns = module_alloc_exec(PAGE_SIZE);
37923 if (!kip->insns) {
37924 kfree(kip);
37925 return NULL;
017d2877 37926@@ -225,7 +225,7 @@ static int __kprobes collect_one_slot(st
2380c486
JR
37927 hlist_add_head(&kip->hlist,
37928 &kprobe_insn_pages);
37929 } else {
37930- module_free(NULL, kip->insns);
37931+ module_free_exec(NULL, kip->insns);
37932 kfree(kip);
37933 }
37934 return 1;
017d2877
AM
37935@@ -1333,7 +1333,7 @@ static int __kprobes show_kprobe_addr(st
37936 return 0;
37937 }
37938
37939-static struct seq_operations kprobes_seq_ops = {
37940+static const struct seq_operations kprobes_seq_ops = {
37941 .start = kprobe_seq_start,
37942 .next = kprobe_seq_next,
37943 .stop = kprobe_seq_stop,
37944@@ -1345,7 +1345,7 @@ static int __kprobes kprobes_open(struct
37945 return seq_open(filp, &kprobes_seq_ops);
37946 }
37947
37948-static struct file_operations debugfs_kprobes_operations = {
37949+static const struct file_operations debugfs_kprobes_operations = {
37950 .open = kprobes_open,
37951 .read = seq_read,
37952 .llseek = seq_lseek,
37953@@ -1527,7 +1527,7 @@ static ssize_t write_enabled_file_bool(s
37954 return count;
37955 }
37956
37957-static struct file_operations fops_kp = {
37958+static const struct file_operations fops_kp = {
37959 .read = read_enabled_file_bool,
37960 .write = write_enabled_file_bool,
37961 };
37962diff -urNp linux-2.6.30.4/kernel/lockdep.c linux-2.6.30.4/kernel/lockdep.c
37963--- linux-2.6.30.4/kernel/lockdep.c 2009-07-24 17:47:51.000000000 -0400
37964+++ linux-2.6.30.4/kernel/lockdep.c 2009-07-30 09:48:10.130698443 -0400
37965@@ -628,6 +628,10 @@ static int static_obj(void *obj)
2380c486
JR
37966 int i;
37967 #endif
37968
37969+#ifdef CONFIG_PAX_KERNEXEC
37970+ start = (unsigned long )&_data;
37971+#endif
37972+
37973 /*
37974 * static variable?
37975 */
017d2877 37976@@ -639,9 +643,12 @@ static int static_obj(void *obj)
2380c486
JR
37977 * percpu var?
37978 */
37979 for_each_possible_cpu(i) {
37980+#ifdef CONFIG_X86_32
37981+ start = per_cpu_offset(i);
37982+#else
37983 start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
37984- end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
37985- + per_cpu_offset(i);
37986+#endif
37987+ end = start + PERCPU_ENOUGH_ROOM;
37988
37989 if ((addr >= start) && (addr < end))
37990 return 1;
017d2877
AM
37991diff -urNp linux-2.6.30.4/kernel/lockdep_proc.c linux-2.6.30.4/kernel/lockdep_proc.c
37992--- linux-2.6.30.4/kernel/lockdep_proc.c 2009-07-24 17:47:51.000000000 -0400
37993+++ linux-2.6.30.4/kernel/lockdep_proc.c 2009-07-30 09:48:10.130698443 -0400
37994@@ -670,7 +670,7 @@ static int ls_show(struct seq_file *m, v
37995 return 0;
37996 }
37997
37998-static struct seq_operations lockstat_ops = {
37999+static const struct seq_operations lockstat_ops = {
38000 .start = ls_start,
38001 .next = ls_next,
38002 .stop = ls_stop,
38003diff -urNp linux-2.6.30.4/kernel/module.c linux-2.6.30.4/kernel/module.c
38004--- linux-2.6.30.4/kernel/module.c 2009-07-24 17:47:51.000000000 -0400
38005+++ linux-2.6.30.4/kernel/module.c 2009-07-30 11:10:49.634551667 -0400
2380c486
JR
38006@@ -46,6 +46,11 @@
38007 #include <linux/rculist.h>
38008 #include <asm/uaccess.h>
38009 #include <asm/cacheflush.h>
38010+
38011+#ifdef CONFIG_PAX_KERNEXEC
38012+#include <asm/desc.h>
38013+#endif
38014+
38015 #include <linux/license.h>
38016 #include <asm/sections.h>
38017 #include <linux/tracepoint.h>
017d2877 38018@@ -78,7 +83,10 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
2380c486
JR
38019 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
38020
017d2877 38021 /* Bounds of module allocation, for speeding __module_address */
2380c486
JR
38022-static unsigned long module_addr_min = -1UL, module_addr_max = 0;
38023+static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
38024+static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
38025+
38026+extern int gr_check_modstop(void);
38027
38028 int register_module_notifier(struct notifier_block * nb)
38029 {
017d2877 38030@@ -234,7 +242,7 @@ bool each_symbol(bool (*fn)(const struct
2380c486
JR
38031 return true;
38032
38033 list_for_each_entry_rcu(mod, &modules, list) {
38034- struct symsearch arr[] = {
38035+ struct symsearch modarr[] = {
38036 { mod->syms, mod->syms + mod->num_syms, mod->crcs,
38037 NOT_GPL_ONLY, false },
38038 { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
017d2877 38039@@ -256,7 +264,7 @@ bool each_symbol(bool (*fn)(const struct
2380c486
JR
38040 #endif
38041 };
38042
38043- if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
38044+ if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
38045 return true;
38046 }
38047 return false;
017d2877
AM
38048@@ -361,6 +369,8 @@ EXPORT_SYMBOL_GPL(find_module);
38049
38050 #ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA
38051
38052+EXPORT_SYMBOL(__per_cpu_load);
38053+
38054 static void *percpu_modalloc(unsigned long size, unsigned long align,
38055 const char *name)
38056 {
38057@@ -423,6 +433,8 @@ static inline unsigned int block_size(in
2380c486
JR
38058 return val;
38059 }
38060
017d2877 38061+EXPORT_SYMBOL(__per_cpu_load);
2380c486
JR
38062+
38063 static void *percpu_modalloc(unsigned long size, unsigned long align,
38064 const char *name)
38065 {
017d2877 38066@@ -430,7 +442,7 @@ static void *percpu_modalloc(unsigned lo
2380c486
JR
38067 unsigned int i;
38068 void *ptr;
38069
38070- if (align > PAGE_SIZE) {
38071+ if (align-1 >= PAGE_SIZE) {
38072 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
38073 name, align, PAGE_SIZE);
38074 align = PAGE_SIZE;
017d2877 38075@@ -533,7 +545,11 @@ static void percpu_modcopy(void *pcpudes
2380c486
JR
38076 int cpu;
38077
38078 for_each_possible_cpu(cpu)
38079+#ifdef CONFIG_X86_32
38080+ memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
38081+#else
38082 memcpy(pcpudest + per_cpu_offset(cpu), from, size);
38083+#endif
38084 }
38085
017d2877
AM
38086 #else /* ... !CONFIG_SMP */
38087@@ -777,6 +793,9 @@ SYSCALL_DEFINE2(delete_module, const cha
2380c486
JR
38088 char name[MODULE_NAME_LEN];
38089 int ret, forced = 0;
38090
38091+ if (gr_check_modstop())
38092+ return -EPERM;
38093+
38094 if (!capable(CAP_SYS_MODULE))
38095 return -EPERM;
38096
017d2877
AM
38097@@ -1490,10 +1509,11 @@ static void free_module(struct module *m
38098 destroy_params(mod->kp, mod->num_kp);
2380c486
JR
38099
38100 /* release any pointers to mcount in this module */
38101- ftrace_release(mod->module_core, mod->core_size);
38102+ ftrace_release(mod->module_core_rx, mod->core_size_rx);
38103
38104 /* This may be NULL, but that's OK */
38105- module_free(mod, mod->module_init);
38106+ module_free(mod, mod->module_init_rw);
38107+ module_free_exec(mod, mod->module_init_rx);
38108 kfree(mod->args);
38109 if (mod->percpu)
38110 percpu_modfree(mod->percpu);
017d2877 38111@@ -1502,10 +1522,12 @@ static void free_module(struct module *m
2380c486
JR
38112 percpu_modfree(mod->refptr);
38113 #endif
38114 /* Free lock-classes: */
38115- lockdep_free_key_range(mod->module_core, mod->core_size);
38116+ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
38117+ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
38118
38119 /* Finally, free the core (containing the module structure) */
38120- module_free(mod, mod->module_core);
38121+ module_free_exec(mod, mod->module_core_rx);
38122+ module_free(mod, mod->module_core_rw);
38123 }
38124
38125 void *__symbol_get(const char *symbol)
017d2877 38126@@ -1573,6 +1595,10 @@ static int simplify_symbols(Elf_Shdr *se
2380c486 38127 int ret = 0;
017d2877 38128 const struct kernel_symbol *ksym;
2380c486
JR
38129
38130+#ifdef CONFIG_PAX_KERNEXEC
38131+ unsigned long cr0;
38132+#endif
38133+
38134 for (i = 1; i < n; i++) {
38135 switch (sym[i].st_shndx) {
38136 case SHN_COMMON:
017d2877
AM
38137@@ -1595,7 +1621,17 @@ static int simplify_symbols(Elf_Shdr *se
38138 strtab + sym[i].st_name, mod);
38139 /* Ok if resolved. */
38140 if (ksym) {
38141+
2380c486 38142+#ifdef CONFIG_PAX_KERNEXEC
017d2877 38143+ pax_open_kernel(cr0);
2380c486
JR
38144+#endif
38145+
017d2877 38146 sym[i].st_value = ksym->value;
2380c486
JR
38147+
38148+#ifdef CONFIG_PAX_KERNEXEC
017d2877 38149+ pax_close_kernel(cr0);
2380c486
JR
38150+#endif
38151+
2380c486 38152 break;
017d2877
AM
38153 }
38154
38155@@ -1610,11 +1646,27 @@ static int simplify_symbols(Elf_Shdr *se
2380c486
JR
38156
38157 default:
38158 /* Divert to percpu allocation if a percpu var. */
38159- if (sym[i].st_shndx == pcpuindex)
38160+ if (sym[i].st_shndx == pcpuindex) {
38161+
38162+#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
017d2877 38163+ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_load;
2380c486
JR
38164+#else
38165 secbase = (unsigned long)mod->percpu;
38166- else
38167+#endif
38168+
38169+ } else
38170 secbase = sechdrs[sym[i].st_shndx].sh_addr;
38171+
38172+#ifdef CONFIG_PAX_KERNEXEC
38173+ pax_open_kernel(cr0);
38174+#endif
38175+
38176 sym[i].st_value += secbase;
38177+
38178+#ifdef CONFIG_PAX_KERNEXEC
38179+ pax_close_kernel(cr0);
38180+#endif
38181+
38182 break;
38183 }
38184 }
017d2877
AM
38185@@ -1675,11 +1727,12 @@ static void layout_sections(struct modul
38186 || s->sh_entsize != ~0UL
38187 || strstarts(secstrings + s->sh_name, ".init"))
2380c486
JR
38188 continue;
38189- s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
38190+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
38191+ s->sh_entsize = get_offset(mod, &mod->core_size_rw, s, i);
38192+ else
38193+ s->sh_entsize = get_offset(mod, &mod->core_size_rx, s, i);
38194 DEBUGP("\t%s\n", secstrings + s->sh_name);
38195 }
38196- if (m == 0)
38197- mod->core_text_size = mod->core_size;
38198 }
38199
38200 DEBUGP("Init section allocation order:\n");
017d2877
AM
38201@@ -1692,12 +1745,13 @@ static void layout_sections(struct modul
38202 || s->sh_entsize != ~0UL
38203 || !strstarts(secstrings + s->sh_name, ".init"))
2380c486
JR
38204 continue;
38205- s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
38206- | INIT_OFFSET_MASK);
38207+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
38208+ s->sh_entsize = get_offset(mod, &mod->init_size_rw, s, i);
38209+ else
38210+ s->sh_entsize = get_offset(mod, &mod->init_size_rx, s, i);
38211+ s->sh_entsize |= INIT_OFFSET_MASK;
38212 DEBUGP("\t%s\n", secstrings + s->sh_name);
38213 }
38214- if (m == 0)
38215- mod->init_text_size = mod->init_size;
38216 }
38217 }
38218
017d2877 38219@@ -1836,14 +1890,31 @@ static void add_kallsyms(struct module *
2380c486
JR
38220 {
38221 unsigned int i;
38222
38223+#ifdef CONFIG_PAX_KERNEXEC
38224+ unsigned long cr0;
38225+#endif
38226+
38227 mod->symtab = (void *)sechdrs[symindex].sh_addr;
38228 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
38229 mod->strtab = (void *)sechdrs[strindex].sh_addr;
38230
38231 /* Set types up while we still have access to sections. */
38232- for (i = 0; i < mod->num_symtab; i++)
38233- mod->symtab[i].st_info
38234- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
38235+
38236+ for (i = 0; i < mod->num_symtab; i++) {
38237+ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
38238+
38239+#ifdef CONFIG_PAX_KERNEXEC
38240+ pax_open_kernel(cr0);
38241+#endif
38242+
38243+ mod->symtab[i].st_info = type;
38244+
38245+#ifdef CONFIG_PAX_KERNEXEC
38246+ pax_close_kernel(cr0);
38247+#endif
38248+
38249+ }
38250+
38251 }
38252 #else
38253 static inline void add_kallsyms(struct module *mod,
017d2877
AM
38254@@ -1864,16 +1935,30 @@ static void dynamic_debug_setup(struct _
38255 #endif
2380c486
JR
38256 }
38257
38258-static void *module_alloc_update_bounds(unsigned long size)
38259+static void *module_alloc_update_bounds_rw(unsigned long size)
38260 {
38261 void *ret = module_alloc(size);
38262
38263 if (ret) {
38264 /* Update module bounds. */
38265- if ((unsigned long)ret < module_addr_min)
38266- module_addr_min = (unsigned long)ret;
38267- if ((unsigned long)ret + size > module_addr_max)
38268- module_addr_max = (unsigned long)ret + size;
38269+ if ((unsigned long)ret < module_addr_min_rw)
38270+ module_addr_min_rw = (unsigned long)ret;
38271+ if ((unsigned long)ret + size > module_addr_max_rw)
38272+ module_addr_max_rw = (unsigned long)ret + size;
38273+ }
38274+ return ret;
38275+}
38276+
38277+static void *module_alloc_update_bounds_rx(unsigned long size)
38278+{
38279+ void *ret = module_alloc_exec(size);
38280+
38281+ if (ret) {
38282+ /* Update module bounds. */
38283+ if ((unsigned long)ret < module_addr_min_rx)
38284+ module_addr_min_rx = (unsigned long)ret;
38285+ if ((unsigned long)ret + size > module_addr_max_rx)
38286+ module_addr_max_rx = (unsigned long)ret + size;
38287 }
38288 return ret;
38289 }
017d2877 38290@@ -1899,6 +1984,10 @@ static noinline struct module *load_modu
2380c486
JR
38291 unsigned long *mseg;
38292 mm_segment_t old_fs;
38293
38294+#ifdef CONFIG_PAX_KERNEXEC
38295+ unsigned long cr0;
38296+#endif
38297+
38298 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
38299 umod, len, uargs);
38300 if (len < sizeof(*hdr))
017d2877 38301@@ -2049,22 +2138,57 @@ static noinline struct module *load_modu
2380c486
JR
38302 layout_sections(mod, hdr, sechdrs, secstrings);
38303
38304 /* Do the allocs. */
38305- ptr = module_alloc_update_bounds(mod->core_size);
38306+ ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
38307 if (!ptr) {
38308 err = -ENOMEM;
38309 goto free_percpu;
38310 }
38311- memset(ptr, 0, mod->core_size);
38312- mod->module_core = ptr;
38313+ memset(ptr, 0, mod->core_size_rw);
38314+ mod->module_core_rw = ptr;
38315+
38316+ ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
38317+ if (!ptr && mod->init_size_rw) {
38318+ err = -ENOMEM;
38319+ goto free_core_rw;
38320+ }
38321+ memset(ptr, 0, mod->init_size_rw);
38322+ mod->module_init_rw = ptr;
38323+
38324+ ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
38325+ if (!ptr) {
38326+ err = -ENOMEM;
38327+ goto free_init_rw;
38328+ }
017d2877
AM
38329
38330- ptr = module_alloc_update_bounds(mod->init_size);
38331- if (!ptr && mod->init_size) {
2380c486
JR
38332+#ifdef CONFIG_PAX_KERNEXEC
38333+ pax_open_kernel(cr0);
38334+#endif
38335+
38336+ memset(ptr, 0, mod->core_size_rx);
017d2877 38337+
2380c486
JR
38338+#ifdef CONFIG_PAX_KERNEXEC
38339+ pax_close_kernel(cr0);
38340+#endif
38341+
38342+ mod->module_core_rx = ptr;
38343+
38344+ ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
38345+ if (!ptr && mod->init_size_rx) {
38346 err = -ENOMEM;
38347- goto free_core;
38348+ goto free_core_rx;
38349 }
38350- memset(ptr, 0, mod->init_size);
38351- mod->module_init = ptr;
38352
38353+#ifdef CONFIG_PAX_KERNEXEC
38354+ pax_open_kernel(cr0);
38355+#endif
38356+
38357+ memset(ptr, 0, mod->init_size_rx);
38358+
38359+#ifdef CONFIG_PAX_KERNEXEC
38360+ pax_close_kernel(cr0);
38361+#endif
38362+
38363+ mod->module_init_rx = ptr;
38364 /* Transfer each section which specifies SHF_ALLOC */
38365 DEBUGP("final section addresses:\n");
38366 for (i = 0; i < hdr->e_shnum; i++) {
017d2877 38367@@ -2073,17 +2197,41 @@ static noinline struct module *load_modu
2380c486
JR
38368 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
38369 continue;
38370
38371- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
38372- dest = mod->module_init
38373- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
38374- else
38375- dest = mod->module_core + sechdrs[i].sh_entsize;
38376+ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
38377+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
38378+ dest = mod->module_init_rw
38379+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
38380+ else
38381+ dest = mod->module_init_rx
38382+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
38383+ } else {
38384+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
38385+ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
38386+ else
38387+ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
38388+ }
017d2877 38389+
2380c486
JR
38390+ if (sechdrs[i].sh_type != SHT_NOBITS) {
38391+
38392+#ifdef CONFIG_PAX_KERNEXEC
38393+ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
38394+ pax_open_kernel(cr0);
38395+ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
38396+ pax_close_kernel(cr0);
38397+ } else
38398+#endif
017d2877
AM
38399
38400- if (sechdrs[i].sh_type != SHT_NOBITS)
38401- memcpy(dest, (void *)sechdrs[i].sh_addr,
38402- sechdrs[i].sh_size);
2380c486
JR
38403+ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
38404+ }
38405 /* Update sh_addr to point to copy in image. */
38406- sechdrs[i].sh_addr = (unsigned long)dest;
38407+
38408+#ifdef CONFIG_PAX_KERNEXEC
38409+ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
38410+ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
38411+ else
38412+#endif
38413+
38414+ sechdrs[i].sh_addr = (unsigned long)dest;
38415 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
38416 }
38417 /* Module has been moved. */
017d2877 38418@@ -2094,7 +2242,7 @@ static noinline struct module *load_modu
2380c486
JR
38419 mod->name);
38420 if (!mod->refptr) {
38421 err = -ENOMEM;
38422- goto free_init;
38423+ goto free_init_rx;
38424 }
38425 #endif
38426 /* Now we've moved module, initialize linked lists, etc. */
017d2877 38427@@ -2191,8 +2339,8 @@ static noinline struct module *load_modu
2380c486
JR
38428
38429 /* Now do relocations. */
38430 for (i = 1; i < hdr->e_shnum; i++) {
38431- const char *strtab = (char *)sechdrs[strindex].sh_addr;
38432 unsigned int info = sechdrs[i].sh_info;
38433+ strtab = (char *)sechdrs[strindex].sh_addr;
38434
38435 /* Not a valid relocation section? */
38436 if (info >= hdr->e_shnum)
017d2877 38437@@ -2255,12 +2403,12 @@ static noinline struct module *load_modu
2380c486
JR
38438 * Do it before processing of module parameters, so the module
38439 * can provide parameter accessor functions of its own.
38440 */
38441- if (mod->module_init)
38442- flush_icache_range((unsigned long)mod->module_init,
38443- (unsigned long)mod->module_init
38444- + mod->init_size);
38445- flush_icache_range((unsigned long)mod->module_core,
38446- (unsigned long)mod->module_core + mod->core_size);
38447+ if (mod->module_init_rx)
38448+ flush_icache_range((unsigned long)mod->module_init_rx,
38449+ (unsigned long)mod->module_init_rx
38450+ + mod->init_size_rx);
38451+ flush_icache_range((unsigned long)mod->module_core_rx,
38452+ (unsigned long)mod->module_core_rx + mod->core_size_rx);
38453
38454 set_fs(old_fs);
38455
017d2877 38456@@ -2302,16 +2450,20 @@ static noinline struct module *load_modu
2380c486
JR
38457 cleanup:
38458 kobject_del(&mod->mkobj.kobj);
38459 kobject_put(&mod->mkobj.kobj);
38460- ftrace_release(mod->module_core, mod->core_size);
38461+ ftrace_release(mod->module_core_rx, mod->core_size_rx);
38462 free_unload:
38463 module_unload_free(mod);
017d2877 38464 #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
2380c486
JR
38465- free_init:
38466+ free_init_rx:
2380c486
JR
38467 percpu_modfree(mod->refptr);
38468 #endif
38469- module_free(mod, mod->module_init);
38470- free_core:
38471- module_free(mod, mod->module_core);
38472+ module_free_exec(mod, mod->module_init_rx);
38473+ free_core_rx:
38474+ module_free_exec(mod, mod->module_core_rx);
38475+ free_init_rw:
38476+ module_free(mod, mod->module_init_rw);
38477+ free_core_rw:
38478+ module_free(mod, mod->module_core_rw);
38479 /* mod will be freed with core. Don't access it beyond this line! */
38480 free_percpu:
38481 if (percpu)
017d2877 38482@@ -2335,6 +2487,9 @@ SYSCALL_DEFINE3(init_module, void __user
2380c486
JR
38483 struct module *mod;
38484 int ret = 0;
38485
38486+ if (gr_check_modstop())
38487+ return -EPERM;
38488+
38489 /* Must have permission */
38490 if (!capable(CAP_SYS_MODULE))
38491 return -EPERM;
017d2877 38492@@ -2394,20 +2549,17 @@ SYSCALL_DEFINE3(init_module, void __user
2380c486
JR
38493 mutex_lock(&module_mutex);
38494 /* Drop initial reference. */
38495 module_put(mod);
38496- module_free(mod, mod->module_init);
38497- mod->module_init = NULL;
38498- mod->init_size = 0;
38499- mod->init_text_size = 0;
38500+ module_free(mod, mod->module_init_rw);
38501+ module_free_exec(mod, mod->module_init_rx);
38502+ mod->module_init_rw = NULL;
38503+ mod->module_init_rx = NULL;
38504+ mod->init_size_rw = 0;
38505+ mod->init_size_rx = 0;
38506 mutex_unlock(&module_mutex);
38507
38508 return 0;
38509 }
38510
38511-static inline int within(unsigned long addr, void *start, unsigned long size)
38512-{
38513- return ((void *)addr >= start && (void *)addr < start + size);
38514-}
38515-
38516 #ifdef CONFIG_KALLSYMS
38517 /*
38518 * This ignores the intensely annoying "mapping symbols" found
017d2877 38519@@ -2428,10 +2580,16 @@ static const char *get_ksymbol(struct mo
2380c486
JR
38520 unsigned long nextval;
38521
38522 /* At worse, next value is at end of module */
38523- if (within_module_init(addr, mod))
38524- nextval = (unsigned long)mod->module_init+mod->init_text_size;
38525+ if (within_module_init_rx(addr, mod))
38526+ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
38527+ else if (within_module_init_rw(addr, mod))
38528+ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
38529+ else if (within_module_core_rx(addr, mod))
38530+ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
38531+ else if (within_module_core_rw(addr, mod))
38532+ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
38533 else
38534- nextval = (unsigned long)mod->module_core+mod->core_text_size;
38535+ return NULL;
38536
38537 /* Scan for closest preceeding symbol, and next symbol. (ELF
38538 starts real symbols at 1). */
017d2877 38539@@ -2677,7 +2835,7 @@ static int m_show(struct seq_file *m, vo
2380c486
JR
38540 char buf[8];
38541
38542 seq_printf(m, "%s %u",
38543- mod->name, mod->init_size + mod->core_size);
38544+ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
38545 print_unload_info(m, mod);
38546
38547 /* Informative for users. */
017d2877 38548@@ -2686,7 +2844,7 @@ static int m_show(struct seq_file *m, vo
2380c486
JR
38549 mod->state == MODULE_STATE_COMING ? "Loading":
38550 "Live");
38551 /* Used by oprofile and other similar tools. */
38552- seq_printf(m, " 0x%p", mod->module_core);
38553+ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
38554
38555 /* Taints info */
38556 if (mod->taints)
017d2877 38557@@ -2781,12 +2939,12 @@ struct module *__module_address(unsigned
2380c486
JR
38558 {
38559 struct module *mod;
38560
38561- if (addr < module_addr_min || addr > module_addr_max)
017d2877
AM
38562+ if ((addr < module_addr_min_rx || addr > module_addr_max_rx) &&
38563+ (addr < module_addr_min_rw || addr > module_addr_max_rw))
2380c486
JR
38564 return NULL;
38565
38566 list_for_each_entry_rcu(mod, &modules, list)
017d2877
AM
38567- if (within_module_core(addr, mod)
38568- || within_module_init(addr, mod))
38569+ if (within_module_init(addr, mod) || within_module_core(addr, mod))
2380c486
JR
38570 return mod;
38571 return NULL;
38572 }
017d2877
AM
38573@@ -2820,11 +2978,20 @@ bool is_module_text_address(unsigned lon
38574 */
38575 struct module *__module_text_address(unsigned long addr)
38576 {
38577- struct module *mod = __module_address(addr);
38578+ struct module *mod;
38579+
38580+#ifdef CONFIG_X86_32
38581+ addr = ktla_ktva(addr);
38582+#endif
38583+
38584+ if (addr < module_addr_min_rx || addr > module_addr_max_rx)
38585+ return NULL;
38586+
38587+ mod = __module_address(addr);
38588+
38589 if (mod) {
38590 /* Make sure it's within the text section. */
38591- if (!within(addr, mod->module_init, mod->init_text_size)
38592- && !within(addr, mod->module_core, mod->core_text_size))
38593+ if (!within_module_init_rx(addr, mod) && !within_module_core_rx(addr, mod))
38594 mod = NULL;
38595 }
38596 return mod;
38597diff -urNp linux-2.6.30.4/kernel/mutex.c linux-2.6.30.4/kernel/mutex.c
38598--- linux-2.6.30.4/kernel/mutex.c 2009-07-24 17:47:51.000000000 -0400
38599+++ linux-2.6.30.4/kernel/mutex.c 2009-07-30 09:48:10.131672113 -0400
38600@@ -89,7 +89,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
2380c486
JR
38601 *
38602 * This function is similar to (but not equivalent to) down().
38603 */
38604-void inline __sched mutex_lock(struct mutex *lock)
38605+inline void __sched mutex_lock(struct mutex *lock)
38606 {
38607 might_sleep();
38608 /*
017d2877
AM
38609diff -urNp linux-2.6.30.4/kernel/panic.c linux-2.6.30.4/kernel/panic.c
38610--- linux-2.6.30.4/kernel/panic.c 2009-07-24 17:47:51.000000000 -0400
38611+++ linux-2.6.30.4/kernel/panic.c 2009-07-30 09:48:10.131672113 -0400
38612@@ -390,7 +390,8 @@ EXPORT_SYMBOL(warn_slowpath_null);
2380c486
JR
38613 */
38614 void __stack_chk_fail(void)
38615 {
017d2877 38616- panic("stack-protector: Kernel stack is corrupted in: %p\n",
2380c486 38617+ dump_stack();
017d2877
AM
38618+ panic("stack-protector: Kernel stack is corrupted in: %pS\n",
38619 __builtin_return_address(0));
2380c486
JR
38620 }
38621 EXPORT_SYMBOL(__stack_chk_fail);
017d2877
AM
38622diff -urNp linux-2.6.30.4/kernel/pid.c linux-2.6.30.4/kernel/pid.c
38623--- linux-2.6.30.4/kernel/pid.c 2009-07-24 17:47:51.000000000 -0400
38624+++ linux-2.6.30.4/kernel/pid.c 2009-07-30 11:10:49.635626798 -0400
2380c486
JR
38625@@ -33,6 +33,7 @@
38626 #include <linux/rculist.h>
38627 #include <linux/bootmem.h>
38628 #include <linux/hash.h>
38629+#include <linux/security.h>
38630 #include <linux/pid_namespace.h>
38631 #include <linux/init_task.h>
38632 #include <linux/syscalls.h>
38633@@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
38634
38635 int pid_max = PID_MAX_DEFAULT;
38636
38637-#define RESERVED_PIDS 300
38638+#define RESERVED_PIDS 500
38639
38640 int pid_max_min = RESERVED_PIDS + 1;
38641 int pid_max_max = PID_MAX_LIMIT;
38642@@ -381,7 +382,14 @@ EXPORT_SYMBOL(pid_task);
38643 struct task_struct *find_task_by_pid_type_ns(int type, int nr,
38644 struct pid_namespace *ns)
38645 {
38646- return pid_task(find_pid_ns(nr, ns), type);
38647+ struct task_struct *task;
38648+
38649+ task = pid_task(find_pid_ns(nr, ns), type);
38650+
38651+ if (gr_pid_is_chrooted(task))
38652+ return NULL;
38653+
38654+ return task;
38655 }
38656
38657 EXPORT_SYMBOL(find_task_by_pid_type_ns);
017d2877
AM
38658diff -urNp linux-2.6.30.4/kernel/posix-cpu-timers.c linux-2.6.30.4/kernel/posix-cpu-timers.c
38659--- linux-2.6.30.4/kernel/posix-cpu-timers.c 2009-07-24 17:47:51.000000000 -0400
38660+++ linux-2.6.30.4/kernel/posix-cpu-timers.c 2009-07-30 11:10:49.652340336 -0400
2380c486
JR
38661@@ -6,6 +6,7 @@
38662 #include <linux/posix-timers.h>
38663 #include <linux/errno.h>
38664 #include <linux/math64.h>
38665+#include <linux/security.h>
38666 #include <asm/uaccess.h>
38667 #include <linux/kernel_stat.h>
38668
de855c5d 38669@@ -1040,6 +1041,7 @@ static void check_thread_timers(struct t
2380c486
JR
38670 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
38671 return;
38672 }
38673+ gr_learn_resource(tsk, RLIMIT_RTTIME, tsk->rt.timeout, 1);
38674 if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) {
38675 /*
38676 * At the soft limit, send a SIGXCPU every second.
de855c5d 38677@@ -1195,6 +1197,7 @@ static void check_process_timers(struct
2380c486
JR
38678 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
38679 return;
38680 }
38681+ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 0);
38682 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
38683 /*
38684 * At the soft limit, send a SIGXCPU every second.
017d2877
AM
38685diff -urNp linux-2.6.30.4/kernel/power/poweroff.c linux-2.6.30.4/kernel/power/poweroff.c
38686--- linux-2.6.30.4/kernel/power/poweroff.c 2009-07-24 17:47:51.000000000 -0400
38687+++ linux-2.6.30.4/kernel/power/poweroff.c 2009-07-30 09:48:10.132674489 -0400
2380c486
JR
38688@@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof
38689 .enable_mask = SYSRQ_ENABLE_BOOT,
38690 };
38691
38692-static int pm_sysrq_init(void)
38693+static int __init pm_sysrq_init(void)
38694 {
38695 register_sysrq_key('o', &sysrq_poweroff_op);
38696 return 0;
017d2877
AM
38697diff -urNp linux-2.6.30.4/kernel/printk.c linux-2.6.30.4/kernel/printk.c
38698--- linux-2.6.30.4/kernel/printk.c 2009-07-24 17:47:51.000000000 -0400
38699+++ linux-2.6.30.4/kernel/printk.c 2009-07-30 11:10:49.653305213 -0400
38700@@ -272,6 +272,11 @@ int do_syslog(int type, char __user *buf
2380c486
JR
38701 char c;
38702 int error = 0;
38703
38704+#ifdef CONFIG_GRKERNSEC_DMESG
38705+ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
38706+ return -EPERM;
38707+#endif
38708+
38709 error = security_syslog(type);
38710 if (error)
38711 return error;
017d2877
AM
38712diff -urNp linux-2.6.30.4/kernel/ptrace.c linux-2.6.30.4/kernel/ptrace.c
38713--- linux-2.6.30.4/kernel/ptrace.c 2009-07-24 17:47:51.000000000 -0400
38714+++ linux-2.6.30.4/kernel/ptrace.c 2009-07-30 11:10:49.654304318 -0400
38715@@ -151,7 +151,7 @@ int __ptrace_may_access(struct task_stru
2380c486
JR
38716 cred->gid != tcred->egid ||
38717 cred->gid != tcred->sgid ||
38718 cred->gid != tcred->gid) &&
38719- !capable(CAP_SYS_PTRACE)) {
38720+ !capable_nolog(CAP_SYS_PTRACE)) {
38721 rcu_read_unlock();
38722 return -EPERM;
38723 }
017d2877 38724@@ -159,7 +159,7 @@ int __ptrace_may_access(struct task_stru
2380c486
JR
38725 smp_rmb();
38726 if (task->mm)
38727 dumpable = get_dumpable(task->mm);
38728- if (!dumpable && !capable(CAP_SYS_PTRACE))
38729+ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
38730 return -EPERM;
38731
38732 return security_ptrace_may_access(task, mode);
017d2877 38733@@ -223,7 +223,7 @@ repeat:
2380c486
JR
38734
38735 /* Go */
38736 task->ptrace |= PT_PTRACED;
38737- if (capable(CAP_SYS_PTRACE))
38738+ if (capable_nolog(CAP_SYS_PTRACE))
38739 task->ptrace |= PT_PTRACE_CAP;
38740
38741 __ptrace_link(task, current);
017d2877 38742@@ -687,6 +687,11 @@ SYSCALL_DEFINE4(ptrace, long, request, l
2380c486
JR
38743 if (ret < 0)
38744 goto out_put_task_struct;
38745
38746+ if (gr_handle_ptrace(child, request)) {
38747+ ret = -EPERM;
38748+ goto out_put_task_struct;
38749+ }
38750+
38751 ret = arch_ptrace(child, request, addr, data);
017d2877
AM
38752
38753 out_put_task_struct:
38754diff -urNp linux-2.6.30.4/kernel/rcupreempt_trace.c linux-2.6.30.4/kernel/rcupreempt_trace.c
38755--- linux-2.6.30.4/kernel/rcupreempt_trace.c 2009-07-24 17:47:51.000000000 -0400
38756+++ linux-2.6.30.4/kernel/rcupreempt_trace.c 2009-07-30 09:48:10.132674489 -0400
38757@@ -261,17 +261,17 @@ static ssize_t rcuctrs_read(struct file
38758 return bcount;
38759 }
38760
38761-static struct file_operations rcustats_fops = {
38762+static const struct file_operations rcustats_fops = {
38763 .owner = THIS_MODULE,
38764 .read = rcustats_read,
38765 };
38766
38767-static struct file_operations rcugp_fops = {
38768+static const struct file_operations rcugp_fops = {
38769 .owner = THIS_MODULE,
38770 .read = rcugp_read,
38771 };
38772
38773-static struct file_operations rcuctrs_fops = {
38774+static const struct file_operations rcuctrs_fops = {
38775 .owner = THIS_MODULE,
38776 .read = rcuctrs_read,
38777 };
38778diff -urNp linux-2.6.30.4/kernel/rcutree_trace.c linux-2.6.30.4/kernel/rcutree_trace.c
38779--- linux-2.6.30.4/kernel/rcutree_trace.c 2009-07-24 17:47:51.000000000 -0400
38780+++ linux-2.6.30.4/kernel/rcutree_trace.c 2009-07-30 09:48:10.132674489 -0400
38781@@ -88,7 +88,7 @@ static int rcudata_open(struct inode *in
38782 return single_open(file, show_rcudata, NULL);
38783 }
38784
38785-static struct file_operations rcudata_fops = {
38786+static const struct file_operations rcudata_fops = {
38787 .owner = THIS_MODULE,
38788 .open = rcudata_open,
38789 .read = seq_read,
38790@@ -136,7 +136,7 @@ static int rcudata_csv_open(struct inode
38791 return single_open(file, show_rcudata_csv, NULL);
38792 }
38793
38794-static struct file_operations rcudata_csv_fops = {
38795+static const struct file_operations rcudata_csv_fops = {
38796 .owner = THIS_MODULE,
38797 .open = rcudata_csv_open,
38798 .read = seq_read,
38799@@ -183,7 +183,7 @@ static int rcuhier_open(struct inode *in
38800 return single_open(file, show_rcuhier, NULL);
38801 }
38802
38803-static struct file_operations rcuhier_fops = {
38804+static const struct file_operations rcuhier_fops = {
38805 .owner = THIS_MODULE,
38806 .open = rcuhier_open,
38807 .read = seq_read,
38808@@ -205,7 +205,7 @@ static int rcugp_open(struct inode *inod
38809 return single_open(file, show_rcugp, NULL);
38810 }
38811
38812-static struct file_operations rcugp_fops = {
38813+static const struct file_operations rcugp_fops = {
38814 .owner = THIS_MODULE,
38815 .open = rcugp_open,
38816 .read = seq_read,
38817diff -urNp linux-2.6.30.4/kernel/relay.c linux-2.6.30.4/kernel/relay.c
38818--- linux-2.6.30.4/kernel/relay.c 2009-07-24 17:47:51.000000000 -0400
38819+++ linux-2.6.30.4/kernel/relay.c 2009-07-30 09:48:10.133766067 -0400
38820@@ -60,7 +60,7 @@ static int relay_buf_fault(struct vm_are
38821 /*
38822 * vm_ops for relay file mappings.
38823 */
38824-static struct vm_operations_struct relay_file_mmap_ops = {
38825+static const struct vm_operations_struct relay_file_mmap_ops = {
38826 .fault = relay_buf_fault,
38827 .close = relay_file_mmap_close,
38828 };
2380c486
JR
38829@@ -1292,7 +1292,7 @@ static int subbuf_splice_actor(struct fi
38830 return 0;
38831
38832 ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
38833- if (ret < 0 || ret < total_len)
38834+ if ((int)ret < 0 || ret < total_len)
38835 return ret;
38836
38837 if (read_start + ret == nonpad_end)
017d2877
AM
38838diff -urNp linux-2.6.30.4/kernel/resource.c linux-2.6.30.4/kernel/resource.c
38839--- linux-2.6.30.4/kernel/resource.c 2009-07-24 17:47:51.000000000 -0400
38840+++ linux-2.6.30.4/kernel/resource.c 2009-07-30 11:10:49.657454572 -0400
2380c486
JR
38841@@ -132,8 +132,18 @@ static const struct file_operations proc
38842
38843 static int __init ioresources_init(void)
38844 {
38845+#ifdef CONFIG_GRKERNSEC_PROC_ADD
38846+#ifdef CONFIG_GRKERNSEC_PROC_USER
38847+ proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
38848+ proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
38849+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
38850+ proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
38851+ proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
38852+#endif
38853+#else
38854 proc_create("ioports", 0, NULL, &proc_ioports_operations);
38855 proc_create("iomem", 0, NULL, &proc_iomem_operations);
38856+#endif
38857 return 0;
38858 }
38859 __initcall(ioresources_init);
017d2877
AM
38860diff -urNp linux-2.6.30.4/kernel/sched.c linux-2.6.30.4/kernel/sched.c
38861--- linux-2.6.30.4/kernel/sched.c 2009-07-30 20:32:40.551917543 -0400
38862+++ linux-2.6.30.4/kernel/sched.c 2009-07-30 20:32:48.093586870 -0400
38863@@ -819,7 +819,7 @@ static int sched_feat_open(struct inode
38864 return single_open(filp, sched_feat_show, NULL);
38865 }
38866
38867-static struct file_operations sched_feat_fops = {
38868+static const struct file_operations sched_feat_fops = {
38869 .open = sched_feat_open,
38870 .write = sched_feat_write,
38871 .read = seq_read,
38872@@ -5663,6 +5663,8 @@ int can_nice(const struct task_struct *p
2380c486
JR
38873 /* convert nice value [19,-20] to rlimit style value [1,40] */
38874 int nice_rlim = 20 - nice;
38875
38876+ gr_learn_resource(p, RLIMIT_NICE, nice_rlim, 1);
38877+
38878 return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur ||
38879 capable(CAP_SYS_NICE));
38880 }
017d2877 38881@@ -5738,7 +5738,7 @@
2380c486
JR
38882 if (nice > 19)
38883 nice = 19;
38884
38885- if (increment < 0 && !can_nice(current, nice))
017d2877
AM
38886+ if (increment < 0 && (!can_nice(current, nice) || gr_handle_chroot_nice()))
38887 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
2380c486
JR
38888
38889 retval = security_task_setnice(current, nice);
017d2877 38890@@ -5838,6 +5841,8 @@ recheck:
2380c486
JR
38891 if (rt_policy(policy)) {
38892 unsigned long rlim_rtprio;
38893
38894+ gr_learn_resource(p, RLIMIT_RTPRIO, param->sched_priority, 1);
38895+
38896 if (!lock_task_sighand(p, &flags))
38897 return -ESRCH;
38898 rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur;
017d2877 38899@@ -6980,7 +6985,7 @@ static struct ctl_table sd_ctl_dir[] = {
2380c486
JR
38900 .procname = "sched_domain",
38901 .mode = 0555,
38902 },
38903- {0, },
38904+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
38905 };
38906
38907 static struct ctl_table sd_ctl_root[] = {
017d2877 38908@@ -6990,7 +6995,7 @@ static struct ctl_table sd_ctl_root[] =
2380c486
JR
38909 .mode = 0555,
38910 .child = sd_ctl_dir,
38911 },
38912- {0, },
38913+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
38914 };
38915
38916 static struct ctl_table *sd_alloc_ctl_entry(int n)
017d2877
AM
38917diff -urNp linux-2.6.30.4/kernel/signal.c linux-2.6.30.4/kernel/signal.c
38918--- linux-2.6.30.4/kernel/signal.c 2009-07-24 17:47:51.000000000 -0400
38919+++ linux-2.6.30.4/kernel/signal.c 2009-07-30 11:10:49.687338803 -0400
38920@@ -209,6 +209,9 @@ static struct sigqueue *__sigqueue_alloc
2380c486
JR
38921 */
38922 user = get_uid(__task_cred(t)->user);
38923 atomic_inc(&user->sigpending);
38924+
38925+ if (!override_rlimit)
38926+ gr_learn_resource(t, RLIMIT_SIGPENDING, atomic_read(&user->sigpending), 1);
38927 if (override_rlimit ||
38928 atomic_read(&user->sigpending) <=
38929 t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
017d2877
AM
38930@@ -649,6 +649,10 @@
38931 return error;
2380c486 38932 }
017d2877
AM
38933 skip:
38934+
2380c486
JR
38935+ if (gr_handle_signal(t, sig))
38936+ return -EPERM;
38937+
38938 return security_task_kill(t, info, sig, 0);
38939 }
38940
017d2877 38941@@ -931,8 +937,8 @@ static void print_fatal_signal(struct pt
2380c486
JR
38942 for (i = 0; i < 16; i++) {
38943 unsigned char insn;
38944
38945- __get_user(insn, (unsigned char *)(regs->ip + i));
38946- printk("%02x ", insn);
38947+ if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
38948+ printk("%02x ", insn);
38949 }
38950 }
38951 #endif
017d2877 38952@@ -957,7 +963,7 @@ __group_send_sig_info(int sig, struct si
2380c486
JR
38953 return send_signal(sig, info, p, 1);
38954 }
38955
38956-static int
38957+int
38958 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
38959 {
38960 return send_signal(sig, info, t, 0);
017d2877 38961@@ -997,6 +1003,9 @@ force_sig_info(int sig, struct siginfo *
2380c486
JR
38962 ret = specific_send_sig_info(sig, info, t);
38963 spin_unlock_irqrestore(&t->sighand->siglock, flags);
38964
38965+ gr_log_signal(sig, t);
38966+ gr_handle_crash(t, sig);
38967+
38968 return ret;
38969 }
38970
017d2877 38971@@ -1071,6 +1080,8 @@ int group_send_sig_info(int sig, struct
2380c486
JR
38972 ret = __group_send_sig_info(sig, info, p);
38973 unlock_task_sighand(p, &flags);
38974 }
38975+ if (!ret)
38976+ gr_log_signal(sig, p);
38977 }
38978
38979 return ret;
017d2877
AM
38980diff -urNp linux-2.6.30.4/kernel/sys.c linux-2.6.30.4/kernel/sys.c
38981--- linux-2.6.30.4/kernel/sys.c 2009-07-24 17:47:51.000000000 -0400
38982+++ linux-2.6.30.4/kernel/sys.c 2009-07-30 11:10:49.695716903 -0400
38983@@ -132,6 +132,12 @@ static int set_one_prio(struct task_stru
2380c486
JR
38984 error = -EACCES;
38985 goto out;
38986 }
38987+
38988+ if (gr_handle_chroot_setpriority(p, niceval)) {
38989+ error = -EACCES;
38990+ goto out;
38991+ }
38992+
38993 no_nice = security_task_setnice(p, niceval);
38994 if (no_nice) {
38995 error = no_nice;
017d2877 38996@@ -508,6 +514,9 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, g
2380c486
JR
38997 goto error;
38998 }
38999
39000+ if (gr_check_group_change(new->gid, new->egid, -1))
39001+ goto error;
39002+
39003 if (rgid != (gid_t) -1 ||
39004 (egid != (gid_t) -1 && egid != old->gid))
39005 new->sgid = new->egid;
017d2877 39006@@ -541,6 +550,10 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
2380c486
JR
39007 goto error;
39008
39009 retval = -EPERM;
39010+
39011+ if (gr_check_group_change(gid, gid, gid))
39012+ goto error;
39013+
39014 if (capable(CAP_SETGID))
39015 new->gid = new->egid = new->sgid = new->fsgid = gid;
39016 else if (gid == old->gid || gid == old->sgid)
017d2877 39017@@ -631,6 +644,9 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, u
2380c486
JR
39018 goto error;
39019 }
39020
39021+ if (gr_check_user_change(new->uid, new->euid, -1))
39022+ goto error;
39023+
39024 if (new->uid != old->uid) {
39025 retval = set_user(new);
39026 if (retval < 0)
017d2877 39027@@ -679,6 +695,12 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
2380c486
JR
39028 goto error;
39029
39030 retval = -EPERM;
39031+
39032+ if (gr_check_crash_uid(uid))
39033+ goto error;
39034+ if (gr_check_user_change(uid, uid, uid))
39035+ goto error;
39036+
39037 if (capable(CAP_SETUID)) {
39038 new->suid = new->uid = uid;
39039 if (uid != old->uid) {
017d2877 39040@@ -736,6 +758,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid,
2380c486
JR
39041 goto error;
39042 }
39043
39044+ if (gr_check_user_change(ruid, euid, -1))
39045+ goto error;
39046+
39047 if (ruid != (uid_t) -1) {
39048 new->uid = ruid;
39049 if (ruid != old->uid) {
017d2877 39050@@ -804,6 +829,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid,
2380c486
JR
39051 goto error;
39052 }
39053
39054+ if (gr_check_group_change(rgid, egid, -1))
39055+ goto error;
39056+
39057 if (rgid != (gid_t) -1)
39058 new->gid = rgid;
39059 if (egid != (gid_t) -1)
017d2877 39060@@ -853,6 +881,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
2380c486
JR
39061 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS) < 0)
39062 goto error;
39063
39064+ if (gr_check_user_change(-1, -1, uid))
39065+ goto error;
39066+
39067 if (uid == old->uid || uid == old->euid ||
39068 uid == old->suid || uid == old->fsuid ||
39069 capable(CAP_SETUID)) {
017d2877 39070@@ -893,6 +924,9 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
2380c486
JR
39071 if (gid == old->gid || gid == old->egid ||
39072 gid == old->sgid || gid == old->fsgid ||
39073 capable(CAP_SETGID)) {
39074+ if (gr_check_group_change(-1, -1, gid))
39075+ goto error;
39076+
39077 if (gid != old_fsgid) {
39078 new->fsgid = gid;
39079 goto change_okay;
017d2877 39080@@ -1725,7 +1759,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
2380c486
JR
39081 error = get_dumpable(me->mm);
39082 break;
39083 case PR_SET_DUMPABLE:
39084- if (arg2 < 0 || arg2 > 1) {
39085+ if (arg2 > 1) {
39086 error = -EINVAL;
39087 break;
39088 }
017d2877
AM
39089diff -urNp linux-2.6.30.4/kernel/sysctl.c linux-2.6.30.4/kernel/sysctl.c
39090--- linux-2.6.30.4/kernel/sysctl.c 2009-07-24 17:47:51.000000000 -0400
39091+++ linux-2.6.30.4/kernel/sysctl.c 2009-07-30 11:10:49.710420812 -0400
39092@@ -62,6 +62,13 @@
2380c486
JR
39093 static int deprecated_sysctl_warning(struct __sysctl_args *args);
39094
39095 #if defined(CONFIG_SYSCTL)
39096+#include <linux/grsecurity.h>
39097+#include <linux/grinternal.h>
39098+
39099+extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
39100+extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
39101+ const int op);
39102+extern int gr_handle_chroot_sysctl(const int op);
39103
39104 /* External variables not in a header file. */
39105 extern int C_A_D;
017d2877 39106@@ -159,6 +166,7 @@ static int proc_do_cad_pid(struct ctl_ta
2380c486
JR
39107 static int proc_taint(struct ctl_table *table, int write, struct file *filp,
39108 void __user *buffer, size_t *lenp, loff_t *ppos);
39109 #endif
39110+extern ctl_table grsecurity_table[];
39111
39112 static struct ctl_table root_table[];
39113 static struct ctl_table_root sysctl_table_root;
017d2877 39114@@ -191,6 +199,21 @@ extern struct ctl_table epoll_table[];
2380c486
JR
39115 int sysctl_legacy_va_layout;
39116 #endif
39117
39118+#ifdef CONFIG_PAX_SOFTMODE
39119+static ctl_table pax_table[] = {
39120+ {
39121+ .ctl_name = CTL_UNNUMBERED,
39122+ .procname = "softmode",
39123+ .data = &pax_softmode,
39124+ .maxlen = sizeof(unsigned int),
39125+ .mode = 0600,
39126+ .proc_handler = &proc_dointvec,
39127+ },
39128+
39129+ { .ctl_name = 0 }
39130+};
39131+#endif
39132+
39133 extern int prove_locking;
39134 extern int lock_stat;
39135
017d2877 39136@@ -1280,6 +1303,25 @@ static struct ctl_table vm_table[] = {
2380c486
JR
39137 .proc_handler = &scan_unevictable_handler,
39138 },
39139 #endif
39140+
39141+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
39142+ {
39143+ .ctl_name = CTL_UNNUMBERED,
39144+ .procname = "grsecurity",
39145+ .mode = 0500,
39146+ .child = grsecurity_table,
39147+ },
39148+#endif
39149+
39150+#ifdef CONFIG_PAX_SOFTMODE
39151+ {
39152+ .ctl_name = CTL_UNNUMBERED,
39153+ .procname = "pax",
39154+ .mode = 0500,
39155+ .child = pax_table,
39156+ },
39157+#endif
39158+
39159 /*
39160 * NOTE: do not add new entries to this table unless you have read
39161 * Documentation/sysctl/ctl_unnumbered.txt
017d2877 39162@@ -1657,6 +1699,8 @@ static int do_sysctl_strategy(struct ctl
2380c486
JR
39163 return 0;
39164 }
39165
39166+static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
39167+
39168 static int parse_table(int __user *name, int nlen,
39169 void __user *oldval, size_t __user *oldlenp,
39170 void __user *newval, size_t newlen,
017d2877 39171@@ -1675,7 +1719,7 @@ repeat:
2380c486
JR
39172 if (n == table->ctl_name) {
39173 int error;
39174 if (table->child) {
39175- if (sysctl_perm(root, table, MAY_EXEC))
39176+ if (sysctl_perm_nochk(root, table, MAY_EXEC))
39177 return -EPERM;
39178 name++;
39179 nlen--;
017d2877 39180@@ -1760,6 +1804,33 @@ int sysctl_perm(struct ctl_table_root *r
2380c486
JR
39181 int error;
39182 int mode;
39183
39184+ if (table->parent != NULL && table->parent->procname != NULL &&
39185+ table->procname != NULL &&
39186+ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
39187+ return -EACCES;
39188+ if (gr_handle_chroot_sysctl(op))
39189+ return -EACCES;
39190+ error = gr_handle_sysctl(table, op);
39191+ if (error)
39192+ return error;
39193+
39194+ error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
39195+ if (error)
39196+ return error;
39197+
39198+ if (root->permissions)
39199+ mode = root->permissions(root, current->nsproxy, table);
39200+ else
39201+ mode = table->mode;
39202+
39203+ return test_perm(mode, op);
39204+}
39205+
39206+int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
39207+{
39208+ int error;
39209+ int mode;
39210+
39211 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
39212 if (error)
39213 return error;
017d2877
AM
39214diff -urNp linux-2.6.30.4/kernel/taskstats.c linux-2.6.30.4/kernel/taskstats.c
39215--- linux-2.6.30.4/kernel/taskstats.c 2009-07-24 17:47:51.000000000 -0400
39216+++ linux-2.6.30.4/kernel/taskstats.c 2009-07-30 11:10:49.711410081 -0400
de855c5d
AM
39217@@ -26,9 +26,12 @@
39218 #include <linux/cgroup.h>
39219 #include <linux/fs.h>
39220 #include <linux/file.h>
39221+#include <linux/grsecurity.h>
39222 #include <net/genetlink.h>
39223 #include <asm/atomic.h>
39224
39225+extern int gr_is_taskstats_denied(int pid);
39226+
39227 /*
39228 * Maximum length of a cpumask that can be specified in
39229 * the TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK attribute
39230@@ -433,6 +436,9 @@ static int taskstats_user_cmd(struct sk_
39231 size_t size;
39232 cpumask_var_t mask;
39233
39234+ if (gr_is_taskstats_denied(current->pid))
39235+ return -EACCES;
39236+
39237 if (!alloc_cpumask_var(&mask, GFP_KERNEL))
39238 return -ENOMEM;
39239
017d2877
AM
39240diff -urNp linux-2.6.30.4/kernel/time/tick-broadcast.c linux-2.6.30.4/kernel/time/tick-broadcast.c
39241--- linux-2.6.30.4/kernel/time/tick-broadcast.c 2009-07-24 17:47:51.000000000 -0400
39242+++ linux-2.6.30.4/kernel/time/tick-broadcast.c 2009-07-30 09:48:10.137714626 -0400
2380c486
JR
39243@@ -116,7 +116,7 @@ int tick_device_uses_broadcast(struct cl
39244 * then clear the broadcast bit.
39245 */
39246 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
39247- int cpu = smp_processor_id();
39248+ cpu = smp_processor_id();
39249
39250 cpumask_clear_cpu(cpu, tick_get_broadcast_mask());
39251 tick_broadcast_clear_oneshot(cpu);
017d2877
AM
39252diff -urNp linux-2.6.30.4/kernel/time/timer_list.c linux-2.6.30.4/kernel/time/timer_list.c
39253--- linux-2.6.30.4/kernel/time/timer_list.c 2009-07-24 17:47:51.000000000 -0400
39254+++ linux-2.6.30.4/kernel/time/timer_list.c 2009-07-30 09:48:10.137714626 -0400
39255@@ -275,7 +275,7 @@ static int timer_list_open(struct inode
39256 return single_open(filp, timer_list_show, NULL);
39257 }
39258
39259-static struct file_operations timer_list_fops = {
39260+static const struct file_operations timer_list_fops = {
39261 .open = timer_list_open,
39262 .read = seq_read,
39263 .llseek = seq_lseek,
39264diff -urNp linux-2.6.30.4/kernel/time/timer_stats.c linux-2.6.30.4/kernel/time/timer_stats.c
39265--- linux-2.6.30.4/kernel/time/timer_stats.c 2009-07-24 17:47:51.000000000 -0400
39266+++ linux-2.6.30.4/kernel/time/timer_stats.c 2009-07-30 09:48:10.138707979 -0400
39267@@ -395,7 +395,7 @@ static int tstats_open(struct inode *ino
39268 return single_open(filp, tstats_show, NULL);
39269 }
39270
39271-static struct file_operations tstats_fops = {
39272+static const struct file_operations tstats_fops = {
39273 .open = tstats_open,
39274 .read = seq_read,
39275 .write = tstats_write,
39276diff -urNp linux-2.6.30.4/kernel/time.c linux-2.6.30.4/kernel/time.c
39277--- linux-2.6.30.4/kernel/time.c 2009-07-24 17:47:51.000000000 -0400
39278+++ linux-2.6.30.4/kernel/time.c 2009-07-30 11:10:49.712371224 -0400
39279@@ -95,6 +95,7 @@
2380c486
JR
39280 return err;
39281
017d2877 39282 vx_settimeofday(&tv);
2380c486 39283+ gr_log_timechange();
2380c486
JR
39284 return 0;
39285 }
39286
39287@@ -202,6 +205,8 @@ SYSCALL_DEFINE2(settimeofday, struct tim
39288 return -EFAULT;
39289 }
39290
39291+ gr_log_timechange();
39292+
39293 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
39294 }
39295
39296@@ -240,7 +245,7 @@ EXPORT_SYMBOL(current_fs_time);
39297 * Avoid unnecessary multiplications/divisions in the
39298 * two most common HZ cases:
39299 */
39300-unsigned int inline jiffies_to_msecs(const unsigned long j)
39301+inline unsigned int jiffies_to_msecs(const unsigned long j)
39302 {
39303 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
39304 return (MSEC_PER_SEC / HZ) * j;
39305@@ -256,7 +261,7 @@ unsigned int inline jiffies_to_msecs(con
39306 }
39307 EXPORT_SYMBOL(jiffies_to_msecs);
39308
39309-unsigned int inline jiffies_to_usecs(const unsigned long j)
39310+inline unsigned int jiffies_to_usecs(const unsigned long j)
39311 {
39312 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
39313 return (USEC_PER_SEC / HZ) * j;
017d2877
AM
39314diff -urNp linux-2.6.30.4/kernel/trace/ftrace.c linux-2.6.30.4/kernel/trace/ftrace.c
39315--- linux-2.6.30.4/kernel/trace/ftrace.c 2009-07-24 17:47:51.000000000 -0400
39316+++ linux-2.6.30.4/kernel/trace/ftrace.c 2009-07-30 09:48:10.139681175 -0400
39317@@ -1001,7 +1001,7 @@ static int t_show(struct seq_file *m, vo
39318 return 0;
39319 }
39320
39321-static struct seq_operations show_ftrace_seq_ops = {
39322+static const struct seq_operations show_ftrace_seq_ops = {
39323 .start = t_start,
39324 .next = t_next,
39325 .stop = t_stop,
39326@@ -1956,7 +1956,7 @@ static int g_show(struct seq_file *m, vo
39327 return 0;
39328 }
39329
39330-static struct seq_operations ftrace_graph_seq_ops = {
39331+static const struct seq_operations ftrace_graph_seq_ops = {
39332 .start = g_start,
39333 .next = g_next,
39334 .stop = g_stop,
39335diff -urNp linux-2.6.30.4/kernel/trace/Kconfig linux-2.6.30.4/kernel/trace/Kconfig
39336--- linux-2.6.30.4/kernel/trace/Kconfig 2009-07-24 17:47:51.000000000 -0400
39337+++ linux-2.6.30.4/kernel/trace/Kconfig 2009-07-30 11:13:44.980492661 -0400
39338@@ -78,6 +78,7 @@ menu "Tracers"
39339 config FUNCTION_TRACER
39340 bool "Kernel Function Tracer"
39341 depends on HAVE_FUNCTION_TRACER
39342+ depends on !PAX_KERNEXEC
39343 select FRAME_POINTER
39344 select KALLSYMS
39345 select TRACING
39346@@ -271,6 +272,7 @@ config POWER_TRACER
39347 config STACK_TRACER
39348 bool "Trace max stack"
39349 depends on HAVE_FUNCTION_TRACER
39350+ depends on !PAX_KERNEXEC
39351 select FUNCTION_TRACER
39352 select STACKTRACE
39353 select KALLSYMS
39354diff -urNp linux-2.6.30.4/kernel/trace/trace.c linux-2.6.30.4/kernel/trace/trace.c
39355--- linux-2.6.30.4/kernel/trace/trace.c 2009-07-24 17:47:51.000000000 -0400
39356+++ linux-2.6.30.4/kernel/trace/trace.c 2009-07-30 09:48:10.139681175 -0400
39357@@ -1836,7 +1836,7 @@ static int s_show(struct seq_file *m, vo
39358 return 0;
39359 }
39360
39361-static struct seq_operations tracer_seq_ops = {
39362+static const struct seq_operations tracer_seq_ops = {
39363 .start = s_start,
39364 .next = s_next,
39365 .stop = s_stop,
39366@@ -2050,7 +2050,7 @@ static int t_show(struct seq_file *m, vo
39367 return 0;
39368 }
39369
39370-static struct seq_operations show_traces_seq_ops = {
39371+static const struct seq_operations show_traces_seq_ops = {
39372 .start = t_start,
39373 .next = t_next,
39374 .stop = t_stop,
39375diff -urNp linux-2.6.30.4/kernel/trace/trace_output.c linux-2.6.30.4/kernel/trace/trace_output.c
39376--- linux-2.6.30.4/kernel/trace/trace_output.c 2009-07-24 17:47:51.000000000 -0400
39377+++ linux-2.6.30.4/kernel/trace/trace_output.c 2009-07-30 09:48:10.140750846 -0400
39378@@ -188,7 +188,7 @@ int trace_seq_path(struct trace_seq *s,
2380c486
JR
39379 return 0;
39380 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
39381 if (!IS_ERR(p)) {
39382- p = mangle_path(s->buffer + s->len, p, "\n");
39383+ p = mangle_path(s->buffer + s->len, p, "\n\\");
39384 if (p) {
39385 s->len = p - s->buffer;
39386 return 1;
017d2877
AM
39387diff -urNp linux-2.6.30.4/kernel/utsname_sysctl.c linux-2.6.30.4/kernel/utsname_sysctl.c
39388--- linux-2.6.30.4/kernel/utsname_sysctl.c 2009-07-24 17:47:51.000000000 -0400
39389+++ linux-2.6.30.4/kernel/utsname_sysctl.c 2009-07-30 09:48:10.140750846 -0400
2380c486
JR
39390@@ -123,7 +123,7 @@ static struct ctl_table uts_kern_table[]
39391 .proc_handler = proc_do_uts_string,
39392 .strategy = sysctl_uts_string,
39393 },
39394- {}
39395+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
39396 };
39397
39398 static struct ctl_table uts_root_table[] = {
39399@@ -133,7 +133,7 @@ static struct ctl_table uts_root_table[]
39400 .mode = 0555,
39401 .child = uts_kern_table,
39402 },
39403- {}
39404+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
39405 };
39406
39407 static int __init utsname_sysctl_init(void)
017d2877
AM
39408diff -urNp linux-2.6.30.4/lib/Kconfig.debug linux-2.6.30.4/lib/Kconfig.debug
39409--- linux-2.6.30.4/lib/Kconfig.debug 2009-07-24 17:47:51.000000000 -0400
39410+++ linux-2.6.30.4/lib/Kconfig.debug 2009-07-30 11:10:49.747708160 -0400
39411@@ -821,7 +821,7 @@ config LATENCYTOP
de855c5d
AM
39412 select STACKTRACE
39413 select SCHEDSTATS
39414 select SCHED_DEBUG
39415- depends on HAVE_LATENCYTOP_SUPPORT
39416+ depends on HAVE_LATENCYTOP_SUPPORT && !GRKERNSEC_HIDESYM
39417 help
39418 Enable this option if you want to use the LatencyTOP tool
39419 to find out which userspace is blocking on what kernel operations.
017d2877
AM
39420diff -urNp linux-2.6.30.4/lib/parser.c linux-2.6.30.4/lib/parser.c
39421--- linux-2.6.30.4/lib/parser.c 2009-07-24 17:47:51.000000000 -0400
39422+++ linux-2.6.30.4/lib/parser.c 2009-07-30 09:48:10.140750846 -0400
de855c5d
AM
39423@@ -126,7 +126,7 @@ static int match_number(substring_t *s,
39424 char *buf;
39425 int ret;
39426
39427- buf = kmalloc(s->to - s->from + 1, GFP_KERNEL);
39428+ buf = kmalloc((s->to - s->from) + 1, GFP_KERNEL);
39429 if (!buf)
39430 return -ENOMEM;
39431 memcpy(buf, s->from, s->to - s->from);
017d2877
AM
39432diff -urNp linux-2.6.30.4/lib/radix-tree.c linux-2.6.30.4/lib/radix-tree.c
39433--- linux-2.6.30.4/lib/radix-tree.c 2009-07-24 17:47:51.000000000 -0400
39434+++ linux-2.6.30.4/lib/radix-tree.c 2009-07-30 09:48:10.140750846 -0400
2380c486
JR
39435@@ -81,7 +81,7 @@ struct radix_tree_preload {
39436 int nr;
39437 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
39438 };
39439-static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
39440+static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
39441
39442 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
39443 {
017d2877
AM
39444diff -urNp linux-2.6.30.4/lib/random32.c linux-2.6.30.4/lib/random32.c
39445--- linux-2.6.30.4/lib/random32.c 2009-07-24 17:47:51.000000000 -0400
39446+++ linux-2.6.30.4/lib/random32.c 2009-07-30 09:48:10.141806319 -0400
de855c5d
AM
39447@@ -61,7 +61,7 @@ static u32 __random32(struct rnd_state *
39448 */
39449 static inline u32 __seed(u32 x, u32 m)
39450 {
39451- return (x < m) ? x + m : x;
39452+ return (x <= m) ? x + m + 1 : x;
39453 }
39454
39455 /**
017d2877
AM
39456diff -urNp linux-2.6.30.4/localversion-grsec linux-2.6.30.4/localversion-grsec
39457--- linux-2.6.30.4/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
39458+++ linux-2.6.30.4/localversion-grsec 2009-07-30 11:10:49.747708160 -0400
2380c486
JR
39459@@ -0,0 +1 @@
39460+-grsec
017d2877
AM
39461diff -urNp linux-2.6.30.4/Makefile linux-2.6.30.4/Makefile
39462--- linux-2.6.30.4/Makefile 2009-07-30 20:32:40.332701013 -0400
39463+++ linux-2.6.30.4/Makefile 2009-07-30 20:32:47.921679729 -0400
39464@@ -231,8 +231,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
2380c486
JR
39465
39466 HOSTCC = gcc
39467 HOSTCXX = g++
39468-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
017d2877
AM
39469-HOSTCXXFLAGS = -O2
39470+HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-delete-null-pointer-checks
39471+HOSTCXXFLAGS = -O2 -fno-delete-null-pointer-checks
2380c486
JR
39472
39473 # Decide whether to build built-in, modular, or both.
017d2877
AM
39474 # Normally, just do built-in.
39475@@ -647,7 +647,7 @@ export mod_strip_cmd
2380c486
JR
39476
39477
39478 ifeq ($(KBUILD_EXTMOD),)
39479-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
39480+core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
39481
39482 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
39483 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
017d2877
AM
39484diff -urNp linux-2.6.30.4/mm/filemap.c linux-2.6.30.4/mm/filemap.c
39485--- linux-2.6.30.4/mm/filemap.c 2009-07-30 20:32:40.553577478 -0400
39486+++ linux-2.6.30.4/mm/filemap.c 2009-07-30 20:32:48.096612667 -0400
39487@@ -1625,7 +1625,7 @@ page_not_uptodate:
39488 }
39489 EXPORT_SYMBOL(filemap_fault);
39490
39491-struct vm_operations_struct generic_file_vm_ops = {
39492+const struct vm_operations_struct generic_file_vm_ops = {
39493 .fault = filemap_fault,
39494 };
39495
39496@@ -1636,7 +1636,7 @@ int generic_file_mmap(struct file * file
2380c486
JR
39497 struct address_space *mapping = file->f_mapping;
39498
39499 if (!mapping->a_ops->readpage)
39500- return -ENOEXEC;
39501+ return -ENODEV;
39502 file_accessed(file);
39503 vma->vm_ops = &generic_file_vm_ops;
39504 vma->vm_flags |= VM_CAN_NONLINEAR;
017d2877 39505@@ -1996,6 +1996,7 @@ inline int generic_write_checks(struct f
2380c486
JR
39506 *pos = i_size_read(inode);
39507
39508 if (limit != RLIM_INFINITY) {
39509+ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
39510 if (*pos >= limit) {
39511 send_sig(SIGXFSZ, current, 0);
39512 return -EFBIG;
017d2877
AM
39513diff -urNp linux-2.6.30.4/mm/filemap_xip.c linux-2.6.30.4/mm/filemap_xip.c
39514--- linux-2.6.30.4/mm/filemap_xip.c 2009-07-24 17:47:51.000000000 -0400
39515+++ linux-2.6.30.4/mm/filemap_xip.c 2009-07-30 09:48:10.142775471 -0400
39516@@ -296,7 +296,7 @@ out:
39517 }
39518 }
39519
39520-static struct vm_operations_struct xip_file_vm_ops = {
39521+static const struct vm_operations_struct xip_file_vm_ops = {
39522 .fault = xip_file_fault,
39523 };
39524
39525diff -urNp linux-2.6.30.4/mm/fremap.c linux-2.6.30.4/mm/fremap.c
39526--- linux-2.6.30.4/mm/fremap.c 2009-07-24 17:47:51.000000000 -0400
39527+++ linux-2.6.30.4/mm/fremap.c 2009-07-30 09:48:10.142775471 -0400
2380c486
JR
39528@@ -153,6 +153,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsign
39529 retry:
39530 vma = find_vma(mm, start);
39531
39532+#ifdef CONFIG_PAX_SEGMEXEC
39533+ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC))
39534+ goto out;
39535+#endif
39536+
39537 /*
39538 * Make sure the vma is shared, that it supports prefaulting,
39539 * and that the remapped range is valid and fully within
017d2877
AM
39540diff -urNp linux-2.6.30.4/mm/hugetlb.c linux-2.6.30.4/mm/hugetlb.c
39541--- linux-2.6.30.4/mm/hugetlb.c 2009-07-24 17:47:51.000000000 -0400
39542+++ linux-2.6.30.4/mm/hugetlb.c 2009-07-30 09:48:10.143720396 -0400
39543@@ -1661,7 +1661,7 @@ static int hugetlb_vm_op_fault(struct vm
39544 return 0;
39545 }
39546
39547-struct vm_operations_struct hugetlb_vm_ops = {
39548+const struct vm_operations_struct hugetlb_vm_ops = {
39549 .fault = hugetlb_vm_op_fault,
39550 .open = hugetlb_vm_op_open,
39551 .close = hugetlb_vm_op_close,
2380c486
JR
39552@@ -1864,6 +1864,26 @@ static int unmap_ref_private(struct mm_s
39553 return 1;
39554 }
39555
39556+#ifdef CONFIG_PAX_SEGMEXEC
39557+static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
39558+{
39559+ struct mm_struct *mm = vma->vm_mm;
39560+ struct vm_area_struct *vma_m;
39561+ unsigned long address_m;
39562+ pte_t *ptep_m;
39563+
39564+ vma_m = pax_find_mirror_vma(vma);
39565+ if (!vma_m)
39566+ return;
39567+
39568+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
39569+ address_m = address + SEGMEXEC_TASK_SIZE;
39570+ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
39571+ get_page(page_m);
39572+ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
39573+}
39574+#endif
39575+
39576 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
39577 unsigned long address, pte_t *ptep, pte_t pte,
39578 struct page *pagecache_page)
39579@@ -1935,6 +1955,11 @@ retry_avoidcopy:
39580 huge_ptep_clear_flush(vma, address, ptep);
39581 set_huge_pte_at(mm, address, ptep,
39582 make_huge_pte(vma, new_page, 1));
39583+
39584+#ifdef CONFIG_PAX_SEGMEXEC
39585+ pax_mirror_huge_pte(vma, address, new_page);
39586+#endif
39587+
39588 /* Make the old page be freed below */
39589 new_page = old_page;
39590 }
39591@@ -2044,6 +2069,10 @@ retry:
39592 && (vma->vm_flags & VM_SHARED)));
39593 set_huge_pte_at(mm, address, ptep, new_pte);
39594
39595+#ifdef CONFIG_PAX_SEGMEXEC
39596+ pax_mirror_huge_pte(vma, address, page);
39597+#endif
39598+
39599 if (write_access && !(vma->vm_flags & VM_SHARED)) {
39600 /* Optimization, do the COW without a second fault */
39601 ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
39602@@ -2072,6 +2101,28 @@ int hugetlb_fault(struct mm_struct *mm,
39603 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
39604 struct hstate *h = hstate_vma(vma);
39605
39606+#ifdef CONFIG_PAX_SEGMEXEC
39607+ struct vm_area_struct *vma_m;
39608+
39609+ vma_m = pax_find_mirror_vma(vma);
39610+ if (vma_m) {
39611+ unsigned long address_m;
39612+
39613+ if (vma->vm_start > vma_m->vm_start) {
39614+ address_m = address;
39615+ address -= SEGMEXEC_TASK_SIZE;
39616+ vma = vma_m;
39617+ h = hstate_vma(vma);
39618+ } else
39619+ address_m = address + SEGMEXEC_TASK_SIZE;
39620+
39621+ if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
39622+ return VM_FAULT_OOM;
39623+ address_m &= HPAGE_MASK;
39624+ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
39625+ }
39626+#endif
39627+
39628 ptep = huge_pte_alloc(mm, address, huge_page_size(h));
39629 if (!ptep)
39630 return VM_FAULT_OOM;
017d2877
AM
39631diff -urNp linux-2.6.30.4/mm/madvise.c linux-2.6.30.4/mm/madvise.c
39632--- linux-2.6.30.4/mm/madvise.c 2009-07-24 17:47:51.000000000 -0400
39633+++ linux-2.6.30.4/mm/madvise.c 2009-07-30 09:48:10.143720396 -0400
2380c486
JR
39634@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
39635 pgoff_t pgoff;
39636 int new_flags = vma->vm_flags;
39637
39638+#ifdef CONFIG_PAX_SEGMEXEC
39639+ struct vm_area_struct *vma_m;
39640+#endif
39641+
39642 switch (behavior) {
39643 case MADV_NORMAL:
39644 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
39645@@ -92,6 +96,13 @@ success:
39646 /*
39647 * vm_flags is protected by the mmap_sem held in write mode.
39648 */
39649+
39650+#ifdef CONFIG_PAX_SEGMEXEC
39651+ vma_m = pax_find_mirror_vma(vma);
39652+ if (vma_m)
39653+ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
39654+#endif
39655+
39656 vma->vm_flags = new_flags;
39657
39658 out:
017d2877 39659@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
2380c486
JR
39660
39661 case MADV_DONTNEED:
39662 error = madvise_dontneed(vma, prev, start, end);
39663+
39664+#ifdef CONFIG_PAX_SEGMEXEC
39665+ if (!error) {
39666+ struct vm_area_struct *vma_m, *prev_m;
39667+
39668+ vma_m = pax_find_mirror_vma(vma);
39669+ if (vma_m)
39670+ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
39671+ }
39672+#endif
39673+
39674 break;
39675
39676 default:
017d2877 39677@@ -308,6 +330,16 @@ SYSCALL_DEFINE3(madvise, unsigned long,
2380c486
JR
39678 if (end < start)
39679 goto out;
39680
39681+#ifdef CONFIG_PAX_SEGMEXEC
39682+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
39683+ if (end > SEGMEXEC_TASK_SIZE)
39684+ goto out;
39685+ } else
39686+#endif
39687+
39688+ if (end > TASK_SIZE)
39689+ goto out;
39690+
39691 error = 0;
39692 if (end == start)
39693 goto out;
017d2877
AM
39694diff -urNp linux-2.6.30.4/mm/memory.c linux-2.6.30.4/mm/memory.c
39695--- linux-2.6.30.4/mm/memory.c 2009-07-24 17:47:51.000000000 -0400
39696+++ linux-2.6.30.4/mm/memory.c 2009-07-30 11:10:49.792655285 -0400
2380c486
JR
39697@@ -47,6 +47,7 @@
39698 #include <linux/pagemap.h>
39699 #include <linux/rmap.h>
39700 #include <linux/module.h>
39701+#include <linux/security.h>
39702 #include <linux/delayacct.h>
39703 #include <linux/init.h>
39704 #include <linux/writeback.h>
017d2877 39705@@ -1227,11 +1228,11 @@ int __get_user_pages(struct task_struct
2380c486
JR
39706 vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
39707 i = 0;
39708
39709- do {
39710+ while (len) {
39711 struct vm_area_struct *vma;
39712 unsigned int foll_flags;
39713
39714- vma = find_extend_vma(mm, start);
39715+ vma = find_vma(mm, start);
39716 if (!vma && in_gate_area(tsk, start)) {
39717 unsigned long pg = start & PAGE_MASK;
39718 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
017d2877 39719@@ -1273,7 +1274,7 @@ int __get_user_pages(struct task_struct
2380c486
JR
39720 continue;
39721 }
39722
39723- if (!vma ||
39724+ if (!vma || start < vma->vm_start ||
39725 (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
39726 (!ignore && !(vm_flags & vma->vm_flags)))
39727 return i ? : -EFAULT;
017d2877 39728@@ -1356,7 +1357,7 @@ int __get_user_pages(struct task_struct
2380c486
JR
39729 start += PAGE_SIZE;
39730 len--;
39731 } while (len && start < vma->vm_end);
39732- } while (len);
39733+ }
39734 return i;
39735 }
39736
017d2877 39737@@ -1874,6 +1875,186 @@ static inline void cow_user_page(struct
2380c486
JR
39738 copy_user_highpage(dst, src, va, vma);
39739 }
39740
39741+#ifdef CONFIG_PAX_SEGMEXEC
39742+static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
39743+{
39744+ struct mm_struct *mm = vma->vm_mm;
39745+ spinlock_t *ptl;
39746+ pte_t *pte, entry;
39747+
39748+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
39749+ entry = *pte;
39750+ if (!pte_present(entry)) {
39751+ if (!pte_none(entry)) {
39752+ BUG_ON(pte_file(entry));
39753+ free_swap_and_cache(pte_to_swp_entry(entry));
39754+ pte_clear_not_present_full(mm, address, pte, 0);
39755+ }
39756+ } else {
39757+ struct page *page;
39758+
39759+ flush_cache_page(vma, address, pte_pfn(entry));
39760+ entry = ptep_clear_flush(vma, address, pte);
39761+ BUG_ON(pte_dirty(entry));
39762+ page = vm_normal_page(vma, address, entry);
39763+ if (page) {
39764+ update_hiwater_rss(mm);
39765+ if (PageAnon(page))
39766+ dec_mm_counter(mm, anon_rss);
39767+ else
39768+ dec_mm_counter(mm, file_rss);
39769+ page_remove_rmap(page);
39770+ page_cache_release(page);
39771+ }
39772+ }
39773+ pte_unmap_unlock(pte, ptl);
39774+}
39775+
39776+/* PaX: if vma is mirrored, synchronize the mirror's PTE
39777+ *
39778+ * the ptl of the lower mapped page is held on entry and is not released on exit
39779+ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
39780+ */
39781+static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
39782+{
39783+ struct mm_struct *mm = vma->vm_mm;
39784+ unsigned long address_m;
39785+ spinlock_t *ptl_m;
39786+ struct vm_area_struct *vma_m;
39787+ pmd_t *pmd_m;
39788+ pte_t *pte_m, entry_m;
39789+
39790+ BUG_ON(!page_m || !PageAnon(page_m));
39791+
39792+ vma_m = pax_find_mirror_vma(vma);
39793+ if (!vma_m)
39794+ return;
39795+
39796+ BUG_ON(!PageLocked(page_m));
39797+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
39798+ address_m = address + SEGMEXEC_TASK_SIZE;
39799+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
39800+ pte_m = pte_offset_map_nested(pmd_m, address_m);
39801+ ptl_m = pte_lockptr(mm, pmd_m);
39802+ if (ptl != ptl_m) {
39803+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
39804+ if (!pte_none(*pte_m))
39805+ goto out;
39806+ }
39807+
39808+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
39809+ page_cache_get(page_m);
39810+ page_add_anon_rmap(page_m, vma_m, address_m);
39811+ inc_mm_counter(mm, anon_rss);
39812+ set_pte_at(mm, address_m, pte_m, entry_m);
39813+ update_mmu_cache(vma_m, address_m, entry_m);
39814+out:
39815+ if (ptl != ptl_m)
39816+ spin_unlock(ptl_m);
39817+ pte_unmap_nested(pte_m);
39818+ unlock_page(page_m);
39819+}
39820+
39821+void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
39822+{
39823+ struct mm_struct *mm = vma->vm_mm;
39824+ unsigned long address_m;
39825+ spinlock_t *ptl_m;
39826+ struct vm_area_struct *vma_m;
39827+ pmd_t *pmd_m;
39828+ pte_t *pte_m, entry_m;
39829+
39830+ BUG_ON(!page_m || PageAnon(page_m));
39831+
39832+ vma_m = pax_find_mirror_vma(vma);
39833+ if (!vma_m)
39834+ return;
39835+
39836+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
39837+ address_m = address + SEGMEXEC_TASK_SIZE;
39838+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
39839+ pte_m = pte_offset_map_nested(pmd_m, address_m);
39840+ ptl_m = pte_lockptr(mm, pmd_m);
39841+ if (ptl != ptl_m) {
39842+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
39843+ if (!pte_none(*pte_m))
39844+ goto out;
39845+ }
39846+
39847+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
39848+ page_cache_get(page_m);
39849+ page_add_file_rmap(page_m);
39850+ inc_mm_counter(mm, file_rss);
39851+ set_pte_at(mm, address_m, pte_m, entry_m);
39852+ update_mmu_cache(vma_m, address_m, entry_m);
39853+out:
39854+ if (ptl != ptl_m)
39855+ spin_unlock(ptl_m);
39856+ pte_unmap_nested(pte_m);
39857+}
39858+
39859+static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
39860+{
39861+ struct mm_struct *mm = vma->vm_mm;
39862+ unsigned long address_m;
39863+ spinlock_t *ptl_m;
39864+ struct vm_area_struct *vma_m;
39865+ pmd_t *pmd_m;
39866+ pte_t *pte_m, entry_m;
39867+
39868+ vma_m = pax_find_mirror_vma(vma);
39869+ if (!vma_m)
39870+ return;
39871+
39872+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
39873+ address_m = address + SEGMEXEC_TASK_SIZE;
39874+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
39875+ pte_m = pte_offset_map_nested(pmd_m, address_m);
39876+ ptl_m = pte_lockptr(mm, pmd_m);
39877+ if (ptl != ptl_m) {
39878+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
39879+ if (!pte_none(*pte_m))
39880+ goto out;
39881+ }
39882+
39883+ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
39884+ set_pte_at(mm, address_m, pte_m, entry_m);
39885+out:
39886+ if (ptl != ptl_m)
39887+ spin_unlock(ptl_m);
39888+ pte_unmap_nested(pte_m);
39889+}
39890+
39891+static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
39892+{
39893+ struct page *page_m;
39894+ pte_t entry;
39895+
39896+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
39897+ goto out;
39898+
39899+ entry = *pte;
39900+ page_m = vm_normal_page(vma, address, entry);
39901+ if (!page_m)
39902+ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
39903+ else if (PageAnon(page_m)) {
39904+ if (pax_find_mirror_vma(vma)) {
39905+ pte_unmap_unlock(pte, ptl);
39906+ lock_page(page_m);
39907+ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
39908+ if (pte_same(entry, *pte))
39909+ pax_mirror_anon_pte(vma, address, page_m, ptl);
39910+ else
39911+ unlock_page(page_m);
39912+ }
39913+ } else
39914+ pax_mirror_file_pte(vma, address, page_m, ptl);
39915+
39916+out:
39917+ pte_unmap_unlock(pte, ptl);
39918+}
39919+#endif
39920+
39921 /*
39922 * This routine handles present pages, when users try to write
39923 * to a shared page. It is done by copying the page to a new address
017d2877 39924@@ -2046,6 +2227,12 @@ gotten:
2380c486
JR
39925 */
39926 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
39927 if (likely(pte_same(*page_table, orig_pte))) {
39928+
39929+#ifdef CONFIG_PAX_SEGMEXEC
39930+ if (pax_find_mirror_vma(vma))
39931+ BUG_ON(!trylock_page(new_page));
39932+#endif
39933+
39934 if (old_page) {
39935 if (!PageAnon(old_page)) {
39936 dec_mm_counter(mm, file_rss);
017d2877 39937@@ -2092,6 +2279,10 @@ gotten:
2380c486
JR
39938 page_remove_rmap(old_page);
39939 }
39940
39941+#ifdef CONFIG_PAX_SEGMEXEC
39942+ pax_mirror_anon_pte(vma, address, new_page, ptl);
39943+#endif
39944+
39945 /* Free the old page.. */
39946 new_page = old_page;
39947 ret |= VM_FAULT_WRITE;
017d2877 39948@@ -2373,6 +2564,7 @@ int vmtruncate(struct inode * inode, lof
2380c486
JR
39949 unsigned long limit;
39950
39951 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
39952+ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
39953 if (limit != RLIM_INFINITY && offset > limit)
39954 goto out_sig;
39955 if (offset > inode->i_sb->s_maxbytes)
017d2877 39956@@ -2535,6 +2727,11 @@ static int do_swap_page(struct mm_struct
2380c486
JR
39957 swap_free(entry);
39958 if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
39959 try_to_free_swap(page);
39960+
39961+#ifdef CONFIG_PAX_SEGMEXEC
39962+ if (write_access || !pax_find_mirror_vma(vma))
39963+#endif
39964+
39965 unlock_page(page);
39966
39967 if (write_access) {
017d2877 39968@@ -2546,6 +2743,11 @@ static int do_swap_page(struct mm_struct
2380c486
JR
39969
39970 /* No need to invalidate - it was non-present before */
39971 update_mmu_cache(vma, address, pte);
39972+
39973+#ifdef CONFIG_PAX_SEGMEXEC
39974+ pax_mirror_anon_pte(vma, address, page, ptl);
39975+#endif
39976+
39977 unlock:
39978 pte_unmap_unlock(page_table, ptl);
39979 out:
017d2877 39980@@ -2591,12 +2793,23 @@ static int do_anonymous_page(struct mm_s
2380c486
JR
39981 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
39982 if (!pte_none(*page_table))
39983 goto release;
39984+
39985+#ifdef CONFIG_PAX_SEGMEXEC
39986+ if (pax_find_mirror_vma(vma))
39987+ BUG_ON(!trylock_page(page));
39988+#endif
39989+
39990 inc_mm_counter(mm, anon_rss);
39991 page_add_new_anon_rmap(page, vma, address);
39992 set_pte_at(mm, address, page_table, entry);
39993
39994 /* No need to invalidate - it was non-present before */
39995 update_mmu_cache(vma, address, entry);
39996+
39997+#ifdef CONFIG_PAX_SEGMEXEC
39998+ pax_mirror_anon_pte(vma, address, page, ptl);
39999+#endif
40000+
40001 unlock:
40002 pte_unmap_unlock(page_table, ptl);
40003 return 0;
017d2877 40004@@ -2733,6 +2946,12 @@ static int __do_fault(struct mm_struct *
2380c486
JR
40005 */
40006 /* Only go through if we didn't race with anybody else... */
40007 if (likely(pte_same(*page_table, orig_pte))) {
40008+
40009+#ifdef CONFIG_PAX_SEGMEXEC
40010+ if (anon && pax_find_mirror_vma(vma))
40011+ BUG_ON(!trylock_page(page));
40012+#endif
40013+
40014 flush_icache_page(vma, page);
40015 entry = mk_pte(page, vma->vm_page_prot);
40016 if (flags & FAULT_FLAG_WRITE)
017d2877 40017@@ -2752,6 +2971,14 @@ static int __do_fault(struct mm_struct *
2380c486
JR
40018
40019 /* no need to invalidate: a not-present page won't be cached */
40020 update_mmu_cache(vma, address, entry);
40021+
40022+#ifdef CONFIG_PAX_SEGMEXEC
40023+ if (anon)
40024+ pax_mirror_anon_pte(vma, address, page, ptl);
40025+ else
40026+ pax_mirror_file_pte(vma, address, page, ptl);
40027+#endif
40028+
40029 } else {
40030 if (charged)
40031 mem_cgroup_uncharge_page(page);
017d2877 40032@@ -2900,6 +3127,12 @@ static inline int handle_pte_fault(struc
2380c486
JR
40033 if (write_access)
40034 flush_tlb_page(vma, address);
40035 }
40036+
40037+#ifdef CONFIG_PAX_SEGMEXEC
40038+ pax_mirror_pte(vma, address, pte, pmd, ptl);
40039+ return 0;
40040+#endif
40041+
40042 unlock:
40043 pte_unmap_unlock(pte, ptl);
40044 return 0;
017d2877 40045@@ -2916,6 +3149,10 @@ int handle_mm_fault(struct mm_struct *mm
2380c486
JR
40046 pmd_t *pmd;
40047 pte_t *pte;
40048
40049+#ifdef CONFIG_PAX_SEGMEXEC
40050+ struct vm_area_struct *vma_m;
40051+#endif
40052+
40053 __set_current_state(TASK_RUNNING);
40054
40055 count_vm_event(PGFAULT);
017d2877 40056@@ -2923,6 +3160,34 @@ int handle_mm_fault(struct mm_struct *mm
2380c486
JR
40057 if (unlikely(is_vm_hugetlb_page(vma)))
40058 return hugetlb_fault(mm, vma, address, write_access);
40059
40060+#ifdef CONFIG_PAX_SEGMEXEC
40061+ vma_m = pax_find_mirror_vma(vma);
40062+ if (vma_m) {
40063+ unsigned long address_m;
40064+ pgd_t *pgd_m;
40065+ pud_t *pud_m;
40066+ pmd_t *pmd_m;
40067+
40068+ if (vma->vm_start > vma_m->vm_start) {
40069+ address_m = address;
40070+ address -= SEGMEXEC_TASK_SIZE;
40071+ vma = vma_m;
40072+ } else
40073+ address_m = address + SEGMEXEC_TASK_SIZE;
40074+
40075+ pgd_m = pgd_offset(mm, address_m);
40076+ pud_m = pud_alloc(mm, pgd_m, address_m);
40077+ if (!pud_m)
40078+ return VM_FAULT_OOM;
40079+ pmd_m = pmd_alloc(mm, pud_m, address_m);
40080+ if (!pmd_m)
40081+ return VM_FAULT_OOM;
40082+ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
40083+ return VM_FAULT_OOM;
40084+ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
40085+ }
40086+#endif
40087+
40088 pgd = pgd_offset(mm, address);
40089 pud = pud_alloc(mm, pgd, address);
40090 if (!pud)
017d2877 40091@@ -3020,7 +3285,7 @@ static int __init gate_vma_init(void)
2380c486
JR
40092 gate_vma.vm_start = FIXADDR_USER_START;
40093 gate_vma.vm_end = FIXADDR_USER_END;
40094 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
40095- gate_vma.vm_page_prot = __P101;
40096+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
40097 /*
40098 * Make sure the vDSO gets into every core dump.
40099 * Dumping its contents makes post-mortem fully interpretable later
017d2877
AM
40100diff -urNp linux-2.6.30.4/mm/mempolicy.c linux-2.6.30.4/mm/mempolicy.c
40101--- linux-2.6.30.4/mm/mempolicy.c 2009-07-24 17:47:51.000000000 -0400
40102+++ linux-2.6.30.4/mm/mempolicy.c 2009-07-30 09:48:10.145161384 -0400
2380c486
JR
40103@@ -551,6 +551,10 @@ static int mbind_range(struct vm_area_st
40104 struct vm_area_struct *next;
40105 int err;
40106
40107+#ifdef CONFIG_PAX_SEGMEXEC
40108+ struct vm_area_struct *vma_m;
40109+#endif
40110+
40111 err = 0;
40112 for (; vma && vma->vm_start < end; vma = next) {
40113 next = vma->vm_next;
40114@@ -562,6 +566,16 @@ static int mbind_range(struct vm_area_st
40115 err = policy_vma(vma, new);
40116 if (err)
40117 break;
40118+
40119+#ifdef CONFIG_PAX_SEGMEXEC
40120+ vma_m = pax_find_mirror_vma(vma);
40121+ if (vma_m) {
40122+ err = policy_vma(vma_m, new);
40123+ if (err)
40124+ break;
40125+ }
40126+#endif
40127+
40128 }
40129 return err;
40130 }
40131@@ -954,6 +968,17 @@ static long do_mbind(unsigned long start
40132
40133 if (end < start)
40134 return -EINVAL;
40135+
40136+#ifdef CONFIG_PAX_SEGMEXEC
40137+ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
40138+ if (end > SEGMEXEC_TASK_SIZE)
40139+ return -EINVAL;
40140+ } else
40141+#endif
40142+
40143+ if (end > TASK_SIZE)
40144+ return -EINVAL;
40145+
40146 if (end == start)
40147 return 0;
40148
40149@@ -2290,7 +2315,7 @@ int show_numa_map(struct seq_file *m, vo
40150
40151 if (file) {
40152 seq_printf(m, " file=");
40153- seq_path(m, &file->f_path, "\n\t= ");
40154+ seq_path(m, &file->f_path, "\n\t\\= ");
40155 } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
40156 seq_printf(m, " heap");
40157 } else if (vma->vm_start <= mm->start_stack &&
017d2877
AM
40158diff -urNp linux-2.6.30.4/mm/mlock.c linux-2.6.30.4/mm/mlock.c
40159--- linux-2.6.30.4/mm/mlock.c 2009-07-24 17:47:51.000000000 -0400
40160+++ linux-2.6.30.4/mm/mlock.c 2009-07-30 11:10:49.799565380 -0400
2380c486
JR
40161@@ -13,6 +13,7 @@
40162 #include <linux/pagemap.h>
40163 #include <linux/mempolicy.h>
40164 #include <linux/syscalls.h>
40165+#include <linux/security.h>
40166 #include <linux/sched.h>
40167 #include <linux/module.h>
40168 #include <linux/rmap.h>
40169@@ -453,6 +454,17 @@ static int do_mlock(unsigned long start,
40170 return -EINVAL;
40171 if (end == start)
40172 return 0;
40173+
40174+#ifdef CONFIG_PAX_SEGMEXEC
40175+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
40176+ if (end > SEGMEXEC_TASK_SIZE)
40177+ return -EINVAL;
40178+ } else
40179+#endif
40180+
40181+ if (end > TASK_SIZE)
40182+ return -EINVAL;
40183+
40184 vma = find_vma_prev(current->mm, start, &prev);
40185 if (!vma || vma->vm_start > start)
40186 return -ENOMEM;
40187@@ -512,6 +524,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
40188 lock_limit >>= PAGE_SHIFT;
40189
40190 /* check against resource limits */
40191+ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
40192 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
40193 error = do_mlock(start, len, 1);
40194 up_write(&current->mm->mmap_sem);
40195@@ -533,10 +546,10 @@ SYSCALL_DEFINE2(munlock, unsigned long,
40196 static int do_mlockall(int flags)
40197 {
40198 struct vm_area_struct * vma, * prev = NULL;
40199- unsigned int def_flags = 0;
40200+ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
40201
40202 if (flags & MCL_FUTURE)
40203- def_flags = VM_LOCKED;
40204+ def_flags |= VM_LOCKED;
40205 current->mm->def_flags = def_flags;
40206 if (flags == MCL_FUTURE)
40207 goto out;
40208@@ -544,6 +557,12 @@ static int do_mlockall(int flags)
40209 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
40210 unsigned int newflags;
40211
40212+#ifdef CONFIG_PAX_SEGMEXEC
40213+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
40214+ break;
40215+#endif
40216+
40217+ BUG_ON(vma->vm_end > TASK_SIZE);
40218 newflags = vma->vm_flags | VM_LOCKED;
40219 if (!(flags & MCL_CURRENT))
40220 newflags &= ~VM_LOCKED;
017d2877 40221@@ -600,6 +600,7 @@
2380c486 40222 ret = -ENOMEM;
017d2877
AM
40223 if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
40224 goto out;
3f74aa08 40225+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
2380c486 40226 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
3f74aa08
AM
40227 capable(CAP_IPC_LOCK))
40228 ret = do_mlockall(flags);
017d2877
AM
40229diff -urNp linux-2.6.30.4/mm/mmap.c linux-2.6.30.4/mm/mmap.c
40230--- linux-2.6.30.4/mm/mmap.c 2009-07-24 17:47:51.000000000 -0400
40231+++ linux-2.6.30.4/mm/mmap.c 2009-07-30 11:10:49.813589536 -0400
40232@@ -44,6 +44,16 @@
2380c486
JR
40233 #define arch_rebalance_pgtables(addr, len) (addr)
40234 #endif
40235
40236+static inline void verify_mm_writelocked(struct mm_struct *mm)
40237+{
40238+#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
40239+ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
40240+ up_read(&mm->mmap_sem);
40241+ BUG();
40242+ }
40243+#endif
40244+}
40245+
40246 static void unmap_region(struct mm_struct *mm,
40247 struct vm_area_struct *vma, struct vm_area_struct *prev,
40248 unsigned long start, unsigned long end);
017d2877 40249@@ -69,16 +79,25 @@ static void unmap_region(struct mm_struc
2380c486
JR
40250 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
40251 *
40252 */
40253-pgprot_t protection_map[16] = {
40254+pgprot_t protection_map[16] __read_only = {
40255 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
40256 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
40257 };
40258
40259 pgprot_t vm_get_page_prot(unsigned long vm_flags)
40260 {
40261- return __pgprot(pgprot_val(protection_map[vm_flags &
40262+ pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
40263 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
40264 pgprot_val(arch_vm_get_page_prot(vm_flags)));
40265+
40266+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
40267+ if (!nx_enabled &&
40268+ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
40269+ (vm_flags & (VM_READ | VM_WRITE)))
40270+ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
40271+#endif
40272+
40273+ return prot;
40274 }
40275 EXPORT_SYMBOL(vm_get_page_prot);
40276
017d2877 40277@@ -233,6 +252,7 @@ static struct vm_area_struct *remove_vma
2380c486
JR
40278 struct vm_area_struct *next = vma->vm_next;
40279
40280 might_sleep();
40281+ BUG_ON(vma->vm_mirror);
40282 if (vma->vm_ops && vma->vm_ops->close)
40283 vma->vm_ops->close(vma);
40284 if (vma->vm_file) {
017d2877 40285@@ -269,6 +289,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
2380c486
JR
40286 * not page aligned -Ram Gupta
40287 */
40288 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
40289+ gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
40290 if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
40291 (mm->end_data - mm->start_data) > rlim)
40292 goto out;
017d2877 40293@@ -698,6 +719,12 @@ static int
2380c486
JR
40294 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
40295 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
40296 {
40297+
40298+#ifdef CONFIG_PAX_SEGMEXEC
40299+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
40300+ return 0;
40301+#endif
40302+
40303 if (is_mergeable_vma(vma, file, vm_flags) &&
40304 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
40305 if (vma->vm_pgoff == vm_pgoff)
017d2877 40306@@ -717,6 +744,12 @@ static int
2380c486
JR
40307 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
40308 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
40309 {
40310+
40311+#ifdef CONFIG_PAX_SEGMEXEC
40312+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
40313+ return 0;
40314+#endif
40315+
40316 if (is_mergeable_vma(vma, file, vm_flags) &&
40317 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
40318 pgoff_t vm_pglen;
017d2877 40319@@ -759,12 +792,19 @@ can_vma_merge_after(struct vm_area_struc
2380c486
JR
40320 struct vm_area_struct *vma_merge(struct mm_struct *mm,
40321 struct vm_area_struct *prev, unsigned long addr,
40322 unsigned long end, unsigned long vm_flags,
40323- struct anon_vma *anon_vma, struct file *file,
40324+ struct anon_vma *anon_vma, struct file *file,
40325 pgoff_t pgoff, struct mempolicy *policy)
40326 {
40327 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
40328 struct vm_area_struct *area, *next;
40329
40330+#ifdef CONFIG_PAX_SEGMEXEC
40331+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
40332+ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
40333+
40334+ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
40335+#endif
40336+
40337 /*
40338 * We later require that vma->vm_flags == vm_flags,
40339 * so this tests vma->vm_flags & VM_SPECIAL, too.
017d2877 40340@@ -780,6 +820,15 @@ struct vm_area_struct *vma_merge(struct
2380c486
JR
40341 if (next && next->vm_end == end) /* cases 6, 7, 8 */
40342 next = next->vm_next;
40343
40344+#ifdef CONFIG_PAX_SEGMEXEC
40345+ if (prev)
40346+ prev_m = pax_find_mirror_vma(prev);
40347+ if (area)
40348+ area_m = pax_find_mirror_vma(area);
40349+ if (next)
40350+ next_m = pax_find_mirror_vma(next);
40351+#endif
40352+
40353 /*
40354 * Can it merge with the predecessor?
40355 */
017d2877 40356@@ -799,9 +848,24 @@ struct vm_area_struct *vma_merge(struct
2380c486
JR
40357 /* cases 1, 6 */
40358 vma_adjust(prev, prev->vm_start,
40359 next->vm_end, prev->vm_pgoff, NULL);
40360- } else /* cases 2, 5, 7 */
40361+
40362+#ifdef CONFIG_PAX_SEGMEXEC
40363+ if (prev_m)
40364+ vma_adjust(prev_m, prev_m->vm_start,
40365+ next_m->vm_end, prev_m->vm_pgoff, NULL);
40366+#endif
40367+
40368+ } else { /* cases 2, 5, 7 */
40369 vma_adjust(prev, prev->vm_start,
40370 end, prev->vm_pgoff, NULL);
40371+
40372+#ifdef CONFIG_PAX_SEGMEXEC
40373+ if (prev_m)
40374+ vma_adjust(prev_m, prev_m->vm_start,
40375+ end_m, prev_m->vm_pgoff, NULL);
40376+#endif
40377+
40378+ }
40379 return prev;
40380 }
40381
017d2877 40382@@ -812,12 +876,27 @@ struct vm_area_struct *vma_merge(struct
2380c486
JR
40383 mpol_equal(policy, vma_policy(next)) &&
40384 can_vma_merge_before(next, vm_flags,
40385 anon_vma, file, pgoff+pglen)) {
40386- if (prev && addr < prev->vm_end) /* case 4 */
40387+ if (prev && addr < prev->vm_end) { /* case 4 */
40388 vma_adjust(prev, prev->vm_start,
40389 addr, prev->vm_pgoff, NULL);
40390- else /* cases 3, 8 */
40391+
40392+#ifdef CONFIG_PAX_SEGMEXEC
40393+ if (prev_m)
40394+ vma_adjust(prev_m, prev_m->vm_start,
40395+ addr_m, prev_m->vm_pgoff, NULL);
40396+#endif
40397+
40398+ } else { /* cases 3, 8 */
40399 vma_adjust(area, addr, next->vm_end,
40400 next->vm_pgoff - pglen, NULL);
40401+
40402+#ifdef CONFIG_PAX_SEGMEXEC
40403+ if (area_m)
40404+ vma_adjust(area_m, addr_m, next_m->vm_end,
40405+ next_m->vm_pgoff - pglen, NULL);
40406+#endif
40407+
40408+ }
40409 return area;
40410 }
40411
017d2877 40412@@ -892,14 +971,11 @@ none:
2380c486
JR
40413 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
40414 struct file *file, long pages)
40415 {
40416- const unsigned long stack_flags
40417- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
40418-
40419 if (file) {
40420 mm->shared_vm += pages;
40421 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
40422 mm->exec_vm += pages;
40423- } else if (flags & stack_flags)
40424+ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
40425 mm->stack_vm += pages;
40426 if (flags & (VM_RESERVED|VM_IO))
40427 mm->reserved_vm += pages;
017d2877 40428@@ -926,7 +1002,7 @@ unsigned long do_mmap_pgoff(struct file
2380c486
JR
40429 * (the exception is when the underlying filesystem is noexec
40430 * mounted, in which case we dont add PROT_EXEC.)
40431 */
40432- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
40433+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
40434 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
40435 prot |= PROT_EXEC;
40436
017d2877 40437@@ -936,15 +1012,15 @@ unsigned long do_mmap_pgoff(struct file
2380c486
JR
40438 if (!(flags & MAP_FIXED))
40439 addr = round_hint_to_min(addr);
40440
40441- error = arch_mmap_check(addr, len, flags);
40442- if (error)
40443- return error;
40444-
40445 /* Careful about overflows.. */
40446 len = PAGE_ALIGN(len);
40447 if (!len || len > TASK_SIZE)
40448 return -ENOMEM;
40449
40450+ error = arch_mmap_check(addr, len, flags);
40451+ if (error)
40452+ return error;
40453+
40454 /* offset overflow? */
40455 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
40456 return -EOVERFLOW;
017d2877 40457@@ -956,7 +1032,7 @@ unsigned long do_mmap_pgoff(struct file
2380c486
JR
40458 /* Obtain the address to map to. we verify (or select) it and ensure
40459 * that it represents a valid section of the address space.
40460 */
40461- addr = get_unmapped_area(file, addr, len, pgoff, flags);
40462+ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
40463 if (addr & ~PAGE_MASK)
40464 return addr;
40465
017d2877 40466@@ -967,6 +1043,26 @@ unsigned long do_mmap_pgoff(struct file
2380c486
JR
40467 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
40468 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
40469
40470+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
40471+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
40472+
40473+#ifdef CONFIG_PAX_MPROTECT
40474+ if (mm->pax_flags & MF_PAX_MPROTECT) {
40475+ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
40476+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
40477+ else
40478+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
40479+ }
40480+#endif
40481+
40482+ }
40483+#endif
40484+
40485+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
40486+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
40487+ vm_flags &= ~VM_PAGEEXEC;
40488+#endif
40489+
40490 if (flags & MAP_LOCKED) {
40491 if (!can_do_mlock())
40492 return -EPERM;
017d2877 40493@@ -980,6 +1076,7 @@ unsigned long do_mmap_pgoff(struct file
2380c486
JR
40494 locked += mm->locked_vm;
40495 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
40496 lock_limit >>= PAGE_SHIFT;
40497+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
40498 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
40499 return -EAGAIN;
40500 }
017d2877 40501@@ -1053,6 +1150,9 @@ unsigned long do_mmap_pgoff(struct file
2380c486
JR
40502 if (error)
40503 return error;
40504
40505+ if (!gr_acl_handle_mmap(file, prot))
40506+ return -EACCES;
40507+
40508 return mmap_region(file, addr, len, flags, vm_flags, pgoff);
40509 }
40510 EXPORT_SYMBOL(do_mmap_pgoff);
017d2877 40511@@ -1065,10 +1165,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
2380c486
JR
40512 */
40513 int vma_wants_writenotify(struct vm_area_struct *vma)
40514 {
40515- unsigned int vm_flags = vma->vm_flags;
40516+ unsigned long vm_flags = vma->vm_flags;
40517
40518 /* If it was private or non-writable, the write bit is already clear */
40519- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
40520+ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
40521 return 0;
40522
40523 /* The backer wishes to know when pages are first written to? */
017d2877 40524@@ -1117,14 +1217,24 @@ unsigned long mmap_region(struct file *f
2380c486
JR
40525 unsigned long charged = 0;
40526 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
40527
40528+#ifdef CONFIG_PAX_SEGMEXEC
40529+ struct vm_area_struct *vma_m = NULL;
40530+#endif
40531+
40532+ /*
40533+ * mm->mmap_sem is required to protect against another thread
40534+ * changing the mappings in case we sleep.
40535+ */
40536+ verify_mm_writelocked(mm);
40537+
40538 /* Clear old maps */
40539 error = -ENOMEM;
40540-munmap_back:
40541 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
40542 if (vma && vma->vm_start < addr + len) {
40543 if (do_munmap(mm, addr, len))
40544 return -ENOMEM;
40545- goto munmap_back;
40546+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
40547+ BUG_ON(vma && vma->vm_start < addr + len);
40548 }
40549
40550 /* Check against address space limit. */
017d2877 40551@@ -1173,6 +1283,16 @@ munmap_back:
2380c486
JR
40552 goto unacct_error;
40553 }
40554
40555+#ifdef CONFIG_PAX_SEGMEXEC
40556+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
40557+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
40558+ if (!vma_m) {
40559+ error = -ENOMEM;
40560+ goto free_vma;
40561+ }
40562+ }
40563+#endif
40564+
40565 vma->vm_mm = mm;
40566 vma->vm_start = addr;
40567 vma->vm_end = addr + len;
017d2877 40568@@ -1195,6 +1315,19 @@ munmap_back:
2380c486
JR
40569 error = file->f_op->mmap(file, vma);
40570 if (error)
40571 goto unmap_and_free_vma;
40572+
40573+#ifdef CONFIG_PAX_SEGMEXEC
40574+ if (vma_m && (vm_flags & VM_EXECUTABLE))
40575+ added_exe_file_vma(mm);
40576+#endif
40577+
40578+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
40579+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
40580+ vma->vm_flags |= VM_PAGEEXEC;
40581+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
40582+ }
40583+#endif
40584+
40585 if (vm_flags & VM_EXECUTABLE)
40586 added_exe_file_vma(mm);
40587 } else if (vm_flags & VM_SHARED) {
017d2877 40588@@ -1351,6 +1351,11 @@
2380c486
JR
40589 vma_link(mm, vma, prev, rb_link, rb_parent);
40590 file = vma->vm_file;
40591
40592+#ifdef CONFIG_PAX_SEGMEXEC
40593+ if (vma_m)
40594+ pax_mirror_vma(vma_m, vma);
40595+#endif
2380c486
JR
40596+
40597 /* Once vma denies write, undo our temporary denial count */
40598 if (correct_wcount)
40599 atomic_inc(&inode->i_writecount);
017d2877
AM
40600@@ -1358,6 +1363,7 @@
40601 // mm->total_vm += len >> PAGE_SHIFT;
40602 vx_vmpages_add(mm, len >> PAGE_SHIFT);
2380c486
JR
40603 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
40604+ track_exec_limit(mm, addr, addr + len, vm_flags);
40605 if (vm_flags & VM_LOCKED) {
40606 /*
40607 * makes pages present; downgrades, drops, reacquires mmap_sem
017d2877 40608@@ -1246,6 +1385,12 @@ unmap_and_free_vma:
2380c486
JR
40609 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
40610 charged = 0;
40611 free_vma:
40612+
40613+#ifdef CONFIG_PAX_SEGMEXEC
40614+ if (vma_m)
40615+ kmem_cache_free(vm_area_cachep, vma_m);
40616+#endif
40617+
40618 kmem_cache_free(vm_area_cachep, vma);
40619 unacct_error:
40620 if (charged)
017d2877 40621@@ -1279,6 +1424,10 @@ arch_get_unmapped_area(struct file *filp
2380c486
JR
40622 if (flags & MAP_FIXED)
40623 return addr;
40624
40625+#ifdef CONFIG_PAX_RANDMMAP
40626+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
40627+#endif
40628+
40629 if (addr) {
40630 addr = PAGE_ALIGN(addr);
40631 vma = find_vma(mm, addr);
017d2877 40632@@ -1287,10 +1436,10 @@ arch_get_unmapped_area(struct file *filp
2380c486
JR
40633 return addr;
40634 }
40635 if (len > mm->cached_hole_size) {
40636- start_addr = addr = mm->free_area_cache;
40637+ start_addr = addr = mm->free_area_cache;
40638 } else {
40639- start_addr = addr = TASK_UNMAPPED_BASE;
40640- mm->cached_hole_size = 0;
40641+ start_addr = addr = mm->mmap_base;
40642+ mm->cached_hole_size = 0;
40643 }
40644
40645 full_search:
017d2877 40646@@ -1301,9 +1450,8 @@ full_search:
2380c486
JR
40647 * Start a new search - just in case we missed
40648 * some holes.
40649 */
40650- if (start_addr != TASK_UNMAPPED_BASE) {
40651- addr = TASK_UNMAPPED_BASE;
40652- start_addr = addr;
40653+ if (start_addr != mm->mmap_base) {
40654+ start_addr = addr = mm->mmap_base;
40655 mm->cached_hole_size = 0;
40656 goto full_search;
40657 }
017d2877 40658@@ -1325,10 +1473,16 @@ full_search:
2380c486
JR
40659
40660 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
40661 {
40662+
40663+#ifdef CONFIG_PAX_SEGMEXEC
40664+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
40665+ return;
40666+#endif
40667+
40668 /*
40669 * Is this a new hole at the lowest possible address?
40670 */
40671- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
40672+ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
40673 mm->free_area_cache = addr;
40674 mm->cached_hole_size = ~0UL;
40675 }
017d2877 40676@@ -1346,7 +1500,7 @@ arch_get_unmapped_area_topdown(struct fi
2380c486
JR
40677 {
40678 struct vm_area_struct *vma;
40679 struct mm_struct *mm = current->mm;
40680- unsigned long addr = addr0;
40681+ unsigned long base = mm->mmap_base, addr = addr0;
40682
40683 /* requested length too big for entire address space */
40684 if (len > TASK_SIZE)
017d2877 40685@@ -1355,6 +1509,10 @@ arch_get_unmapped_area_topdown(struct fi
2380c486
JR
40686 if (flags & MAP_FIXED)
40687 return addr;
40688
40689+#ifdef CONFIG_PAX_RANDMMAP
40690+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
40691+#endif
40692+
40693 /* requesting a specific address */
40694 if (addr) {
40695 addr = PAGE_ALIGN(addr);
017d2877 40696@@ -1412,13 +1570,21 @@ bottomup:
2380c486
JR
40697 * can happen with large stack limits and large mmap()
40698 * allocations.
40699 */
40700+ mm->mmap_base = TASK_UNMAPPED_BASE;
40701+
40702+#ifdef CONFIG_PAX_RANDMMAP
40703+ if (mm->pax_flags & MF_PAX_RANDMMAP)
40704+ mm->mmap_base += mm->delta_mmap;
40705+#endif
40706+
40707+ mm->free_area_cache = mm->mmap_base;
40708 mm->cached_hole_size = ~0UL;
40709- mm->free_area_cache = TASK_UNMAPPED_BASE;
40710 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
40711 /*
40712 * Restore the topdown base:
40713 */
40714- mm->free_area_cache = mm->mmap_base;
40715+ mm->mmap_base = base;
40716+ mm->free_area_cache = base;
40717 mm->cached_hole_size = ~0UL;
40718
40719 return addr;
017d2877 40720@@ -1427,6 +1593,12 @@ bottomup:
2380c486
JR
40721
40722 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
40723 {
40724+
40725+#ifdef CONFIG_PAX_SEGMEXEC
40726+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
40727+ return;
40728+#endif
40729+
40730 /*
40731 * Is this a new hole at the highest possible address?
40732 */
017d2877 40733@@ -1434,8 +1606,10 @@ void arch_unmap_area_topdown(struct mm_s
2380c486
JR
40734 mm->free_area_cache = addr;
40735
40736 /* dont allow allocations above current base */
40737- if (mm->free_area_cache > mm->mmap_base)
40738+ if (mm->free_area_cache > mm->mmap_base) {
40739 mm->free_area_cache = mm->mmap_base;
40740+ mm->cached_hole_size = ~0UL;
40741+ }
40742 }
40743
40744 unsigned long
017d2877 40745@@ -1535,6 +1709,27 @@ out:
2380c486
JR
40746 return prev ? prev->vm_next : vma;
40747 }
40748
40749+#ifdef CONFIG_PAX_SEGMEXEC
40750+struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
40751+{
40752+ struct vm_area_struct *vma_m;
40753+
40754+ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
40755+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
40756+ BUG_ON(vma->vm_mirror);
40757+ return NULL;
40758+ }
40759+ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
40760+ vma_m = vma->vm_mirror;
40761+ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
40762+ BUG_ON(vma->vm_file != vma_m->vm_file);
40763+ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
40764+ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
40765+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
40766+ return vma_m;
40767+}
40768+#endif
40769+
40770 /*
40771 * Verify that the stack growth is acceptable and
40772 * update accounting. This is shared with both the
017d2877 40773@@ -1551,6 +1746,7 @@ static int acct_stack_growth(struct vm_a
2380c486
JR
40774 return -ENOMEM;
40775
40776 /* Stack limit test */
40777+ gr_learn_resource(current, RLIMIT_STACK, size, 1);
40778 if (size > rlim[RLIMIT_STACK].rlim_cur)
40779 return -ENOMEM;
40780
017d2877 40781@@ -1560,6 +1756,7 @@ static int acct_stack_growth(struct vm_a
2380c486
JR
40782 unsigned long limit;
40783 locked = mm->locked_vm + grow;
40784 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
40785+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
40786 if (locked > limit && !capable(CAP_IPC_LOCK))
40787 return -ENOMEM;
40788 }
017d2877 40789@@ -1595,35 +1792,40 @@ static
2380c486
JR
40790 #endif
40791 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
40792 {
40793- int error;
40794+ int error, locknext;
40795
40796 if (!(vma->vm_flags & VM_GROWSUP))
40797 return -EFAULT;
40798
40799+ /* Also guard against wrapping around to address 0. */
40800+ if (address < PAGE_ALIGN(address+1))
40801+ address = PAGE_ALIGN(address+1);
40802+ else
40803+ return -ENOMEM;
40804+
40805 /*
40806 * We must make sure the anon_vma is allocated
40807 * so that the anon_vma locking is not a noop.
40808 */
40809 if (unlikely(anon_vma_prepare(vma)))
40810 return -ENOMEM;
40811+ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
40812+ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
40813+ return -ENOMEM;
40814 anon_vma_lock(vma);
40815+ if (locknext)
40816+ anon_vma_lock(vma->vm_next);
40817
40818 /*
40819 * vma->vm_start/vm_end cannot change under us because the caller
40820 * is required to hold the mmap_sem in read mode. We need the
40821- * anon_vma lock to serialize against concurrent expand_stacks.
40822- * Also guard against wrapping around to address 0.
40823+ * anon_vma locks to serialize against concurrent expand_stacks
40824+ * and expand_upwards.
40825 */
40826- if (address < PAGE_ALIGN(address+4))
40827- address = PAGE_ALIGN(address+4);
40828- else {
40829- anon_vma_unlock(vma);
40830- return -ENOMEM;
40831- }
40832 error = 0;
40833
40834 /* Somebody else might have raced and expanded it already */
40835- if (address > vma->vm_end) {
40836+ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
40837 unsigned long size, grow;
40838
40839 size = address - vma->vm_start;
017d2877 40840@@ -1633,6 +1835,8 @@ int expand_upwards(struct vm_area_struct
2380c486
JR
40841 if (!error)
40842 vma->vm_end = address;
40843 }
40844+ if (locknext)
40845+ anon_vma_unlock(vma->vm_next);
40846 anon_vma_unlock(vma);
40847 return error;
40848 }
017d2877 40849@@ -1644,7 +1848,8 @@ int expand_upwards(struct vm_area_struct
2380c486
JR
40850 static int expand_downwards(struct vm_area_struct *vma,
40851 unsigned long address)
40852 {
40853- int error;
40854+ int error, lockprev = 0;
40855+ struct vm_area_struct *prev = NULL;
40856
40857 /*
40858 * We must make sure the anon_vma is allocated
017d2877 40859@@ -1658,6 +1863,15 @@ static int expand_downwards(struct vm_ar
2380c486
JR
40860 if (error)
40861 return error;
40862
40863+#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
40864+ find_vma_prev(vma->vm_mm, address, &prev);
40865+ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
40866+#endif
40867+ if (lockprev && unlikely(anon_vma_prepare(prev)))
40868+ return -ENOMEM;
40869+ if (lockprev)
40870+ anon_vma_lock(prev);
40871+
40872 anon_vma_lock(vma);
40873
40874 /*
017d2877 40875@@ -1667,9 +1881,15 @@ static int expand_downwards(struct vm_ar
2380c486
JR
40876 */
40877
40878 /* Somebody else might have raced and expanded it already */
40879- if (address < vma->vm_start) {
40880+ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
40881 unsigned long size, grow;
40882
40883+#ifdef CONFIG_PAX_SEGMEXEC
40884+ struct vm_area_struct *vma_m;
40885+
40886+ vma_m = pax_find_mirror_vma(vma);
40887+#endif
40888+
40889 size = vma->vm_end - address;
40890 grow = (vma->vm_start - address) >> PAGE_SHIFT;
40891
017d2877 40892@@ -1677,9 +1897,20 @@ static int expand_downwards(struct vm_ar
2380c486
JR
40893 if (!error) {
40894 vma->vm_start = address;
40895 vma->vm_pgoff -= grow;
40896+ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
40897+
40898+#ifdef CONFIG_PAX_SEGMEXEC
40899+ if (vma_m) {
40900+ vma_m->vm_start -= grow << PAGE_SHIFT;
40901+ vma_m->vm_pgoff -= grow;
40902+ }
40903+#endif
40904+
40905 }
40906 }
40907 anon_vma_unlock(vma);
40908+ if (lockprev)
40909+ anon_vma_unlock(prev);
40910 return error;
40911 }
017d2877
AM
40912
40913@@ -1988,6 +1988,13 @@
2380c486
JR
40914 do {
40915 long nrpages = vma_pages(vma);
40916
40917+#ifdef CONFIG_PAX_SEGMEXEC
017d2877
AM
40918+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
40919+ vma = remove_vma(vma);
40920+ continue;
40921+}
2380c486
JR
40922+#endif
40923+
017d2877
AM
40924 // mm->total_vm -= nrpages;
40925 vx_vmpages_sub(mm, nrpages);
2380c486 40926 vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
017d2877 40927@@ -1799,6 +2037,16 @@ detach_vmas_to_be_unmapped(struct mm_str
2380c486
JR
40928
40929 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
40930 do {
40931+
40932+#ifdef CONFIG_PAX_SEGMEXEC
40933+ if (vma->vm_mirror) {
40934+ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
40935+ vma->vm_mirror->vm_mirror = NULL;
40936+ vma->vm_mirror->vm_flags &= ~VM_EXEC;
40937+ vma->vm_mirror = NULL;
40938+ }
40939+#endif
40940+
40941 rb_erase(&vma->vm_rb, &mm->mm_rb);
40942 mm->map_count--;
40943 tail_vma = vma;
017d2877 40944@@ -1818,6 +2066,108 @@ detach_vmas_to_be_unmapped(struct mm_str
2380c486
JR
40945 * Split a vma into two pieces at address 'addr', a new vma is allocated
40946 * either for the first part or the tail.
40947 */
40948+
40949+#ifdef CONFIG_PAX_SEGMEXEC
40950+int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
40951+ unsigned long addr, int new_below)
40952+{
40953+ struct mempolicy *pol;
40954+ struct vm_area_struct *new, *vma_m, *new_m = NULL;
40955+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
40956+
40957+ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
40958+ return -EINVAL;
40959+
40960+ vma_m = pax_find_mirror_vma(vma);
40961+ if (vma_m) {
40962+ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
40963+ if (mm->map_count >= sysctl_max_map_count-1)
40964+ return -ENOMEM;
40965+ } else if (mm->map_count >= sysctl_max_map_count)
40966+ return -ENOMEM;
40967+
40968+ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
40969+ if (!new)
40970+ return -ENOMEM;
40971+
40972+ if (vma_m) {
40973+ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
40974+ if (!new_m) {
40975+ kmem_cache_free(vm_area_cachep, new);
40976+ return -ENOMEM;
40977+ }
40978+ }
40979+
40980+ /* most fields are the same, copy all, and then fixup */
40981+ *new = *vma;
40982+
40983+ if (new_below)
40984+ new->vm_end = addr;
40985+ else {
40986+ new->vm_start = addr;
40987+ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
40988+ }
40989+
40990+ if (vma_m) {
40991+ *new_m = *vma_m;
40992+ new_m->vm_mirror = new;
40993+ new->vm_mirror = new_m;
40994+
40995+ if (new_below)
40996+ new_m->vm_end = addr_m;
40997+ else {
40998+ new_m->vm_start = addr_m;
40999+ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
41000+ }
41001+ }
41002+
41003+ pol = mpol_dup(vma_policy(vma));
41004+ if (IS_ERR(pol)) {
41005+ if (new_m)
41006+ kmem_cache_free(vm_area_cachep, new_m);
41007+ kmem_cache_free(vm_area_cachep, new);
41008+ return PTR_ERR(pol);
41009+ }
41010+ vma_set_policy(new, pol);
41011+
41012+ if (new->vm_file) {
41013+ get_file(new->vm_file);
41014+ if (vma->vm_flags & VM_EXECUTABLE)
41015+ added_exe_file_vma(mm);
41016+ }
41017+
41018+ if (new->vm_ops && new->vm_ops->open)
41019+ new->vm_ops->open(new);
41020+
41021+ if (new_below)
41022+ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
41023+ ((addr - new->vm_start) >> PAGE_SHIFT), new);
41024+ else
41025+ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
41026+
41027+ if (vma_m) {
41028+ mpol_get(pol);
41029+ vma_set_policy(new_m, pol);
41030+
41031+ if (new_m->vm_file) {
41032+ get_file(new_m->vm_file);
41033+ if (vma_m->vm_flags & VM_EXECUTABLE)
41034+ added_exe_file_vma(mm);
41035+ }
41036+
41037+ if (new_m->vm_ops && new_m->vm_ops->open)
41038+ new_m->vm_ops->open(new_m);
41039+
41040+ if (new_below)
41041+ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
41042+ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
41043+ else
41044+ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
41045+ }
41046+
41047+ return 0;
41048+}
41049+#else
41050 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
41051 unsigned long addr, int new_below)
41052 {
017d2877 41053@@ -1869,17 +2219,37 @@ int split_vma(struct mm_struct * mm, str
2380c486
JR
41054
41055 return 0;
41056 }
41057+#endif
41058
41059 /* Munmap is split into 2 main parts -- this part which finds
41060 * what needs doing, and the areas themselves, which do the
41061 * work. This now handles partial unmappings.
41062 * Jeremy Fitzhardinge <jeremy@goop.org>
41063 */
41064+#ifdef CONFIG_PAX_SEGMEXEC
41065 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
41066 {
41067+ int ret = __do_munmap(mm, start, len);
41068+ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
41069+ return ret;
41070+
41071+ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
41072+}
41073+
41074+int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
41075+#else
41076+int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
41077+#endif
41078+{
41079 unsigned long end;
41080 struct vm_area_struct *vma, *prev, *last;
41081
41082+ /*
41083+ * mm->mmap_sem is required to protect against another thread
41084+ * changing the mappings in case we sleep.
41085+ */
41086+ verify_mm_writelocked(mm);
41087+
41088 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
41089 return -EINVAL;
41090
017d2877 41091@@ -1943,6 +2313,8 @@ int do_munmap(struct mm_struct *mm, unsi
2380c486
JR
41092 /* Fix up all other VM information */
41093 remove_vma_list(mm, vma);
41094
41095+ track_exec_limit(mm, start, end, 0UL);
41096+
41097 return 0;
41098 }
41099
017d2877 41100@@ -1955,22 +2327,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, a
2380c486
JR
41101
41102 profile_munmap(addr);
41103
41104+#ifdef CONFIG_PAX_SEGMEXEC
41105+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
41106+ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
41107+ return -EINVAL;
41108+#endif
41109+
41110 down_write(&mm->mmap_sem);
41111 ret = do_munmap(mm, addr, len);
41112 up_write(&mm->mmap_sem);
41113 return ret;
41114 }
41115
41116-static inline void verify_mm_writelocked(struct mm_struct *mm)
41117-{
41118-#ifdef CONFIG_DEBUG_VM
41119- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
41120- WARN_ON(1);
41121- up_read(&mm->mmap_sem);
41122- }
41123-#endif
41124-}
41125-
41126 /*
41127 * this is really a simplified "do_mmap". it only handles
41128 * anonymous maps. eventually we may be able to do some
017d2877 41129@@ -1984,6 +2352,11 @@ unsigned long do_brk(unsigned long addr,
2380c486
JR
41130 struct rb_node ** rb_link, * rb_parent;
41131 pgoff_t pgoff = addr >> PAGE_SHIFT;
41132 int error;
41133+ unsigned long charged;
41134+
41135+#ifdef CONFIG_PAX_SEGMEXEC
41136+ struct vm_area_struct *vma_m = NULL;
41137+#endif
41138
41139 len = PAGE_ALIGN(len);
41140 if (!len)
017d2877 41141@@ -2001,19 +2374,34 @@ unsigned long do_brk(unsigned long addr,
2380c486
JR
41142
41143 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
41144
41145+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
41146+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
41147+ flags &= ~VM_EXEC;
41148+
41149+#ifdef CONFIG_PAX_MPROTECT
41150+ if (mm->pax_flags & MF_PAX_MPROTECT)
41151+ flags &= ~VM_MAYEXEC;
41152+#endif
41153+
41154+ }
41155+#endif
41156+
41157 error = arch_mmap_check(addr, len, flags);
41158 if (error)
41159 return error;
41160
41161+ charged = len >> PAGE_SHIFT;
41162+
41163 /*
41164 * mlock MCL_FUTURE?
41165 */
41166 if (mm->def_flags & VM_LOCKED) {
41167 unsigned long locked, lock_limit;
41168- locked = len >> PAGE_SHIFT;
41169+ locked = charged;
41170 locked += mm->locked_vm;
41171 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
41172 lock_limit >>= PAGE_SHIFT;
41173+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
41174 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
41175 return -EAGAIN;
de855c5d 41176 }
017d2877 41177@@ -2421,23 +2421,23 @@
2380c486
JR
41178 /*
41179 * Clear old maps. this also does some error checking for us
41180 */
41181- munmap_back:
41182 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
41183 if (vma && vma->vm_start < addr + len) {
41184 if (do_munmap(mm, addr, len))
41185 return -ENOMEM;
41186- goto munmap_back;
41187+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
41188+ BUG_ON(vma && vma->vm_start < addr + len);
41189 }
41190
41191 /* Check against address space limits *after* clearing old maps... */
41192- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
41193+ if (!may_expand_vm(mm, charged))
41194 return -ENOMEM;
41195
41196 if (mm->map_count > sysctl_max_map_count)
41197 return -ENOMEM;
41198
017d2877
AM
41199- if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
41200- !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
41201+ if (security_vm_enough_memory(charged) ||
41202+ !vx_vmpages_avail(mm, charged))
2380c486
JR
41203 return -ENOMEM;
41204
41205 /* Can we just expand an old private anonymous mapping? */
017d2877 41206@@ -2056,10 +2444,21 @@ unsigned long do_brk(unsigned long addr,
2380c486
JR
41207 */
41208 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
41209 if (!vma) {
41210- vm_unacct_memory(len >> PAGE_SHIFT);
41211+ vm_unacct_memory(charged);
41212 return -ENOMEM;
41213 }
41214
41215+#ifdef CONFIG_PAX_SEGMEXEC
41216+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
41217+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
41218+ if (!vma_m) {
41219+ kmem_cache_free(vm_area_cachep, vma);
41220+ vm_unacct_memory(charged);
41221+ return -ENOMEM;
41222+ }
41223+ }
41224+#endif
41225+
41226 vma->vm_mm = mm;
41227 vma->vm_start = addr;
41228 vma->vm_end = addr + len;
017d2877 41229@@ -2474,14 +2474,15 @@
de855c5d 41230 vma->vm_page_prot = vm_get_page_prot(flags);
2380c486
JR
41231 vma_link(mm, vma, prev, rb_link, rb_parent);
41232 out:
017d2877
AM
41233- // mm->total_vm += len >> PAGE_SHIFT;
41234- vx_vmpages_add(mm, len >> PAGE_SHIFT);
41235+ // mm->total_vm += charged;
41236+ vx_vmpages_add(mm, charged);
41237
2380c486
JR
41238 if (flags & VM_LOCKED) {
41239 if (!mlock_vma_pages_range(vma, addr, addr + len))
017d2877
AM
41240- // mm->locked_vm += (len >> PAGE_SHIFT);
41241- vx_vmlocked_add(mm, len >> PAGE_SHIFT);
41242+ // mm->locked_vm += (charged);
41243+ vx_vmlocked_add(mm, charged);
2380c486
JR
41244 }
41245+ track_exec_limit(mm, addr, addr + len, flags);
41246 return addr;
41247 }
41248
017d2877 41249@@ -2118,8 +2518,10 @@ void exit_mmap(struct mm_struct *mm)
2380c486
JR
41250 * Walk the list again, actually closing and freeing it,
41251 * with preemption enabled, without holding any MM locks.
41252 */
41253- while (vma)
41254+ while (vma) {
41255+ vma->vm_mirror = NULL;
41256 vma = remove_vma(vma);
41257+ }
41258
41259 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
41260 }
017d2877 41261@@ -2133,6 +2535,10 @@ int insert_vm_struct(struct mm_struct *
2380c486
JR
41262 struct vm_area_struct * __vma, * prev;
41263 struct rb_node ** rb_link, * rb_parent;
41264
41265+#ifdef CONFIG_PAX_SEGMEXEC
41266+ struct vm_area_struct *vma_m = NULL;
41267+#endif
41268+
41269 /*
41270 * The vm_pgoff of a purely anonymous vma should be irrelevant
41271 * until its first write fault, when page's anon_vma and index
017d2877 41272@@ -2155,7 +2561,22 @@ int insert_vm_struct(struct mm_struct *
de855c5d
AM
41273 if ((vma->vm_flags & VM_ACCOUNT) &&
41274 security_vm_enough_memory_mm(mm, vma_pages(vma)))
2380c486
JR
41275 return -ENOMEM;
41276+
41277+#ifdef CONFIG_PAX_SEGMEXEC
41278+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
41279+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
41280+ if (!vma_m)
41281+ return -ENOMEM;
41282+ }
41283+#endif
41284+
41285 vma_link(mm, vma, prev, rb_link, rb_parent);
41286+
41287+#ifdef CONFIG_PAX_SEGMEXEC
41288+ if (vma_m)
41289+ pax_mirror_vma(vma_m, vma);
41290+#endif
41291+
41292 return 0;
41293 }
41294
017d2877 41295@@ -2173,6 +2594,8 @@ struct vm_area_struct *copy_vma(struct v
2380c486
JR
41296 struct rb_node **rb_link, *rb_parent;
41297 struct mempolicy *pol;
41298
41299+ BUG_ON(vma->vm_mirror);
41300+
41301 /*
41302 * If anonymous vma has not yet been faulted, update new pgoff
41303 * to match new location, to increase its chance of merging.
017d2877 41304@@ -2216,6 +2639,35 @@ struct vm_area_struct *copy_vma(struct v
2380c486
JR
41305 return new_vma;
41306 }
41307
41308+#ifdef CONFIG_PAX_SEGMEXEC
41309+void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
41310+{
41311+ struct vm_area_struct *prev_m;
41312+ struct rb_node **rb_link_m, *rb_parent_m;
41313+ struct mempolicy *pol_m;
41314+
41315+ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
41316+ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
41317+ BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
41318+ *vma_m = *vma;
41319+ pol_m = vma_policy(vma_m);
41320+ mpol_get(pol_m);
41321+ vma_set_policy(vma_m, pol_m);
41322+ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
41323+ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
41324+ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
41325+ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
41326+ if (vma_m->vm_file)
41327+ get_file(vma_m->vm_file);
41328+ if (vma_m->vm_ops && vma_m->vm_ops->open)
41329+ vma_m->vm_ops->open(vma_m);
41330+ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
41331+ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
41332+ vma_m->vm_mirror = vma;
41333+ vma->vm_mirror = vma_m;
41334+}
41335+#endif
41336+
41337 /*
41338 * Return true if the calling process may expand its vm space by the passed
41339 * number of pages
017d2877 41340@@ -2226,7 +2678,7 @@ int may_expand_vm(struct mm_struct *mm,
2380c486
JR
41341 unsigned long lim;
41342
41343 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
41344-
41345+ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
41346 if (cur + npages > lim)
41347 return 0;
de855c5d 41348 return 1;
017d2877
AM
41349@@ -2267,7 +2719,7 @@ static void special_mapping_close(struct
41350 {
41351 }
41352
41353-static struct vm_operations_struct special_mapping_vmops = {
41354+static const struct vm_operations_struct special_mapping_vmops = {
41355 .close = special_mapping_close,
41356 .fault = special_mapping_fault,
41357 };
41358@@ -2295,6 +2747,15 @@ int install_special_mapping(struct mm_st
2380c486
JR
41359 vma->vm_start = addr;
41360 vma->vm_end = addr + len;
41361
41362+#ifdef CONFIG_PAX_MPROTECT
41363+ if (mm->pax_flags & MF_PAX_MPROTECT) {
41364+ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
41365+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
41366+ else
41367+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
41368+ }
41369+#endif
41370+
41371 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
41372 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
41373
017d2877
AM
41374diff -urNp linux-2.6.30.4/mm/mprotect.c linux-2.6.30.4/mm/mprotect.c
41375--- linux-2.6.30.4/mm/mprotect.c 2009-07-24 17:47:51.000000000 -0400
41376+++ linux-2.6.30.4/mm/mprotect.c 2009-07-30 11:10:49.815552001 -0400
2380c486
JR
41377@@ -23,10 +23,16 @@
41378 #include <linux/swapops.h>
41379 #include <linux/mmu_notifier.h>
41380 #include <linux/migrate.h>
41381+
41382+#ifdef CONFIG_PAX_MPROTECT
41383+#include <linux/elf.h>
41384+#endif
41385+
41386 #include <asm/uaccess.h>
41387 #include <asm/pgtable.h>
41388 #include <asm/cacheflush.h>
41389 #include <asm/tlbflush.h>
41390+#include <asm/mmu_context.h>
41391
41392 #ifndef pgprot_modify
41393 static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
41394@@ -131,6 +137,48 @@ static void change_protection(struct vm_
41395 flush_tlb_range(vma, start, end);
41396 }
41397
41398+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
41399+/* called while holding the mmap semaphor for writing except stack expansion */
41400+void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
41401+{
41402+ unsigned long oldlimit, newlimit = 0UL;
41403+
41404+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
41405+ return;
41406+
41407+ spin_lock(&mm->page_table_lock);
41408+ oldlimit = mm->context.user_cs_limit;
41409+ if ((prot & VM_EXEC) && oldlimit < end)
41410+ /* USER_CS limit moved up */
41411+ newlimit = end;
41412+ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
41413+ /* USER_CS limit moved down */
41414+ newlimit = start;
41415+
41416+ if (newlimit) {
41417+ mm->context.user_cs_limit = newlimit;
41418+
41419+#ifdef CONFIG_SMP
41420+ wmb();
41421+ cpus_clear(mm->context.cpu_user_cs_mask);
41422+ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
41423+#endif
41424+
41425+ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
41426+ }
41427+ spin_unlock(&mm->page_table_lock);
41428+ if (newlimit == end) {
41429+ struct vm_area_struct *vma = find_vma(mm, oldlimit);
41430+
41431+ for (; vma && vma->vm_start < end; vma = vma->vm_next)
41432+ if (is_vm_hugetlb_page(vma))
41433+ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
41434+ else
41435+ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
41436+ }
41437+}
41438+#endif
41439+
41440 int
41441 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
41442 unsigned long start, unsigned long end, unsigned long newflags)
41443@@ -143,6 +191,14 @@ mprotect_fixup(struct vm_area_struct *vm
41444 int error;
41445 int dirty_accountable = 0;
41446
41447+#ifdef CONFIG_PAX_SEGMEXEC
41448+ struct vm_area_struct *vma_m = NULL;
41449+ unsigned long start_m, end_m;
41450+
41451+ start_m = start + SEGMEXEC_TASK_SIZE;
41452+ end_m = end + SEGMEXEC_TASK_SIZE;
41453+#endif
41454+
41455 if (newflags == oldflags) {
41456 *pprev = vma;
41457 return 0;
41458@@ -164,6 +220,38 @@ mprotect_fixup(struct vm_area_struct *vm
41459 }
41460 }
41461
41462+#ifdef CONFIG_PAX_SEGMEXEC
41463+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
41464+ if (start != vma->vm_start) {
41465+ error = split_vma(mm, vma, start, 1);
41466+ if (error)
41467+ goto fail;
41468+ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
41469+ *pprev = (*pprev)->vm_next;
41470+ }
41471+
41472+ if (end != vma->vm_end) {
41473+ error = split_vma(mm, vma, end, 0);
41474+ if (error)
41475+ goto fail;
41476+ }
41477+
41478+ if (pax_find_mirror_vma(vma)) {
41479+ error = __do_munmap(mm, start_m, end_m - start_m);
41480+ if (error)
41481+ goto fail;
41482+ } else {
41483+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
41484+ if (!vma_m) {
41485+ error = -ENOMEM;
41486+ goto fail;
41487+ }
41488+ vma->vm_flags = newflags;
41489+ pax_mirror_vma(vma_m, vma);
41490+ }
41491+ }
41492+#endif
41493+
41494 /*
41495 * First try to merge with previous and/or next vma.
41496 */
41497@@ -195,8 +283,14 @@ success:
41498 * held in write mode.
41499 */
41500 vma->vm_flags = newflags;
41501+
41502+#ifdef CONFIG_PAX_MPROTECT
41503+ if (current->binfmt && current->binfmt->handle_mprotect)
41504+ current->binfmt->handle_mprotect(vma, newflags);
41505+#endif
41506+
41507 vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
41508- vm_get_page_prot(newflags));
41509+ vm_get_page_prot(vma->vm_flags));
41510
41511 if (vma_wants_writenotify(vma)) {
41512 vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
41513@@ -237,6 +331,17 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
41514 end = start + len;
41515 if (end <= start)
41516 return -ENOMEM;
41517+
41518+#ifdef CONFIG_PAX_SEGMEXEC
41519+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
41520+ if (end > SEGMEXEC_TASK_SIZE)
41521+ return -EINVAL;
41522+ } else
41523+#endif
41524+
41525+ if (end > TASK_SIZE)
41526+ return -EINVAL;
41527+
41528 if (!arch_validate_prot(prot))
41529 return -EINVAL;
41530
41531@@ -244,7 +349,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
41532 /*
41533 * Does the application expect PROT_READ to imply PROT_EXEC:
41534 */
41535- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
41536+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
41537 prot |= PROT_EXEC;
41538
41539 vm_flags = calc_vm_prot_bits(prot);
41540@@ -276,6 +381,16 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
41541 if (start > vma->vm_start)
41542 prev = vma;
41543
41544+ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
41545+ error = -EACCES;
41546+ goto out;
41547+ }
41548+
41549+#ifdef CONFIG_PAX_MPROTECT
41550+ if (current->binfmt && current->binfmt->handle_mprotect)
41551+ current->binfmt->handle_mprotect(vma, vm_flags);
41552+#endif
41553+
41554 for (nstart = start ; ; ) {
41555 unsigned long newflags;
41556
41557@@ -299,6 +414,9 @@ SYSCALL_DEFINE3(mprotect, unsigned long,
41558 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
41559 if (error)
41560 goto out;
41561+
41562+ track_exec_limit(current->mm, nstart, tmp, vm_flags);
41563+
41564 nstart = tmp;
41565
41566 if (nstart < prev->vm_end)
017d2877
AM
41567diff -urNp linux-2.6.30.4/mm/mremap.c linux-2.6.30.4/mm/mremap.c
41568--- linux-2.6.30.4/mm/mremap.c 2009-07-24 17:47:51.000000000 -0400
41569+++ linux-2.6.30.4/mm/mremap.c 2009-07-30 09:48:10.147955205 -0400
2380c486
JR
41570@@ -113,6 +113,12 @@ static void move_ptes(struct vm_area_str
41571 continue;
41572 pte = ptep_clear_flush(vma, old_addr, old_pte);
41573 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
41574+
41575+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
41576+ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
41577+ pte = pte_exprotect(pte);
41578+#endif
41579+
41580 set_pte_at(mm, new_addr, new_pte, pte);
41581 }
41582
41583@@ -262,6 +268,7 @@ unsigned long do_mremap(unsigned long ad
41584 struct vm_area_struct *vma;
41585 unsigned long ret = -EINVAL;
41586 unsigned long charged = 0;
41587+ unsigned long pax_task_size = TASK_SIZE;
41588
41589 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
41590 goto out;
41591@@ -280,6 +287,15 @@ unsigned long do_mremap(unsigned long ad
41592 if (!new_len)
41593 goto out;
41594
41595+#ifdef CONFIG_PAX_SEGMEXEC
41596+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
41597+ pax_task_size = SEGMEXEC_TASK_SIZE;
41598+#endif
41599+
41600+ if (new_len > pax_task_size || addr > pax_task_size-new_len ||
41601+ old_len > pax_task_size || addr > pax_task_size-old_len)
41602+ goto out;
41603+
41604 /* new_addr is only valid if MREMAP_FIXED is specified */
41605 if (flags & MREMAP_FIXED) {
41606 if (new_addr & ~PAGE_MASK)
41607@@ -287,16 +303,13 @@ unsigned long do_mremap(unsigned long ad
41608 if (!(flags & MREMAP_MAYMOVE))
41609 goto out;
41610
41611- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
41612+ if (new_addr > pax_task_size - new_len)
41613 goto out;
41614
41615 /* Check if the location we're moving into overlaps the
41616 * old location at all, and fail if it does.
41617 */
41618- if ((new_addr <= addr) && (new_addr+new_len) > addr)
41619- goto out;
41620-
41621- if ((addr <= new_addr) && (addr+old_len) > new_addr)
41622+ if (addr + old_len > new_addr && new_addr + new_len > addr)
41623 goto out;
41624
41625 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
41626@@ -334,6 +347,14 @@ unsigned long do_mremap(unsigned long ad
41627 ret = -EINVAL;
41628 goto out;
41629 }
41630+
41631+#ifdef CONFIG_PAX_SEGMEXEC
41632+ if (pax_find_mirror_vma(vma)) {
41633+ ret = -EINVAL;
41634+ goto out;
41635+ }
41636+#endif
41637+
41638 /* We can't remap across vm area boundaries */
41639 if (old_len > vma->vm_end - addr)
41640 goto out;
41641@@ -367,7 +388,7 @@ unsigned long do_mremap(unsigned long ad
41642 if (old_len == vma->vm_end - addr &&
41643 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
41644 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
41645- unsigned long max_addr = TASK_SIZE;
41646+ unsigned long max_addr = pax_task_size;
41647 if (vma->vm_next)
41648 max_addr = vma->vm_next->vm_start;
41649 /* can we just expand the current mapping? */
41650@@ -385,6 +406,7 @@ unsigned long do_mremap(unsigned long ad
41651 addr + new_len);
41652 }
41653 ret = addr;
41654+ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
41655 goto out;
41656 }
41657 }
41658@@ -395,8 +417,8 @@ unsigned long do_mremap(unsigned long ad
41659 */
41660 ret = -ENOMEM;
41661 if (flags & MREMAP_MAYMOVE) {
41662+ unsigned long map_flags = 0;
41663 if (!(flags & MREMAP_FIXED)) {
41664- unsigned long map_flags = 0;
41665 if (vma->vm_flags & VM_MAYSHARE)
41666 map_flags |= MAP_SHARED;
41667
41668@@ -411,7 +433,12 @@ unsigned long do_mremap(unsigned long ad
41669 if (ret)
41670 goto out;
41671 }
41672+ map_flags = vma->vm_flags;
41673 ret = move_vma(vma, addr, old_len, new_len, new_addr);
41674+ if (!(ret & ~PAGE_MASK)) {
41675+ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
41676+ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
41677+ }
41678 }
41679 out:
41680 if (ret & ~PAGE_MASK)
017d2877
AM
41681diff -urNp linux-2.6.30.4/mm/nommu.c linux-2.6.30.4/mm/nommu.c
41682--- linux-2.6.30.4/mm/nommu.c 2009-07-30 20:32:40.555603021 -0400
41683+++ linux-2.6.30.4/mm/nommu.c 2009-07-30 20:32:48.097607328 -0400
41684@@ -82,7 +82,7 @@ static struct kmem_cache *vm_region_jar;
41685 struct rb_root nommu_region_tree = RB_ROOT;
41686 DECLARE_RWSEM(nommu_region_sem);
41687
41688-struct vm_operations_struct generic_file_vm_ops = {
41689+const struct vm_operations_struct generic_file_vm_ops = {
41690 };
41691
41692 /*
41693@@ -764,15 +764,6 @@ struct vm_area_struct *find_vma(struct m
2380c486
JR
41694 EXPORT_SYMBOL(find_vma);
41695
41696 /*
41697- * find a VMA
41698- * - we don't extend stack VMAs under NOMMU conditions
41699- */
41700-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
41701-{
41702- return find_vma(mm, addr);
41703-}
41704-
41705-/*
41706 * expand a stack to a given address
41707 * - not supported under NOMMU conditions
41708 */
017d2877
AM
41709diff -urNp linux-2.6.30.4/mm/page_alloc.c linux-2.6.30.4/mm/page_alloc.c
41710--- linux-2.6.30.4/mm/page_alloc.c 2009-07-30 20:32:40.556595558 -0400
41711+++ linux-2.6.30.4/mm/page_alloc.c 2009-07-30 20:32:48.098681549 -0400
2380c486
JR
41712@@ -549,6 +549,10 @@ static void __free_pages_ok(struct page
41713 int i;
41714 int bad = 0;
41715
41716+#ifdef CONFIG_PAX_MEMORY_SANITIZE
41717+ unsigned long index = 1UL << order;
41718+#endif
41719+
41720 for (i = 0 ; i < (1 << order) ; ++i)
41721 bad += free_pages_check(page + i);
41722 if (bad)
41723@@ -559,6 +563,12 @@ static void __free_pages_ok(struct page
41724 debug_check_no_obj_freed(page_address(page),
41725 PAGE_SIZE << order);
41726 }
41727+
41728+#ifdef CONFIG_PAX_MEMORY_SANITIZE
41729+ for (; index; --index)
41730+ sanitize_highpage(page + index - 1);
41731+#endif
41732+
41733 arch_free_page(page, order);
41734 kernel_map_pages(page, 1 << order, 0);
41735
41736@@ -647,8 +657,10 @@ static int prep_new_page(struct page *pa
41737 arch_alloc_page(page, order);
41738 kernel_map_pages(page, 1 << order, 1);
41739
41740+#ifndef CONFIG_PAX_MEMORY_SANITIZE
41741 if (gfp_flags & __GFP_ZERO)
41742 prep_zero_page(page, order, gfp_flags);
41743+#endif
41744
41745 if (order && (gfp_flags & __GFP_COMP))
41746 prep_compound_page(page, order);
017d2877 41747@@ -1006,6 +1018,11 @@ static void free_hot_cold_page(struct pa
2380c486
JR
41748 debug_check_no_locks_freed(page_address(page), PAGE_SIZE);
41749 debug_check_no_obj_freed(page_address(page), PAGE_SIZE);
41750 }
41751+
41752+#ifdef CONFIG_PAX_MEMORY_SANITIZE
41753+ sanitize_highpage(page);
41754+#endif
41755+
41756 arch_free_page(page, 0);
41757 kernel_map_pages(page, 1, 0);
41758
017d2877
AM
41759diff -urNp linux-2.6.30.4/mm/percpu.c linux-2.6.30.4/mm/percpu.c
41760--- linux-2.6.30.4/mm/percpu.c 2009-07-24 17:47:51.000000000 -0400
41761+++ linux-2.6.30.4/mm/percpu.c 2009-07-30 09:48:10.149665939 -0400
41762@@ -107,7 +107,7 @@ static int pcpu_nr_slots __read_mostly;
41763 static size_t pcpu_chunk_struct_size __read_mostly;
41764
41765 /* the address of the first chunk which starts with the kernel static area */
41766-void *pcpu_base_addr __read_mostly;
41767+void *pcpu_base_addr __read_only;
41768 EXPORT_SYMBOL_GPL(pcpu_base_addr);
41769
41770 /* optional reserved chunk, only accessible for reserved allocations */
41771diff -urNp linux-2.6.30.4/mm/rmap.c linux-2.6.30.4/mm/rmap.c
41772--- linux-2.6.30.4/mm/rmap.c 2009-07-24 17:47:51.000000000 -0400
41773+++ linux-2.6.30.4/mm/rmap.c 2009-07-30 09:48:10.149665939 -0400
2380c486
JR
41774@@ -103,6 +103,10 @@ int anon_vma_prepare(struct vm_area_stru
41775 struct mm_struct *mm = vma->vm_mm;
41776 struct anon_vma *allocated;
41777
41778+#ifdef CONFIG_PAX_SEGMEXEC
41779+ struct vm_area_struct *vma_m;
41780+#endif
41781+
41782 anon_vma = find_mergeable_anon_vma(vma);
41783 allocated = NULL;
41784 if (!anon_vma) {
41785@@ -116,6 +120,15 @@ int anon_vma_prepare(struct vm_area_stru
41786 /* page_table_lock to protect against threads */
41787 spin_lock(&mm->page_table_lock);
41788 if (likely(!vma->anon_vma)) {
41789+
41790+#ifdef CONFIG_PAX_SEGMEXEC
41791+ vma_m = pax_find_mirror_vma(vma);
41792+ if (vma_m) {
41793+ vma_m->anon_vma = anon_vma;
41794+ __anon_vma_link(vma_m);
41795+ }
41796+#endif
41797+
41798 vma->anon_vma = anon_vma;
41799 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
41800 allocated = NULL;
017d2877
AM
41801diff -urNp linux-2.6.30.4/mm/shmem.c linux-2.6.30.4/mm/shmem.c
41802--- linux-2.6.30.4/mm/shmem.c 2009-07-24 17:47:51.000000000 -0400
41803+++ linux-2.6.30.4/mm/shmem.c 2009-07-30 11:10:49.822549311 -0400
41804@@ -31,7 +31,7 @@
2380c486 41805 #include <linux/swap.h>
017d2877 41806 #include <linux/ima.h>
2380c486
JR
41807
41808-static struct vfsmount *shm_mnt;
41809+struct vfsmount *shm_mnt;
41810
41811 #ifdef CONFIG_SHMEM
41812 /*
017d2877
AM
41813@@ -219,7 +219,7 @@ static const struct file_operations shme
41814 static const struct inode_operations shmem_inode_operations;
41815 static const struct inode_operations shmem_dir_inode_operations;
41816 static const struct inode_operations shmem_special_inode_operations;
41817-static struct vm_operations_struct shmem_vm_ops;
41818+static const struct vm_operations_struct shmem_vm_ops;
41819
41820 static struct backing_dev_info shmem_backing_dev_info __read_mostly = {
41821 .ra_pages = 0, /* No readahead */
41822@@ -2501,7 +2501,7 @@ static const struct super_operations shm
41823 .put_super = shmem_put_super,
41824 };
41825
41826-static struct vm_operations_struct shmem_vm_ops = {
41827+static const struct vm_operations_struct shmem_vm_ops = {
41828 .fault = shmem_fault,
41829 #ifdef CONFIG_NUMA
41830 .set_policy = shmem_set_policy,
41831diff -urNp linux-2.6.30.4/mm/slab.c linux-2.6.30.4/mm/slab.c
41832--- linux-2.6.30.4/mm/slab.c 2009-07-30 20:32:40.559581250 -0400
41833+++ linux-2.6.30.4/mm/slab.c 2009-07-30 20:32:48.099850445 -0400
41834@@ -306,7 +306,7 @@ struct kmem_list3 {
2380c486
JR
41835 * Need this for bootstrapping a per node allocator.
41836 */
41837 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
41838-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
41839+struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
41840 #define CACHE_CACHE 0
41841 #define SIZE_AC MAX_NUMNODES
41842 #define SIZE_L3 (2 * MAX_NUMNODES)
017d2877 41843@@ -637,7 +637,7 @@ static inline void *index_to_obj(struct
de855c5d
AM
41844 * reciprocal_divide(offset, cache->reciprocal_buffer_size)
41845 */
41846 static inline unsigned int obj_to_index(const struct kmem_cache *cache,
41847- const struct slab *slab, void *obj)
41848+ const struct slab *slab, const void *obj)
41849 {
41850 u32 offset = (obj - slab->s_mem);
41851 return reciprocal_divide(offset, cache->reciprocal_buffer_size);
017d2877 41852@@ -663,14 +663,14 @@ struct cache_names {
2380c486
JR
41853 static struct cache_names __initdata cache_names[] = {
41854 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
41855 #include <linux/kmalloc_sizes.h>
41856- {NULL,}
41857+ {NULL, NULL}
41858 #undef CACHE
41859 };
41860
41861 static struct arraycache_init initarray_cache __initdata =
41862- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
41863+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
41864 static struct arraycache_init initarray_generic =
41865- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
41866+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
41867
41868 /* internal cache of cache description objs */
41869 static struct kmem_cache cache_cache = {
017d2877 41870@@ -4486,15 +4486,64 @@ static const struct file_operations proc
2380c486
JR
41871
41872 static int __init slab_proc_init(void)
41873 {
41874+#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
41875 proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
41876 #ifdef CONFIG_DEBUG_SLAB_LEAK
41877 proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
41878 #endif
41879+#endif
41880 return 0;
41881 }
41882 module_init(slab_proc_init);
de855c5d
AM
41883 #endif
41884
41885+void check_object_size(const void *ptr, unsigned long n, bool to)
41886+{
41887+
41888+#ifdef CONFIG_PAX_USERCOPY
41889+ struct kmem_cache *cachep;
41890+ struct slab *slabp;
41891+ struct page *page;
41892+ unsigned int objnr;
41893+ unsigned long offset;
41894+
41895+ if (!n)
41896+ return;
41897+
41898+ if (ZERO_OR_NULL_PTR(ptr))
41899+ goto report;
41900+
41901+ if (!virt_addr_valid(ptr))
41902+ return;
41903+
41904+ page = virt_to_head_page(ptr);
41905+
017d2877
AM
41906+ /* XXX: can get a little tighter with this stack check */
41907+ if (!PageSlab(page) && object_is_on_stack(ptr) &&
41908+ (n > ((unsigned long)task_stack_page(current) + THREAD_SIZE -
41909+ (unsigned long)ptr)))
41910+ goto report;
41911+ else
de855c5d
AM
41912+ return;
41913+
41914+ cachep = page_get_cache(page);
41915+ slabp = page_get_slab(page);
41916+ objnr = obj_to_index(cachep, slabp, ptr);
41917+ BUG_ON(objnr >= cachep->num);
41918+ offset = ptr - index_to_obj(cachep, slabp, objnr) - obj_offset(cachep);
41919+ if (offset <= obj_size(cachep) && n <= obj_size(cachep) - offset)
41920+ return;
41921+
41922+report:
41923+ if (to)
41924+ pax_report_leak_to_user(ptr, n);
41925+ else
41926+ pax_report_overflow_from_user(ptr, n);
41927+#endif
41928+
41929+}
41930+EXPORT_SYMBOL(check_object_size);
41931+
41932 /**
41933 * ksize - get the actual amount of memory allocated for a given object
41934 * @objp: Pointer to the object
017d2877
AM
41935diff -urNp linux-2.6.30.4/mm/slob.c linux-2.6.30.4/mm/slob.c
41936--- linux-2.6.30.4/mm/slob.c 2009-07-30 20:32:40.560667928 -0400
41937+++ linux-2.6.30.4/mm/slob.c 2009-07-30 20:32:48.100694054 -0400
de855c5d
AM
41938@@ -29,7 +29,7 @@
41939 * If kmalloc is asked for objects of PAGE_SIZE or larger, it calls
41940 * alloc_pages() directly, allocating compound pages so the page order
41941 * does not have to be separately tracked, and also stores the exact
41942- * allocation size in page->private so that it can be used to accurately
41943+ * allocation size in slob_page->size so that it can be used to accurately
41944 * provide ksize(). These objects are detected in kfree() because slob_page()
41945 * is false for them.
41946 *
41947@@ -58,6 +58,7 @@
41948 */
41949
41950 #include <linux/kernel.h>
41951+#include <linux/sched.h>
41952 #include <linux/slab.h>
41953 #include <linux/mm.h>
017d2877
AM
41954 #include <linux/swap.h> /* struct reclaim_state */
41955@@ -99,7 +100,8 @@ struct slob_page {
de855c5d
AM
41956 unsigned long flags; /* mandatory */
41957 atomic_t _count; /* mandatory */
41958 slobidx_t units; /* free units left in page */
41959- unsigned long pad[2];
41960+ unsigned long pad[1];
41961+ unsigned long size; /* size when >=PAGE_SIZE */
41962 slob_t *free; /* first free slob_t in page */
41963 struct list_head list; /* linked list of free pages */
41964 };
017d2877 41965@@ -132,7 +134,7 @@ static LIST_HEAD(free_slob_large);
de855c5d 41966 */
017d2877 41967 static inline int is_slob_page(struct slob_page *sp)
de855c5d
AM
41968 {
41969- return PageSlobPage((struct page *)sp);
41970+ return PageSlobPage((struct page *)sp) && !sp->size;
41971 }
41972
41973 static inline void set_slob_page(struct slob_page *sp)
017d2877 41974@@ -207,7 +209,7 @@ static void set_slob(slob_t *s, slobidx_
de855c5d
AM
41975 /*
41976 * Return the size of a slob block.
41977 */
41978-static slobidx_t slob_units(slob_t *s)
41979+static slobidx_t slob_units(const slob_t *s)
41980 {
41981 if (s->units > 0)
41982 return s->units;
017d2877 41983@@ -217,7 +219,7 @@ static slobidx_t slob_units(slob_t *s)
de855c5d
AM
41984 /*
41985 * Return the next free slob block pointer after this one.
41986 */
41987-static slob_t *slob_next(slob_t *s)
41988+static slob_t *slob_next(const slob_t *s)
41989 {
41990 slob_t *base = (slob_t *)((unsigned long)s & PAGE_MASK);
41991 slobidx_t next;
017d2877 41992@@ -232,7 +234,7 @@ static slob_t *slob_next(slob_t *s)
de855c5d
AM
41993 /*
41994 * Returns true if s is the last free block in its page.
41995 */
41996-static int slob_last(slob_t *s)
41997+static int slob_last(const slob_t *s)
41998 {
41999 return !((unsigned long)slob_next(s) & ~PAGE_MASK);
42000 }
017d2877 42001@@ -251,6 +253,7 @@ static void *slob_new_pages(gfp_t gfp, i
de855c5d
AM
42002 if (!page)
42003 return NULL;
42004
42005+ set_slob_page(page);
42006 return page_address(page);
42007 }
42008
017d2877 42009@@ -367,11 +370,11 @@ static void *slob_alloc(size_t size, gfp
de855c5d 42010 if (!b)
017d2877
AM
42011 return NULL;
42012 sp = slob_page(b);
de855c5d
AM
42013- set_slob_page(sp);
42014
42015 spin_lock_irqsave(&slob_lock, flags);
42016 sp->units = SLOB_UNITS(PAGE_SIZE);
42017 sp->free = b;
42018+ sp->size = 0;
42019 INIT_LIST_HEAD(&sp->list);
42020 set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
42021 set_slob_page_free(sp, slob_list);
017d2877 42022@@ -474,10 +477,9 @@ out:
de855c5d
AM
42023 #define ARCH_SLAB_MINALIGN __alignof__(unsigned long)
42024 #endif
42025
42026-void *__kmalloc_node(size_t size, gfp_t gfp, int node)
42027+static void *__kmalloc_node_align(size_t size, gfp_t gfp, int node, int align)
42028 {
42029- unsigned int *m;
42030- int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
42031+ slob_t *m;
017d2877
AM
42032 void *ret;
42033
42034 lockdep_trace_alloc(gfp);
42035@@ -490,7 +492,10 @@ void *__kmalloc_node(size_t size, gfp_t
de855c5d 42036
de855c5d
AM
42037 if (!m)
42038 return NULL;
42039- *m = size;
42040+ BUILD_BUG_ON(ARCH_KMALLOC_MINALIGN < 2 * SLOB_UNIT);
42041+ BUILD_BUG_ON(ARCH_SLAB_MINALIGN < 2 * SLOB_UNIT);
42042+ m[0].units = size;
42043+ m[1].units = align;
017d2877 42044 ret = (void *)m + align;
de855c5d 42045
017d2877
AM
42046 trace_kmalloc_node(_RET_IP_, ret,
42047@@ -500,9 +505,9 @@ void *__kmalloc_node(size_t size, gfp_t
42048
42049 ret = slob_new_pages(gfp | __GFP_COMP, get_order(size), node);
de855c5d
AM
42050 if (ret) {
42051- struct page *page;
42052- page = virt_to_page(ret);
42053- page->private = size;
42054+ struct slob_page *sp;
42055+ sp = (struct slob_page *)virt_to_head_page(ret);
42056+ sp->size = size;
42057 }
017d2877
AM
42058
42059 trace_kmalloc_node(_RET_IP_, ret,
42060@@ -511,6 +516,13 @@ void *__kmalloc_node(size_t size, gfp_t
42061
42062 return ret;
de855c5d
AM
42063 }
42064+
42065+void *__kmalloc_node(size_t size, gfp_t gfp, int node)
42066+{
42067+ int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
42068+
42069+ return __kmalloc_node_align(size, gfp, node, align);
42070+}
42071 EXPORT_SYMBOL(__kmalloc_node);
42072
42073 void kfree(const void *block)
017d2877
AM
42074@@ -525,13 +537,86 @@ void kfree(const void *block)
42075 sp = slob_page(block);
42076 if (is_slob_page(sp)) {
de855c5d
AM
42077 int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
42078- unsigned int *m = (unsigned int *)(block - align);
42079- slob_free(m, *m + align);
42080- } else
42081+ slob_t *m = (slob_t *)(block - align);
42082+ slob_free(m, m[0].units + align);
42083+ } else {
42084+ clear_slob_page(sp);
42085+ free_slob_page(sp);
42086+ sp->size = 0;
42087 put_page(&sp->page);
42088+ }
42089 }
42090 EXPORT_SYMBOL(kfree);
42091
42092+void check_object_size(const void *ptr, unsigned long n, bool to)
42093+{
42094+
42095+#ifdef CONFIG_PAX_USERCOPY
42096+ struct slob_page *sp;
42097+ const slob_t *free;
42098+ const void *base;
42099+
42100+ if (!n)
42101+ return;
42102+
42103+ if (ZERO_OR_NULL_PTR(ptr))
42104+ goto report;
42105+
42106+ if (!virt_addr_valid(ptr))
42107+ return;
42108+
42109+ sp = (struct slob_page *)virt_to_head_page(ptr);
017d2877
AM
42110+ /* XXX: can get a little tighter with this stack check */
42111+ if (!PageSlobPage((struct page*)sp) && object_is_on_stack(ptr) &&
42112+ (n > ((unsigned long)task_stack_page(current) + THREAD_SIZE -
42113+ (unsigned long)ptr)))
42114+ goto report;
42115+ else
de855c5d
AM
42116+ return;
42117+
42118+ if (sp->size) {
42119+ base = page_address(&sp->page);
42120+ if (base <= ptr && n <= sp->size - (ptr - base))
42121+ return;
42122+ goto report;
42123+ }
42124+
42125+ /* some tricky double walking to find the chunk */
42126+ base = (void *)((unsigned long)ptr & PAGE_MASK);
42127+ free = sp->free;
42128+
42129+ while (!slob_last(free) && (void *)free <= ptr) {
42130+ base = free + slob_units(free);
42131+ free = slob_next(free);
42132+ }
42133+
42134+ while (base < (void *)free) {
42135+ slobidx_t m = ((slob_t *)base)[0].units, align = ((slob_t *)base)[1].units;
42136+ int size = SLOB_UNIT * SLOB_UNITS(m + align);
42137+ int offset;
42138+
42139+ if (ptr < base + align)
42140+ goto report;
42141+
42142+ offset = ptr - base - align;
42143+ if (offset < m) {
42144+ if (n <= m - offset)
42145+ return;
42146+ goto report;
42147+ }
42148+ base += size;
42149+ }
42150+
42151+report:
42152+ if (to)
42153+ pax_report_leak_to_user(ptr, n);
42154+ else
42155+ pax_report_overflow_from_user(ptr, n);
42156+#endif
42157+
42158+}
42159+EXPORT_SYMBOL(check_object_size);
42160+
42161 /* can't use ksize for kmem_cache_alloc memory, only kmalloc */
42162 size_t ksize(const void *block)
42163 {
017d2877
AM
42164@@ -544,10 +629,10 @@ size_t ksize(const void *block)
42165 sp = slob_page(block);
42166 if (is_slob_page(sp)) {
de855c5d
AM
42167 int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
42168- unsigned int *m = (unsigned int *)(block - align);
42169- return SLOB_UNITS(*m) * SLOB_UNIT;
42170+ slob_t *m = (slob_t *)(block - align);
42171+ return SLOB_UNITS(m[0].units) * SLOB_UNIT;
42172 } else
42173- return sp->page.private;
42174+ return sp->size;
42175 }
42176 EXPORT_SYMBOL(ksize);
42177
017d2877 42178@@ -600,17 +685,25 @@ void *kmem_cache_alloc_node(struct kmem_
de855c5d
AM
42179 {
42180 void *b;
42181
42182+#ifdef CONFIG_PAX_USERCOPY
42183+ b = __kmalloc_node_align(c->size, flags, node, c->align);
42184+#else
017d2877 42185 if (c->size < PAGE_SIZE) {
de855c5d 42186 b = slob_alloc(c->size, flags, c->align, node);
017d2877
AM
42187 trace_kmem_cache_alloc_node(_RET_IP_, b, c->size,
42188 SLOB_UNITS(c->size) * SLOB_UNIT,
42189 flags, node);
42190 } else {
de855c5d
AM
42191+ struct slob_page *sp;
42192+
017d2877 42193 b = slob_new_pages(flags, get_order(c->size), node);
de855c5d
AM
42194+ sp = (struct slob_page *)virt_to_head_page(b);
42195+ sp->size = c->size;
017d2877
AM
42196 trace_kmem_cache_alloc_node(_RET_IP_, b, c->size,
42197 PAGE_SIZE << get_order(c->size),
42198 flags, node);
42199 }
de855c5d
AM
42200+#endif
42201
42202 if (c->ctor)
42203 c->ctor(b);
017d2877 42204@@ -621,10 +714,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
de855c5d
AM
42205
42206 static void __kmem_cache_free(void *b, int size)
42207 {
42208- if (size < PAGE_SIZE)
42209+ struct slob_page *sp = (struct slob_page *)virt_to_head_page(b);
42210+
42211+ if (slob_page(sp))
42212 slob_free(b, size);
42213- else
42214+ else {
42215+ clear_slob_page(sp);
42216+ free_slob_page(sp);
42217+ sp->size = 0;
017d2877 42218 slob_free_pages(b, get_order(size));
de855c5d
AM
42219+ }
42220 }
42221
42222 static void kmem_rcu_free(struct rcu_head *head)
017d2877 42223@@ -637,14 +736,23 @@ static void kmem_rcu_free(struct rcu_hea
de855c5d
AM
42224
42225 void kmem_cache_free(struct kmem_cache *c, void *b)
42226 {
42227+ int size = c->size;
42228+
42229+#ifdef CONFIG_PAX_USERCOPY
42230+ if (size + c->align < PAGE_SIZE) {
42231+ size += c->align;
42232+ b -= c->align;
42233+ }
42234+#endif
42235+
42236 if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {
42237 struct slob_rcu *slob_rcu;
42238- slob_rcu = b + (c->size - sizeof(struct slob_rcu));
42239+ slob_rcu = b + (size - sizeof(struct slob_rcu));
42240 INIT_RCU_HEAD(&slob_rcu->head);
42241- slob_rcu->size = c->size;
42242+ slob_rcu->size = size;
42243 call_rcu(&slob_rcu->head, kmem_rcu_free);
42244 } else {
42245- __kmem_cache_free(b, c->size);
42246+ __kmem_cache_free(b, size);
42247 }
017d2877
AM
42248
42249 trace_kmem_cache_free(_RET_IP_, b);
42250diff -urNp linux-2.6.30.4/mm/slub.c linux-2.6.30.4/mm/slub.c
42251--- linux-2.6.30.4/mm/slub.c 2009-07-30 20:32:40.563597140 -0400
42252+++ linux-2.6.30.4/mm/slub.c 2009-07-30 20:32:48.102657318 -0400
42253@@ -1811,7 +1811,7 @@ static int slub_min_objects;
de855c5d
AM
42254 * Merge control. If this is set then no merging of slab caches will occur.
42255 * (Could be removed. This was introduced to pacify the merge skeptics.)
42256 */
42257-static int slub_nomerge;
42258+static int slub_nomerge = 1;
42259
42260 /*
42261 * Calculate the order of allocation given an slab object size.
017d2877
AM
42262@@ -2354,7 +2354,7 @@ static int kmem_cache_open(struct kmem_c
42263 * list to avoid pounding the page allocator excessively.
42264 */
42265 set_min_partial(s, ilog2(s->size));
2380c486
JR
42266- s->refcount = 1;
42267+ atomic_set(&s->refcount, 1);
42268 #ifdef CONFIG_NUMA
42269 s->remote_node_defrag_ratio = 1000;
42270 #endif
017d2877
AM
42271@@ -2493,8 +2493,7 @@ void kmem_cache_destroy(struct kmem_cach
42272 if (s->flags & SLAB_DESTROY_BY_RCU)
42273 rcu_barrier();
2380c486
JR
42274 down_write(&slub_lock);
42275- s->refcount--;
42276- if (!s->refcount) {
42277+ if (atomic_dec_and_test(&s->refcount)) {
42278 list_del(&s->list);
42279 up_write(&slub_lock);
42280 if (kmem_cache_close(s)) {
017d2877 42281@@ -2754,6 +2753,48 @@ void *__kmalloc_node(size_t size, gfp_t
de855c5d
AM
42282 EXPORT_SYMBOL(__kmalloc_node);
42283 #endif
42284
42285+void check_object_size(const void *ptr, unsigned long n, bool to)
42286+{
42287+
42288+#ifdef CONFIG_PAX_USERCOPY
42289+ struct page *page;
42290+ struct kmem_cache *s;
42291+ unsigned long offset;
42292+
42293+ if (!n)
42294+ return;
42295+
42296+ if (ZERO_OR_NULL_PTR(ptr))
42297+ goto report;
42298+
42299+ if (!virt_addr_valid(ptr))
42300+ return;
42301+
42302+ page = get_object_page(ptr);
42303+
017d2877
AM
42304+ /* XXX: can get a little tighter with this stack check */
42305+ if (!page && object_is_on_stack(ptr) &&
42306+ (n > ((unsigned long)task_stack_page(current) + THREAD_SIZE -
42307+ (unsigned long)ptr)))
42308+ goto report;
42309+ else
de855c5d
AM
42310+ return;
42311+
42312+ s = page->slab;
42313+ offset = (ptr - page_address(page)) % s->size;
42314+ if (offset <= s->objsize && n <= s->objsize - offset)
42315+ return;
42316+
42317+report:
42318+ if (to)
42319+ pax_report_leak_to_user(ptr, n);
42320+ else
42321+ pax_report_overflow_from_user(ptr, n);
42322+#endif
42323+
42324+}
42325+EXPORT_SYMBOL(check_object_size);
42326+
42327 size_t ksize(const void *object)
42328 {
42329 struct page *page;
017d2877 42330@@ -3024,7 +3065,7 @@ void __init kmem_cache_init(void)
2380c486
JR
42331 */
42332 create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node",
42333 sizeof(struct kmem_cache_node), GFP_KERNEL);
42334- kmalloc_caches[0].refcount = -1;
42335+ atomic_set(&kmalloc_caches[0].refcount, -1);
42336 caches++;
42337
42338 hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI);
017d2877 42339@@ -3114,7 +3155,7 @@ static int slab_unmergeable(struct kmem_
2380c486
JR
42340 /*
42341 * We may have set a slab to be unmergeable during bootstrap.
42342 */
42343- if (s->refcount < 0)
42344+ if (atomic_read(&s->refcount) < 0)
42345 return 1;
42346
42347 return 0;
017d2877 42348@@ -3171,7 +3212,7 @@ struct kmem_cache *kmem_cache_create(con
2380c486
JR
42349 if (s) {
42350 int cpu;
42351
42352- s->refcount++;
42353+ atomic_inc(&s->refcount);
42354 /*
42355 * Adjust the object sizes so that we clear
42356 * the complete object on kzalloc.
017d2877 42357@@ -3190,7 +3231,7 @@ struct kmem_cache *kmem_cache_create(con
2380c486
JR
42358
42359 if (sysfs_slab_alias(s, name)) {
42360 down_write(&slub_lock);
42361- s->refcount--;
42362+ atomic_dec(&s->refcount);
42363 up_write(&slub_lock);
42364 goto err;
42365 }
017d2877 42366@@ -3938,7 +3979,7 @@ SLAB_ATTR_RO(ctor);
2380c486
JR
42367
42368 static ssize_t aliases_show(struct kmem_cache *s, char *buf)
42369 {
42370- return sprintf(buf, "%d\n", s->refcount - 1);
42371+ return sprintf(buf, "%d\n", atomic_read(&s->refcount) - 1);
42372 }
42373 SLAB_ATTR_RO(aliases);
42374
017d2877 42375@@ -4617,7 +4658,9 @@ static const struct file_operations proc
2380c486
JR
42376
42377 static int __init slab_proc_init(void)
42378 {
42379+#if !defined(CONFIG_GRKERNSEC_PROC_ADD)
42380 proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
42381+#endif
42382 return 0;
42383 }
42384 module_init(slab_proc_init);
017d2877
AM
42385diff -urNp linux-2.6.30.4/mm/util.c linux-2.6.30.4/mm/util.c
42386--- linux-2.6.30.4/mm/util.c 2009-07-24 17:47:51.000000000 -0400
42387+++ linux-2.6.30.4/mm/util.c 2009-07-30 09:48:10.152770641 -0400
42388@@ -218,6 +218,12 @@ EXPORT_SYMBOL(strndup_user);
2380c486
JR
42389 void arch_pick_mmap_layout(struct mm_struct *mm)
42390 {
42391 mm->mmap_base = TASK_UNMAPPED_BASE;
42392+
42393+#ifdef CONFIG_PAX_RANDMMAP
42394+ if (mm->pax_flags & MF_PAX_RANDMMAP)
42395+ mm->mmap_base += mm->delta_mmap;
42396+#endif
42397+
42398 mm->get_unmapped_area = arch_get_unmapped_area;
42399 mm->unmap_area = arch_unmap_area;
42400 }
017d2877
AM
42401diff -urNp linux-2.6.30.4/mm/vmalloc.c linux-2.6.30.4/mm/vmalloc.c
42402--- linux-2.6.30.4/mm/vmalloc.c 2009-07-24 17:47:51.000000000 -0400
42403+++ linux-2.6.30.4/mm/vmalloc.c 2009-07-30 09:48:10.153729053 -0400
42404@@ -91,6 +91,11 @@ static int vmap_pte_range(pmd_t *pmd, un
2380c486
JR
42405 unsigned long end, pgprot_t prot, struct page **pages, int *nr)
42406 {
42407 pte_t *pte;
42408+ int ret = -ENOMEM;
42409+
42410+#ifdef CONFIG_PAX_KERNEXEC
42411+ unsigned long cr0;
42412+#endif
42413
42414 /*
42415 * nr is a running index into the array which helps higher level
017d2877 42416@@ -100,17 +105,33 @@ static int vmap_pte_range(pmd_t *pmd, un
2380c486
JR
42417 pte = pte_alloc_kernel(pmd, addr);
42418 if (!pte)
42419 return -ENOMEM;
42420+
42421+#ifdef CONFIG_PAX_KERNEXEC
42422+ pax_open_kernel(cr0);
42423+#endif
42424+
42425 do {
42426 struct page *page = pages[*nr];
42427
42428- if (WARN_ON(!pte_none(*pte)))
42429- return -EBUSY;
42430- if (WARN_ON(!page))
42431- return -ENOMEM;
42432+ if (WARN_ON(!pte_none(*pte))) {
42433+ ret = -EBUSY;
42434+ goto out;
42435+ }
42436+ if (WARN_ON(!page)) {
42437+ ret = -ENOMEM;
42438+ goto out;
42439+ }
42440 set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
42441 (*nr)++;
42442 } while (pte++, addr += PAGE_SIZE, addr != end);
42443- return 0;
42444+ ret = 0;
42445+out:
42446+
42447+#ifdef CONFIG_PAX_KERNEXEC
42448+ pax_close_kernel(cr0);
42449+#endif
42450+
42451+ return ret;
42452 }
42453
42454 static int vmap_pmd_range(pud_t *pud, unsigned long addr,
017d2877 42455@@ -1132,6 +1153,16 @@ static struct vm_struct *__get_vm_area_n
2380c486
JR
42456 unsigned long align = 1;
42457
42458 BUG_ON(in_interrupt());
42459+
42460+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
42461+ if (flags & VM_KERNEXEC) {
42462+ if (start != VMALLOC_START || end != VMALLOC_END)
42463+ return NULL;
42464+ start = (unsigned long)MODULES_VADDR;
42465+ end = (unsigned long)MODULES_END;
42466+ }
42467+#endif
42468+
42469 if (flags & VM_IOREMAP) {
42470 int bit = fls(size);
42471
017d2877 42472@@ -1368,6 +1399,11 @@ void *vmap(struct page **pages, unsigned
2380c486
JR
42473 if (count > num_physpages)
42474 return NULL;
42475
42476+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
42477+ if (!(pgprot_val(prot) & _PAGE_NX))
42478+ flags |= VM_KERNEXEC;
42479+#endif
42480+
42481 area = get_vm_area_caller((count << PAGE_SHIFT), flags,
42482 __builtin_return_address(0));
42483 if (!area)
017d2877 42484@@ -1464,6 +1500,13 @@ static void *__vmalloc_node(unsigned lon
2380c486
JR
42485 if (!size || (size >> PAGE_SHIFT) > num_physpages)
42486 return NULL;
42487
42488+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
42489+ if (!(pgprot_val(prot) & _PAGE_NX))
42490+ area = __get_vm_area_node(size, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
42491+ node, gfp_mask, caller);
42492+ else
42493+#endif
42494+
42495 area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
42496 node, gfp_mask, caller);
42497
017d2877 42498@@ -1473,6 +1516,7 @@ static void *__vmalloc_node(unsigned lon
de855c5d
AM
42499 return __vmalloc_area_node(area, gfp_mask, prot, node, caller);
42500 }
2380c486 42501
de855c5d
AM
42502+#undef __vmalloc
42503 void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
42504 {
42505 return __vmalloc_node(size, gfp_mask, prot, -1,
017d2877 42506@@ -1489,6 +1533,7 @@ EXPORT_SYMBOL(__vmalloc);
de855c5d
AM
42507 * For tight control over page level allocator and protection flags
42508 * use __vmalloc() instead.
42509 */
42510+#undef vmalloc
42511 void *vmalloc(unsigned long size)
42512 {
42513 return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
017d2877 42514@@ -1503,6 +1548,7 @@ EXPORT_SYMBOL(vmalloc);
de855c5d
AM
42515 * The resulting memory area is zeroed so it can be mapped to userspace
42516 * without leaking data.
42517 */
42518+#undef vmalloc_user
42519 void *vmalloc_user(unsigned long size)
42520 {
42521 struct vm_struct *area;
017d2877 42522@@ -1529,6 +1575,7 @@ EXPORT_SYMBOL(vmalloc_user);
de855c5d
AM
42523 * For tight control over page level allocator and protection flags
42524 * use __vmalloc() instead.
42525 */
42526+#undef vmalloc_node
42527 void *vmalloc_node(unsigned long size, int node)
42528 {
42529 return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
017d2877 42530@@ -1551,10 +1598,10 @@ EXPORT_SYMBOL(vmalloc_node);
de855c5d
AM
42531 * For tight control over page level allocator and protection flags
42532 * use __vmalloc() instead.
42533 */
42534-
42535+#undef vmalloc_exec
2380c486
JR
42536 void *vmalloc_exec(unsigned long size)
42537 {
42538- return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
42539+ return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC,
42540 -1, __builtin_return_address(0));
42541 }
42542
017d2877 42543@@ -1573,6 +1620,7 @@ void *vmalloc_exec(unsigned long size)
de855c5d
AM
42544 * Allocate enough 32bit PA addressable pages to cover @size from the
42545 * page level allocator and map them into contiguous kernel virtual space.
42546 */
42547+#undef vmalloc_32
42548 void *vmalloc_32(unsigned long size)
42549 {
42550 return __vmalloc_node(size, GFP_VMALLOC32, PAGE_KERNEL,
017d2877 42551@@ -1587,6 +1635,7 @@ EXPORT_SYMBOL(vmalloc_32);
de855c5d
AM
42552 * The resulting memory area is 32bit addressable and zeroed so it can be
42553 * mapped to userspace without leaking data.
42554 */
42555+#undef vmalloc_32_user
42556 void *vmalloc_32_user(unsigned long size)
42557 {
42558 struct vm_struct *area;
017d2877
AM
42559diff -urNp linux-2.6.30.4/net/atm/atm_misc.c linux-2.6.30.4/net/atm/atm_misc.c
42560--- linux-2.6.30.4/net/atm/atm_misc.c 2009-07-24 17:47:51.000000000 -0400
42561+++ linux-2.6.30.4/net/atm/atm_misc.c 2009-07-30 09:48:10.153729053 -0400
de855c5d
AM
42562@@ -19,7 +19,7 @@ int atm_charge(struct atm_vcc *vcc,int t
42563 if (atomic_read(&sk_atm(vcc)->sk_rmem_alloc) <= sk_atm(vcc)->sk_rcvbuf)
42564 return 1;
42565 atm_return(vcc,truesize);
42566- atomic_inc(&vcc->stats->rx_drop);
42567+ atomic_inc_unchecked(&vcc->stats->rx_drop);
42568 return 0;
42569 }
42570
42571@@ -41,7 +41,7 @@ struct sk_buff *atm_alloc_charge(struct
42572 }
42573 }
42574 atm_return(vcc,guess);
42575- atomic_inc(&vcc->stats->rx_drop);
42576+ atomic_inc_unchecked(&vcc->stats->rx_drop);
42577 return NULL;
42578 }
42579
017d2877
AM
42580@@ -96,7 +96,7 @@ void sonet_copy_stats(struct k_sonet_sta
42581
42582 void sonet_subtract_stats(struct k_sonet_stats *from,struct sonet_stats *to)
42583 {
42584-#define __HANDLE_ITEM(i) atomic_sub(to->i,&from->i)
42585+#define __HANDLE_ITEM(i) atomic_sub_unchecked(to->i,&from->i)
42586 __SONET_ITEMS
42587 #undef __HANDLE_ITEM
42588 }
42589diff -urNp linux-2.6.30.4/net/atm/resources.c linux-2.6.30.4/net/atm/resources.c
42590--- linux-2.6.30.4/net/atm/resources.c 2009-07-24 17:47:51.000000000 -0400
42591+++ linux-2.6.30.4/net/atm/resources.c 2009-07-30 09:48:10.153729053 -0400
de855c5d
AM
42592@@ -170,7 +170,7 @@ static void copy_aal_stats(struct k_atm_
42593 static void subtract_aal_stats(struct k_atm_aal_stats *from,
42594 struct atm_aal_stats *to)
42595 {
42596-#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
42597+#define __HANDLE_ITEM(i) atomic_sub_unchecked(to->i, &from->i)
42598 __AAL_STAT_ITEMS
42599 #undef __HANDLE_ITEM
42600 }
017d2877
AM
42601diff -urNp linux-2.6.30.4/net/bridge/br_stp_if.c linux-2.6.30.4/net/bridge/br_stp_if.c
42602--- linux-2.6.30.4/net/bridge/br_stp_if.c 2009-07-24 17:47:51.000000000 -0400
42603+++ linux-2.6.30.4/net/bridge/br_stp_if.c 2009-07-30 09:48:10.153729053 -0400
2380c486
JR
42604@@ -146,7 +146,7 @@ static void br_stp_stop(struct net_bridg
42605 char *envp[] = { NULL };
42606
42607 if (br->stp_enabled == BR_USER_STP) {
42608- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
42609+ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
42610 printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
42611 br->dev->name, r);
42612
017d2877
AM
42613diff -urNp linux-2.6.30.4/net/core/flow.c linux-2.6.30.4/net/core/flow.c
42614--- linux-2.6.30.4/net/core/flow.c 2009-07-24 17:47:51.000000000 -0400
42615+++ linux-2.6.30.4/net/core/flow.c 2009-07-30 09:48:10.154837046 -0400
2380c486
JR
42616@@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
42617
42618 static u32 flow_hash_shift;
42619 #define flow_hash_size (1 << flow_hash_shift)
42620-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
42621+static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
42622
42623 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
42624
42625@@ -52,7 +52,7 @@ struct flow_percpu_info {
42626 u32 hash_rnd;
42627 int count;
42628 };
42629-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
42630+static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
42631
42632 #define flow_hash_rnd_recalc(cpu) \
42633 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
42634@@ -69,7 +69,7 @@ struct flow_flush_info {
42635 atomic_t cpuleft;
42636 struct completion completion;
42637 };
42638-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
42639+static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
42640
42641 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
42642
017d2877
AM
42643diff -urNp linux-2.6.30.4/net/dccp/ccids/ccid3.c linux-2.6.30.4/net/dccp/ccids/ccid3.c
42644--- linux-2.6.30.4/net/dccp/ccids/ccid3.c 2009-07-24 17:47:51.000000000 -0400
42645+++ linux-2.6.30.4/net/dccp/ccids/ccid3.c 2009-07-30 09:48:10.154837046 -0400
2380c486
JR
42646@@ -43,7 +43,7 @@
42647 static int ccid3_debug;
42648 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
42649 #else
42650-#define ccid3_pr_debug(format, a...)
42651+#define ccid3_pr_debug(format, a...) do {} while (0)
42652 #endif
42653
42654 /*
017d2877
AM
42655diff -urNp linux-2.6.30.4/net/dccp/dccp.h linux-2.6.30.4/net/dccp/dccp.h
42656--- linux-2.6.30.4/net/dccp/dccp.h 2009-07-24 17:47:51.000000000 -0400
42657+++ linux-2.6.30.4/net/dccp/dccp.h 2009-07-30 09:48:10.154837046 -0400
42658@@ -44,9 +44,9 @@ extern int dccp_debug;
2380c486 42659 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
017d2877 42660 #define dccp_debug(fmt, a...) dccp_pr_debug_cat(KERN_DEBUG fmt, ##a)
2380c486
JR
42661 #else
42662-#define dccp_pr_debug(format, a...)
42663-#define dccp_pr_debug_cat(format, a...)
017d2877 42664-#define dccp_debug(format, a...)
2380c486
JR
42665+#define dccp_pr_debug(format, a...) do {} while (0)
42666+#define dccp_pr_debug_cat(format, a...) do {} while (0)
017d2877 42667+#define dccp_debug(format, a...) do {} while (0)
2380c486
JR
42668 #endif
42669
42670 extern struct inet_hashinfo dccp_hashinfo;
017d2877
AM
42671diff -urNp linux-2.6.30.4/net/ipv4/inet_hashtables.c linux-2.6.30.4/net/ipv4/inet_hashtables.c
42672--- linux-2.6.30.4/net/ipv4/inet_hashtables.c 2009-07-24 17:47:51.000000000 -0400
42673+++ linux-2.6.30.4/net/ipv4/inet_hashtables.c 2009-07-30 11:10:49.904544447 -0400
42674@@ -18,12 +18,15 @@
de855c5d 42675 #include <linux/sched.h>
2380c486
JR
42676 #include <linux/slab.h>
42677 #include <linux/wait.h>
42678+#include <linux/security.h>
42679
42680 #include <net/inet_connection_sock.h>
42681 #include <net/inet_hashtables.h>
017d2877 42682 #include <net/route.h>
2380c486
JR
42683 #include <net/ip.h>
42684
42685+extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
42686+
42687 /*
42688 * Allocate and initialize a new local port bind bucket.
42689 * The bindhash mutex for snum's hash chain must be held here.
017d2877 42690@@ -490,6 +493,8 @@ ok:
2380c486
JR
42691 }
42692 spin_unlock(&head->lock);
42693
42694+ gr_update_task_in_ip_table(current, inet_sk(sk));
42695+
42696 if (tw) {
42697 inet_twsk_deschedule(tw, death_row);
42698 inet_twsk_put(tw);
017d2877
AM
42699diff -urNp linux-2.6.30.4/net/ipv4/netfilter/nf_nat_snmp_basic.c linux-2.6.30.4/net/ipv4/netfilter/nf_nat_snmp_basic.c
42700--- linux-2.6.30.4/net/ipv4/netfilter/nf_nat_snmp_basic.c 2009-07-24 17:47:51.000000000 -0400
42701+++ linux-2.6.30.4/net/ipv4/netfilter/nf_nat_snmp_basic.c 2009-07-30 09:48:10.155784268 -0400
de855c5d
AM
42702@@ -397,7 +397,7 @@ static unsigned char asn1_octets_decode(
42703
42704 *len = 0;
42705
42706- *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
42707+ *octets = kmalloc((eoc - ctx->pointer), GFP_ATOMIC);
42708 if (*octets == NULL) {
42709 if (net_ratelimit())
42710 printk("OOM in bsalg (%d)\n", __LINE__);
017d2877
AM
42711diff -urNp linux-2.6.30.4/net/ipv4/tcp_ipv4.c linux-2.6.30.4/net/ipv4/tcp_ipv4.c
42712--- linux-2.6.30.4/net/ipv4/tcp_ipv4.c 2009-07-24 17:47:51.000000000 -0400
42713+++ linux-2.6.30.4/net/ipv4/tcp_ipv4.c 2009-07-30 11:10:49.916766621 -0400
42714@@ -1503,6 +1503,9 @@ int tcp_v4_do_rcv(struct sock *sk, struc
de855c5d 42715 return 0;
2380c486 42716
de855c5d
AM
42717 reset:
42718+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
42719+ if (!skb->dev || (skb->dev->flags & IFF_LOOPBACK))
42720+#endif
42721 tcp_v4_send_reset(rsk, skb);
42722 discard:
42723 kfree_skb(skb);
017d2877 42724@@ -1611,6 +1614,9 @@ no_tcp_socket:
de855c5d
AM
42725 bad_packet:
42726 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
42727 } else {
42728+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
42729+ if (skb->dev->flags & IFF_LOOPBACK)
42730+#endif
42731 tcp_v4_send_reset(NULL, skb);
42732 }
2380c486 42733
017d2877
AM
42734diff -urNp linux-2.6.30.4/net/ipv4/tcp_minisocks.c linux-2.6.30.4/net/ipv4/tcp_minisocks.c
42735--- linux-2.6.30.4/net/ipv4/tcp_minisocks.c 2009-07-24 17:47:51.000000000 -0400
42736+++ linux-2.6.30.4/net/ipv4/tcp_minisocks.c 2009-07-30 11:10:49.922670152 -0400
42737@@ -694,8 +694,11 @@ listen_overflow:
de855c5d
AM
42738
42739 embryonic_reset:
42740 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS);
42741+
42742+#ifndef CONFIG_GRKERNSEC_BLACKHOLE
42743 if (!(flg & TCP_FLAG_RST))
42744 req->rsk_ops->send_reset(sk, skb);
42745+#endif
42746
42747 inet_csk_reqsk_queue_drop(sk, req, prev);
42748 return NULL;
017d2877
AM
42749diff -urNp linux-2.6.30.4/net/ipv4/udp.c linux-2.6.30.4/net/ipv4/udp.c
42750--- linux-2.6.30.4/net/ipv4/udp.c 2009-07-24 17:47:51.000000000 -0400
42751+++ linux-2.6.30.4/net/ipv4/udp.c 2009-07-30 11:10:49.923319110 -0400
2380c486
JR
42752@@ -86,6 +86,7 @@
42753 #include <linux/types.h>
42754 #include <linux/fcntl.h>
42755 #include <linux/module.h>
42756+#include <linux/security.h>
42757 #include <linux/socket.h>
42758 #include <linux/sockios.h>
42759 #include <linux/igmp.h>
42760@@ -369,6 +370,9 @@ found:
42761 return s;
42762 }
42763
42764+extern int gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb);
42765+extern int gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr);
42766+
42767 /*
42768 * This routine is called by the ICMP module when it gets some
42769 * sort of error condition. If err < 0 then the socket should
017d2877 42770@@ -631,9 +635,18 @@ int udp_sendmsg(struct kiocb *iocb, stru
2380c486
JR
42771 dport = usin->sin_port;
42772 if (dport == 0)
42773 return -EINVAL;
42774+
42775+ err = gr_search_udp_sendmsg(sk, usin);
42776+ if (err)
42777+ return err;
42778 } else {
42779 if (sk->sk_state != TCP_ESTABLISHED)
42780 return -EDESTADDRREQ;
42781+
42782+ err = gr_search_udp_sendmsg(sk, NULL);
42783+ if (err)
42784+ return err;
42785+
42786 daddr = inet->daddr;
42787 dport = inet->dport;
42788 /* Open fast path for connected socket.
017d2877 42789@@ -902,6 +915,10 @@ try_again:
2380c486
JR
42790 if (!skb)
42791 goto out;
42792
42793+ err = gr_search_udp_recvmsg(sk, skb);
42794+ if (err)
42795+ goto out_free;
42796+
42797 ulen = skb->len - sizeof(struct udphdr);
42798 copied = len;
42799 if (copied > ulen)
017d2877 42800@@ -1292,6 +1309,9 @@ int __udp4_lib_rcv(struct sk_buff *skb,
de855c5d
AM
42801 goto csum_error;
42802
42803 UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
42804+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
42805+ if (skb->dev->flags & IFF_LOOPBACK)
42806+#endif
42807 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
42808
42809 /*
017d2877
AM
42810diff -urNp linux-2.6.30.4/net/ipv6/exthdrs.c linux-2.6.30.4/net/ipv6/exthdrs.c
42811--- linux-2.6.30.4/net/ipv6/exthdrs.c 2009-07-24 17:47:51.000000000 -0400
42812+++ linux-2.6.30.4/net/ipv6/exthdrs.c 2009-07-30 09:48:10.155784268 -0400
2380c486
JR
42813@@ -630,7 +630,7 @@ static struct tlvtype_proc tlvprochopopt
42814 .type = IPV6_TLV_JUMBO,
42815 .func = ipv6_hop_jumbo,
42816 },
42817- { -1, }
42818+ { -1, NULL }
42819 };
42820
42821 int ipv6_parse_hopopts(struct sk_buff *skb)
017d2877
AM
42822diff -urNp linux-2.6.30.4/net/ipv6/ip6mr.c linux-2.6.30.4/net/ipv6/ip6mr.c
42823--- linux-2.6.30.4/net/ipv6/ip6mr.c 2009-07-24 17:47:51.000000000 -0400
42824+++ linux-2.6.30.4/net/ipv6/ip6mr.c 2009-07-30 09:48:10.156679415 -0400
42825@@ -204,7 +204,7 @@ static int ip6mr_vif_seq_show(struct seq
42826 return 0;
42827 }
42828
42829-static struct seq_operations ip6mr_vif_seq_ops = {
42830+static const struct seq_operations ip6mr_vif_seq_ops = {
42831 .start = ip6mr_vif_seq_start,
42832 .next = ip6mr_vif_seq_next,
42833 .stop = ip6mr_vif_seq_stop,
42834@@ -217,7 +217,7 @@ static int ip6mr_vif_open(struct inode *
42835 sizeof(struct ipmr_vif_iter));
42836 }
42837
42838-static struct file_operations ip6mr_vif_fops = {
42839+static const struct file_operations ip6mr_vif_fops = {
42840 .owner = THIS_MODULE,
42841 .open = ip6mr_vif_open,
42842 .read = seq_read,
42843@@ -328,7 +328,7 @@ static int ipmr_mfc_seq_show(struct seq_
42844 return 0;
42845 }
42846
42847-static struct seq_operations ipmr_mfc_seq_ops = {
42848+static const struct seq_operations ipmr_mfc_seq_ops = {
42849 .start = ipmr_mfc_seq_start,
42850 .next = ipmr_mfc_seq_next,
42851 .stop = ipmr_mfc_seq_stop,
42852@@ -341,7 +341,7 @@ static int ipmr_mfc_open(struct inode *i
42853 sizeof(struct ipmr_mfc_iter));
42854 }
42855
42856-static struct file_operations ip6mr_mfc_fops = {
42857+static const struct file_operations ip6mr_mfc_fops = {
42858 .owner = THIS_MODULE,
42859 .open = ipmr_mfc_open,
42860 .read = seq_read,
42861diff -urNp linux-2.6.30.4/net/ipv6/raw.c linux-2.6.30.4/net/ipv6/raw.c
42862--- linux-2.6.30.4/net/ipv6/raw.c 2009-07-24 17:47:51.000000000 -0400
42863+++ linux-2.6.30.4/net/ipv6/raw.c 2009-07-30 09:48:10.156679415 -0400
2380c486
JR
42864@@ -600,7 +600,7 @@ out:
42865 return err;
42866 }
42867
42868-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
42869+static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
42870 struct flowi *fl, struct rt6_info *rt,
42871 unsigned int flags)
42872 {
017d2877
AM
42873diff -urNp linux-2.6.30.4/net/ipv6/tcp_ipv6.c linux-2.6.30.4/net/ipv6/tcp_ipv6.c
42874--- linux-2.6.30.4/net/ipv6/tcp_ipv6.c 2009-07-24 17:47:51.000000000 -0400
42875+++ linux-2.6.30.4/net/ipv6/tcp_ipv6.c 2009-07-30 11:10:49.952595469 -0400
42876@@ -1575,6 +1575,9 @@ static int tcp_v6_do_rcv(struct sock *sk
de855c5d
AM
42877 return 0;
42878
42879 reset:
42880+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
42881+ if (!skb->dev || (skb->dev->flags & IFF_LOOPBACK))
42882+#endif
42883 tcp_v6_send_reset(sk, skb);
42884 discard:
42885 if (opt_skb)
017d2877 42886@@ -1697,6 +1700,9 @@ no_tcp_socket:
de855c5d
AM
42887 bad_packet:
42888 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
42889 } else {
42890+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
42891+ if (skb->dev->flags & IFF_LOOPBACK)
42892+#endif
42893 tcp_v6_send_reset(NULL, skb);
42894 }
42895
017d2877
AM
42896diff -urNp linux-2.6.30.4/net/ipv6/udp.c linux-2.6.30.4/net/ipv6/udp.c
42897--- linux-2.6.30.4/net/ipv6/udp.c 2009-07-24 17:47:51.000000000 -0400
42898+++ linux-2.6.30.4/net/ipv6/udp.c 2009-07-30 11:10:49.959325956 -0400
42899@@ -590,6 +590,9 @@ int __udp6_lib_rcv(struct sk_buff *skb,
de855c5d
AM
42900 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS,
42901 proto == IPPROTO_UDPLITE);
42902
42903+#ifdef CONFIG_GRKERNSEC_BLACKHOLE
42904+ if (skb->dev->flags & IFF_LOOPBACK)
42905+#endif
42906 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
42907
42908 kfree_skb(skb);
017d2877
AM
42909diff -urNp linux-2.6.30.4/net/key/af_key.c linux-2.6.30.4/net/key/af_key.c
42910--- linux-2.6.30.4/net/key/af_key.c 2009-07-24 17:47:51.000000000 -0400
42911+++ linux-2.6.30.4/net/key/af_key.c 2009-07-30 09:48:10.157841054 -0400
42912@@ -3705,7 +3705,7 @@ static void pfkey_seq_stop(struct seq_fi
42913 read_unlock(&pfkey_table_lock);
42914 }
42915
42916-static struct seq_operations pfkey_seq_ops = {
42917+static const struct seq_operations pfkey_seq_ops = {
42918 .start = pfkey_seq_start,
42919 .next = pfkey_seq_next,
42920 .stop = pfkey_seq_stop,
42921@@ -3718,7 +3718,7 @@ static int pfkey_seq_open(struct inode *
42922 sizeof(struct seq_net_private));
42923 }
42924
42925-static struct file_operations pfkey_proc_ops = {
42926+static const struct file_operations pfkey_proc_ops = {
42927 .open = pfkey_seq_open,
42928 .read = seq_read,
42929 .llseek = seq_lseek,
42930diff -urNp linux-2.6.30.4/net/mac80211/ieee80211_i.h linux-2.6.30.4/net/mac80211/ieee80211_i.h
42931--- linux-2.6.30.4/net/mac80211/ieee80211_i.h 2009-07-24 17:47:51.000000000 -0400
42932+++ linux-2.6.30.4/net/mac80211/ieee80211_i.h 2009-07-30 09:48:10.157841054 -0400
42933@@ -599,7 +599,7 @@ struct ieee80211_local {
de855c5d 42934 spinlock_t queue_stop_reason_lock;
017d2877 42935
de855c5d
AM
42936 struct net_device *mdev; /* wmaster# - "master" 802.11 device */
42937- int open_count;
42938+ atomic_t open_count;
42939 int monitors, cooked_mntrs;
42940 /* number of interfaces with corresponding FIF_ flags */
42941 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss;
017d2877
AM
42942diff -urNp linux-2.6.30.4/net/mac80211/iface.c linux-2.6.30.4/net/mac80211/iface.c
42943--- linux-2.6.30.4/net/mac80211/iface.c 2009-07-24 17:47:51.000000000 -0400
42944+++ linux-2.6.30.4/net/mac80211/iface.c 2009-07-30 09:48:10.157841054 -0400
42945@@ -163,7 +163,7 @@ static int ieee80211_open(struct net_dev
de855c5d
AM
42946 break;
42947 }
42948
42949- if (local->open_count == 0) {
42950+ if (atomic_read(&local->open_count) == 0) {
42951 res = 0;
42952 if (local->ops->start)
42953 res = local->ops->start(local_to_hw(local));
017d2877 42954@@ -199,7 +199,7 @@ static int ieee80211_open(struct net_dev
de855c5d
AM
42955 * Validate the MAC address for this device.
42956 */
42957 if (!is_valid_ether_addr(dev->dev_addr)) {
42958- if (!local->open_count && local->ops->stop)
42959+ if (!atomic_read(&local->open_count) && local->ops->stop)
42960 local->ops->stop(local_to_hw(local));
42961 return -EADDRNOTAVAIL;
42962 }
017d2877 42963@@ -286,7 +286,7 @@ static int ieee80211_open(struct net_dev
de855c5d
AM
42964 }
42965 }
42966
42967- if (local->open_count == 0) {
42968+ if (atomic_read(&local->open_count) == 0) {
42969 res = dev_open(local->mdev);
42970 WARN_ON(res);
42971 if (res)
017d2877 42972@@ -306,7 +306,7 @@ static int ieee80211_open(struct net_dev
de855c5d
AM
42973 if (sdata->flags & IEEE80211_SDATA_PROMISC)
42974 atomic_inc(&local->iff_promiscs);
42975
42976- local->open_count++;
42977+ atomic_inc(&local->open_count);
42978 if (hw_reconf_flags) {
42979 ieee80211_hw_config(local, hw_reconf_flags);
42980 /*
017d2877 42981@@ -334,7 +334,7 @@ static int ieee80211_open(struct net_dev
de855c5d
AM
42982 err_del_interface:
42983 local->ops->remove_interface(local_to_hw(local), &conf);
42984 err_stop:
42985- if (!local->open_count && local->ops->stop)
42986+ if (!atomic_read(&local->open_count) && local->ops->stop)
42987 local->ops->stop(local_to_hw(local));
42988 err_del_bss:
42989 sdata->bss = NULL;
017d2877 42990@@ -432,7 +432,7 @@ static int ieee80211_stop(struct net_dev
de855c5d
AM
42991 WARN_ON(!list_empty(&sdata->u.ap.vlans));
42992 }
42993
42994- local->open_count--;
42995+ atomic_dec(&local->open_count);
42996
42997 switch (sdata->vif.type) {
42998 case NL80211_IFTYPE_AP_VLAN:
017d2877 42999@@ -554,7 +554,7 @@ static int ieee80211_stop(struct net_dev
de855c5d
AM
43000
43001 sdata->bss = NULL;
43002
43003- if (local->open_count == 0) {
43004+ if (atomic_read(&local->open_count) == 0) {
43005 if (netif_running(local->mdev))
43006 dev_close(local->mdev);
43007
017d2877
AM
43008diff -urNp linux-2.6.30.4/net/mac80211/main.c linux-2.6.30.4/net/mac80211/main.c
43009--- linux-2.6.30.4/net/mac80211/main.c 2009-07-24 17:47:51.000000000 -0400
43010+++ linux-2.6.30.4/net/mac80211/main.c 2009-07-30 09:48:10.158959820 -0400
43011@@ -266,7 +266,7 @@ int ieee80211_hw_config(struct ieee80211
de855c5d
AM
43012 local->hw.conf.power_level = power;
43013 }
43014
43015- if (changed && local->open_count) {
43016+ if (changed && atomic_read(&local->open_count)) {
43017 ret = local->ops->config(local_to_hw(local), changed);
43018 /*
43019 * Goal:
017d2877
AM
43020diff -urNp linux-2.6.30.4/net/mac80211/pm.c linux-2.6.30.4/net/mac80211/pm.c
43021--- linux-2.6.30.4/net/mac80211/pm.c 2009-07-24 17:47:51.000000000 -0400
43022+++ linux-2.6.30.4/net/mac80211/pm.c 2009-07-30 09:48:10.158959820 -0400
43023@@ -65,7 +65,7 @@ int __ieee80211_suspend(struct ieee80211
43024 flush_workqueue(local->hw.workqueue);
43025
43026 /* stop hardware */
43027- if (local->open_count) {
43028+ if (atomic_read(&local->open_count)) {
43029 ieee80211_led_radio(local, false);
43030 local->ops->stop(hw);
43031 }
43032@@ -82,7 +82,7 @@ int __ieee80211_resume(struct ieee80211_
43033 int res;
43034
43035 /* restart hardware */
43036- if (local->open_count) {
43037+ if (atomic_read(&local->open_count)) {
43038 res = local->ops->start(hw);
43039
43040 ieee80211_led_radio(local, hw->conf.radio_enabled);
43041diff -urNp linux-2.6.30.4/net/mac80211/rate.c linux-2.6.30.4/net/mac80211/rate.c
43042--- linux-2.6.30.4/net/mac80211/rate.c 2009-07-24 17:47:51.000000000 -0400
43043+++ linux-2.6.30.4/net/mac80211/rate.c 2009-07-30 09:48:10.158959820 -0400
43044@@ -258,7 +258,7 @@ int ieee80211_init_rate_ctrl_alg(struct
de855c5d
AM
43045 struct rate_control_ref *ref, *old;
43046
43047 ASSERT_RTNL();
43048- if (local->open_count || netif_running(local->mdev))
43049+ if (atomic_read(&local->open_count) || netif_running(local->mdev))
43050 return -EBUSY;
43051
43052 ref = rate_control_alloc(name, local);
017d2877
AM
43053diff -urNp linux-2.6.30.4/net/mac80211/rc80211_minstrel_debugfs.c linux-2.6.30.4/net/mac80211/rc80211_minstrel_debugfs.c
43054--- linux-2.6.30.4/net/mac80211/rc80211_minstrel_debugfs.c 2009-07-24 17:47:51.000000000 -0400
43055+++ linux-2.6.30.4/net/mac80211/rc80211_minstrel_debugfs.c 2009-07-30 09:48:10.158959820 -0400
43056@@ -139,7 +139,7 @@ minstrel_stats_release(struct inode *ino
43057 return 0;
43058 }
43059
43060-static struct file_operations minstrel_stat_fops = {
43061+static const struct file_operations minstrel_stat_fops = {
43062 .owner = THIS_MODULE,
43063 .open = minstrel_stats_open,
43064 .read = minstrel_stats_read,
43065diff -urNp linux-2.6.30.4/net/mac80211/rc80211_pid_debugfs.c linux-2.6.30.4/net/mac80211/rc80211_pid_debugfs.c
43066--- linux-2.6.30.4/net/mac80211/rc80211_pid_debugfs.c 2009-07-24 17:47:51.000000000 -0400
43067+++ linux-2.6.30.4/net/mac80211/rc80211_pid_debugfs.c 2009-07-30 09:48:10.158959820 -0400
43068@@ -198,7 +198,7 @@ static ssize_t rate_control_pid_events_r
43069
43070 #undef RC_PID_PRINT_BUF_SIZE
43071
43072-static struct file_operations rc_pid_fop_events = {
43073+static const struct file_operations rc_pid_fop_events = {
43074 .owner = THIS_MODULE,
43075 .read = rate_control_pid_events_read,
43076 .poll = rate_control_pid_events_poll,
43077diff -urNp linux-2.6.30.4/net/packet/af_packet.c linux-2.6.30.4/net/packet/af_packet.c
43078--- linux-2.6.30.4/net/packet/af_packet.c 2009-07-24 17:47:51.000000000 -0400
43079+++ linux-2.6.30.4/net/packet/af_packet.c 2009-07-30 09:48:10.160018712 -0400
43080@@ -1740,7 +1740,7 @@ static void packet_mm_close(struct vm_ar
43081 atomic_dec(&pkt_sk(sk)->mapped);
43082 }
43083
43084-static struct vm_operations_struct packet_mmap_ops = {
43085+static const struct vm_operations_struct packet_mmap_ops = {
43086 .open = packet_mm_open,
43087 .close =packet_mm_close,
43088 };
43089diff -urNp linux-2.6.30.4/net/sctp/socket.c linux-2.6.30.4/net/sctp/socket.c
43090--- linux-2.6.30.4/net/sctp/socket.c 2009-07-24 17:47:51.000000000 -0400
43091+++ linux-2.6.30.4/net/sctp/socket.c 2009-07-30 09:48:10.161030758 -0400
2380c486
JR
43092@@ -1434,7 +1434,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
43093 struct sctp_sndrcvinfo *sinfo;
43094 struct sctp_initmsg *sinit;
43095 sctp_assoc_t associd = 0;
43096- sctp_cmsgs_t cmsgs = { NULL };
43097+ sctp_cmsgs_t cmsgs = { NULL, NULL };
43098 int err;
43099 sctp_scope_t scope;
43100 long timeo;
017d2877 43101@@ -5750,7 +5750,6 @@ pp_found:
2380c486
JR
43102 */
43103 int reuse = sk->sk_reuse;
43104 struct sock *sk2;
43105- struct hlist_node *node;
43106
43107 SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
43108 if (pp->fastreuse && sk->sk_reuse &&
017d2877
AM
43109diff -urNp linux-2.6.30.4/net/socket.c linux-2.6.30.4/net/socket.c
43110--- linux-2.6.30.4/net/socket.c 2009-07-24 17:47:51.000000000 -0400
43111+++ linux-2.6.30.4/net/socket.c 2009-07-30 11:29:24.032618401 -0400
2380c486
JR
43112@@ -86,6 +86,7 @@
43113 #include <linux/audit.h>
43114 #include <linux/wireless.h>
43115 #include <linux/nsproxy.h>
43116+#include <linux/in.h>
43117
43118 #include <asm/uaccess.h>
43119 #include <asm/unistd.h>
43120@@ -96,6 +97,21 @@
43121 #include <net/sock.h>
43122 #include <linux/netfilter.h>
43123
43124+extern void gr_attach_curr_ip(const struct sock *sk);
43125+extern int gr_handle_sock_all(const int family, const int type,
43126+ const int protocol);
43127+extern int gr_handle_sock_server(const struct sockaddr *sck);
43128+extern int gr_handle_sock_server_other(const struct socket *sck);
43129+extern int gr_handle_sock_client(const struct sockaddr *sck);
43130+extern int gr_search_connect(struct socket * sock,
43131+ struct sockaddr_in * addr);
43132+extern int gr_search_bind(struct socket * sock,
43133+ struct sockaddr_in * addr);
43134+extern int gr_search_listen(struct socket * sock);
43135+extern int gr_search_accept(struct socket * sock);
43136+extern int gr_search_socket(const int domain, const int type,
43137+ const int protocol);
43138+
43139 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
43140 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
43141 unsigned long nr_segs, loff_t pos);
017d2877
AM
43142@@ -285,7 +301,7 @@ static int init_inodecache(void)
43143 return 0;
43144 }
43145
43146-static struct super_operations sockfs_ops = {
43147+static const struct super_operations sockfs_ops = {
43148 .alloc_inode = sock_alloc_inode,
43149 .destroy_inode =sock_destroy_inode,
43150 .statfs = simple_statfs,
2380c486
JR
43151@@ -299,7 +315,7 @@ static int sockfs_get_sb(struct file_sys
43152 mnt);
43153 }
43154
43155-static struct vfsmount *sock_mnt __read_mostly;
43156+struct vfsmount *sock_mnt __read_mostly;
43157
43158 static struct file_system_type sock_fs_type = {
43159 .name = "sockfs",
017d2877 43160@@ -1283,6 +1299,16 @@ SYSCALL_DEFINE3(socket, int, family, int
2380c486
JR
43161 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
43162 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
43163
43164+ if(!gr_search_socket(family, type, protocol)) {
43165+ retval = -EACCES;
43166+ goto out;
43167+ }
43168+
43169+ if (gr_handle_sock_all(family, type, protocol)) {
43170+ retval = -EACCES;
43171+ goto out;
43172+ }
43173+
43174 retval = sock_create(family, type, protocol, &sock);
43175 if (retval < 0)
43176 goto out;
017d2877 43177@@ -1415,6 +1441,14 @@ SYSCALL_DEFINE3(bind, int, fd, struct so
2380c486
JR
43178 if (sock) {
43179 err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
43180 if (err >= 0) {
43181+ if (gr_handle_sock_server((struct sockaddr *)&address)) {
43182+ err = -EACCES;
43183+ goto error;
43184+ }
43185+ err = gr_search_bind(sock, (struct sockaddr_in *)&address);
43186+ if (err)
43187+ goto error;
43188+
43189 err = security_socket_bind(sock,
43190 (struct sockaddr *)&address,
43191 addrlen);
017d2877 43192@@ -1423,6 +1457,7 @@ SYSCALL_DEFINE3(bind, int, fd, struct so
2380c486
JR
43193 (struct sockaddr *)
43194 &address, addrlen);
43195 }
43196+error:
43197 fput_light(sock->file, fput_needed);
43198 }
43199 return err;
017d2877 43200@@ -1446,10 +1481,20 @@ SYSCALL_DEFINE2(listen, int, fd, int, ba
2380c486
JR
43201 if ((unsigned)backlog > somaxconn)
43202 backlog = somaxconn;
43203
43204+ if (gr_handle_sock_server_other(sock)) {
43205+ err = -EPERM;
43206+ goto error;
43207+ }
43208+
43209+ err = gr_search_listen(sock);
43210+ if (err)
43211+ goto error;
43212+
43213 err = security_socket_listen(sock, backlog);
43214 if (!err)
43215 err = sock->ops->listen(sock, backlog);
43216
43217+error:
43218 fput_light(sock->file, fput_needed);
43219 }
43220 return err;
017d2877 43221@@ -1492,6 +1537,18 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
2380c486
JR
43222 newsock->type = sock->type;
43223 newsock->ops = sock->ops;
43224
43225+ if (gr_handle_sock_server_other(sock)) {
43226+ err = -EPERM;
43227+ sock_release(newsock);
43228+ goto out_put;
43229+ }
43230+
43231+ err = gr_search_accept(sock);
43232+ if (err) {
43233+ sock_release(newsock);
43234+ goto out_put;
43235+ }
43236+
43237 /*
43238 * We don't need try_module_get here, as the listening socket (sock)
43239 * has the protocol module (sock->ops->owner) held.
017d2877
AM
43240@@ -1534,6 +1591,8 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
43241 fd_install(newfd, newfile);
2380c486
JR
43242 err = newfd;
43243
2380c486 43244+ gr_attach_curr_ip(newsock->sk);
017d2877 43245+
2380c486
JR
43246 out_put:
43247 fput_light(sock->file, fput_needed);
017d2877
AM
43248 out:
43249@@ -1571,6 +1630,7 @@ SYSCALL_DEFINE3(connect, int, fd, struct
2380c486
JR
43250 int, addrlen)
43251 {
43252 struct socket *sock;
43253+ struct sockaddr *sck;
43254 struct sockaddr_storage address;
43255 int err, fput_needed;
43256
017d2877 43257@@ -1581,6 +1641,17 @@ SYSCALL_DEFINE3(connect, int, fd, struct
2380c486
JR
43258 if (err < 0)
43259 goto out_put;
43260
43261+ sck = (struct sockaddr *)&address;
43262+
43263+ if (gr_handle_sock_client(sck)) {
43264+ err = -EACCES;
43265+ goto out_put;
43266+ }
43267+
43268+ err = gr_search_connect(sock, (struct sockaddr_in *)sck);
43269+ if (err)
43270+ goto out_put;
43271+
43272 err =
43273 security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
43274 if (err)
017d2877
AM
43275diff -urNp linux-2.6.30.4/net/sunrpc/rpc_pipe.c linux-2.6.30.4/net/sunrpc/rpc_pipe.c
43276--- linux-2.6.30.4/net/sunrpc/rpc_pipe.c 2009-07-24 17:47:51.000000000 -0400
43277+++ linux-2.6.30.4/net/sunrpc/rpc_pipe.c 2009-07-30 12:07:21.048974939 -0400
43278@@ -858,7 +858,7 @@ EXPORT_SYMBOL_GPL(rpc_unlink);
43279 /*
43280 * populate the filesystem
43281 */
43282-static struct super_operations s_ops = {
43283+static const struct super_operations s_ops = {
43284 .alloc_inode = rpc_alloc_inode,
43285 .destroy_inode = rpc_destroy_inode,
43286 .statfs = simple_statfs,
43287diff -urNp linux-2.6.30.4/net/unix/af_unix.c linux-2.6.30.4/net/unix/af_unix.c
43288--- linux-2.6.30.4/net/unix/af_unix.c 2009-07-24 17:47:51.000000000 -0400
43289+++ linux-2.6.30.4/net/unix/af_unix.c 2009-07-30 11:10:49.995552784 -0400
2380c486
JR
43290@@ -734,6 +734,12 @@ static struct sock *unix_find_other(stru
43291 err = -ECONNREFUSED;
43292 if (!S_ISSOCK(inode->i_mode))
43293 goto put_fail;
43294+
43295+ if (!gr_acl_handle_unix(path.dentry, path.mnt)) {
43296+ err = -EACCES;
43297+ goto put_fail;
43298+ }
43299+
43300 u = unix_find_socket_byinode(net, inode);
43301 if (!u)
43302 goto put_fail;
43303@@ -754,6 +760,13 @@ static struct sock *unix_find_other(stru
43304 if (u) {
43305 struct dentry *dentry;
43306 dentry = unix_sk(u)->dentry;
43307+
43308+ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
43309+ err = -EPERM;
43310+ sock_put(u);
43311+ goto fail;
43312+ }
43313+
43314 if (dentry)
43315 touch_atime(unix_sk(u)->mnt, dentry);
43316 } else
43317@@ -839,11 +852,18 @@ static int unix_bind(struct socket *sock
43318 err = security_path_mknod(&nd.path, dentry, mode, 0);
43319 if (err)
43320 goto out_mknod_drop_write;
43321+ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
43322+ err = -EACCES;
43323+ goto out_mknod_drop_write;
43324+ }
43325 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
43326 out_mknod_drop_write:
43327 mnt_drop_write(nd.path.mnt);
43328 if (err)
43329 goto out_mknod_dput;
43330+
43331+ gr_handle_create(dentry, nd.path.mnt);
43332+
43333 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
43334 dput(nd.path.dentry);
43335 nd.path.dentry = dentry;
43336@@ -861,6 +881,10 @@ out_mknod_drop_write:
43337 goto out_unlock;
43338 }
43339
43340+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
43341+ sk->sk_peercred.pid = current->pid;
43342+#endif
43343+
43344 list = &unix_socket_table[addr->hash];
43345 } else {
43346 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
017d2877
AM
43347diff -urNp linux-2.6.30.4/net/xfrm/xfrm_proc.c linux-2.6.30.4/net/xfrm/xfrm_proc.c
43348--- linux-2.6.30.4/net/xfrm/xfrm_proc.c 2009-07-24 17:47:51.000000000 -0400
43349+++ linux-2.6.30.4/net/xfrm/xfrm_proc.c 2009-07-30 09:48:10.161962049 -0400
43350@@ -60,7 +60,7 @@ static int xfrm_statistics_seq_open(stru
43351 return single_open_net(inode, file, xfrm_statistics_seq_show);
43352 }
43353
43354-static struct file_operations xfrm_statistics_seq_fops = {
43355+static const struct file_operations xfrm_statistics_seq_fops = {
43356 .owner = THIS_MODULE,
43357 .open = xfrm_statistics_seq_open,
43358 .read = seq_read,
43359diff -urNp linux-2.6.30.4/samples/markers/marker-example.c linux-2.6.30.4/samples/markers/marker-example.c
43360--- linux-2.6.30.4/samples/markers/marker-example.c 2009-07-24 17:47:51.000000000 -0400
43361+++ linux-2.6.30.4/samples/markers/marker-example.c 2009-07-30 09:48:10.161962049 -0400
43362@@ -26,7 +26,7 @@ static int my_open(struct inode *inode,
43363 return -EPERM;
43364 }
43365
43366-static struct file_operations mark_ops = {
43367+static const struct file_operations mark_ops = {
43368 .open = my_open,
43369 };
43370
43371diff -urNp linux-2.6.30.4/samples/tracepoints/tracepoint-sample.c linux-2.6.30.4/samples/tracepoints/tracepoint-sample.c
43372--- linux-2.6.30.4/samples/tracepoints/tracepoint-sample.c 2009-07-24 17:47:51.000000000 -0400
43373+++ linux-2.6.30.4/samples/tracepoints/tracepoint-sample.c 2009-07-30 09:48:10.161962049 -0400
43374@@ -28,7 +28,7 @@ static int my_open(struct inode *inode,
43375 return -EPERM;
43376 }
43377
43378-static struct file_operations mark_ops = {
43379+static const struct file_operations mark_ops = {
43380 .open = my_open,
43381 };
43382
43383diff -urNp linux-2.6.30.4/scripts/mod/modpost.c linux-2.6.30.4/scripts/mod/modpost.c
43384--- linux-2.6.30.4/scripts/mod/modpost.c 2009-07-24 17:47:51.000000000 -0400
43385+++ linux-2.6.30.4/scripts/mod/modpost.c 2009-07-30 09:48:10.162851614 -0400
43386@@ -831,6 +831,7 @@ enum mismatch {
2380c486
JR
43387 INIT_TO_EXIT,
43388 EXIT_TO_INIT,
43389 EXPORT_TO_INIT_EXIT,
43390+ DATA_TO_TEXT
43391 };
43392
43393 struct sectioncheck {
017d2877 43394@@ -892,6 +893,12 @@ const struct sectioncheck sectioncheck[]
2380c486
JR
43395 .fromsec = { "__ksymtab*", NULL },
43396 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
43397 .mismatch = EXPORT_TO_INIT_EXIT
43398+},
43399+/* Do not reference code from writable data */
43400+{
43401+ .fromsec = { DATA_SECTIONS, NULL },
43402+ .tosec = { TEXT_SECTIONS, NULL },
43403+ .mismatch = DATA_TO_TEXT
43404 }
43405 };
43406
017d2877 43407@@ -1240,6 +1247,14 @@ static void report_sec_mismatch(const ch
2380c486
JR
43408 "Fix this by removing the %sannotation of %s "
43409 "or drop the export.\n",
43410 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
43411+ case DATA_TO_TEXT:
43412+/*
43413+ fprintf(stderr,
43414+ "The variable %s references\n"
43415+ "the %s %s%s%s\n"
43416+ fromsym, to, sec2annotation(tosec), tosym, to_p);
43417+*/
43418+ break;
43419 case NO_MISMATCH:
43420 /* To get warnings on missing members */
43421 break;
017d2877
AM
43422diff -urNp linux-2.6.30.4/scripts/pnmtologo.c linux-2.6.30.4/scripts/pnmtologo.c
43423--- linux-2.6.30.4/scripts/pnmtologo.c 2009-07-24 17:47:51.000000000 -0400
43424+++ linux-2.6.30.4/scripts/pnmtologo.c 2009-07-30 09:48:10.162851614 -0400
2380c486
JR
43425@@ -237,14 +237,14 @@ static void write_header(void)
43426 fprintf(out, " * Linux logo %s\n", logoname);
43427 fputs(" */\n\n", out);
43428 fputs("#include <linux/linux_logo.h>\n\n", out);
43429- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
43430+ fprintf(out, "static unsigned char %s_data[] = {\n",
43431 logoname);
43432 }
43433
43434 static void write_footer(void)
43435 {
43436 fputs("\n};\n\n", out);
43437- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
43438+ fprintf(out, "struct linux_logo %s = {\n", logoname);
43439 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
43440 fprintf(out, " .width\t= %d,\n", logo_width);
43441 fprintf(out, " .height\t= %d,\n", logo_height);
43442@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
43443 fputs("\n};\n\n", out);
43444
43445 /* write logo clut */
43446- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
43447+ fprintf(out, "static unsigned char %s_clut[] = {\n",
43448 logoname);
43449 write_hex_cnt = 0;
43450 for (i = 0; i < logo_clutsize; i++) {
017d2877
AM
43451diff -urNp linux-2.6.30.4/security/commoncap.c linux-2.6.30.4/security/commoncap.c
43452--- linux-2.6.30.4/security/commoncap.c 2009-07-24 17:47:51.000000000 -0400
43453+++ linux-2.6.30.4/security/commoncap.c 2009-07-30 11:10:50.017289381 -0400
43454@@ -29,9 +29,11 @@
2380c486 43455 #include <linux/securebits.h>
017d2877 43456 #include <linux/vs_context.h>
2380c486
JR
43457
43458+extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
43459+
43460 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
43461 {
017d2877
AM
43462- NETLINK_CB(skb).eff_cap = vx_mbcaps(current_cap());
43463+ NETLINK_CB(skb).eff_cap = vx_mbcaps(gr_cap_rtnetlink(sk));
43464 return 0;
43465 }
43466
43467diff -urNp linux-2.6.30.4/security/integrity/ima/ima_fs.c linux-2.6.30.4/security/integrity/ima/ima_fs.c
43468--- linux-2.6.30.4/security/integrity/ima/ima_fs.c 2009-07-24 17:47:51.000000000 -0400
43469+++ linux-2.6.30.4/security/integrity/ima/ima_fs.c 2009-07-30 12:06:52.190847656 -0400
43470@@ -42,7 +42,7 @@ static ssize_t ima_show_htable_violation
43471 return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
43472 }
43473
43474-static struct file_operations ima_htable_violations_ops = {
43475+static const struct file_operations ima_htable_violations_ops = {
43476 .read = ima_show_htable_violations
43477 };
43478
43479@@ -54,7 +54,7 @@ static ssize_t ima_show_measurements_cou
43480
43481 }
43482
43483-static struct file_operations ima_measurements_count_ops = {
43484+static const struct file_operations ima_measurements_count_ops = {
43485 .read = ima_show_measurements_count
43486 };
43487
43488@@ -145,7 +145,7 @@ static int ima_measurements_show(struct
2380c486
JR
43489 return 0;
43490 }
43491
017d2877
AM
43492-static struct seq_operations ima_measurments_seqops = {
43493+static const struct seq_operations ima_measurments_seqops = {
43494 .start = ima_measurements_start,
43495 .next = ima_measurements_next,
43496 .stop = ima_measurements_stop,
43497@@ -157,7 +157,7 @@ static int ima_measurements_open(struct
43498 return seq_open(file, &ima_measurments_seqops);
43499 }
43500
43501-static struct file_operations ima_measurements_ops = {
43502+static const struct file_operations ima_measurements_ops = {
43503 .open = ima_measurements_open,
43504 .read = seq_read,
43505 .llseek = seq_lseek,
43506@@ -220,7 +220,7 @@ static int ima_ascii_measurements_show(s
43507 return 0;
43508 }
43509
43510-static struct seq_operations ima_ascii_measurements_seqops = {
43511+static const struct seq_operations ima_ascii_measurements_seqops = {
43512 .start = ima_measurements_start,
43513 .next = ima_measurements_next,
43514 .stop = ima_measurements_stop,
43515@@ -232,7 +232,7 @@ static int ima_ascii_measurements_open(s
43516 return seq_open(file, &ima_ascii_measurements_seqops);
43517 }
43518
43519-static struct file_operations ima_ascii_measurements_ops = {
43520+static const struct file_operations ima_ascii_measurements_ops = {
43521 .open = ima_ascii_measurements_open,
43522 .read = seq_read,
43523 .llseek = seq_lseek,
43524@@ -309,7 +309,7 @@ static int ima_release_policy(struct ino
43525 return 0;
43526 }
43527
43528-static struct file_operations ima_measure_policy_ops = {
43529+static const struct file_operations ima_measure_policy_ops = {
43530 .open = ima_open_policy,
43531 .write = ima_write_policy,
43532 .release = ima_release_policy
43533diff -urNp linux-2.6.30.4/security/Kconfig linux-2.6.30.4/security/Kconfig
43534--- linux-2.6.30.4/security/Kconfig 2009-07-24 17:47:51.000000000 -0400
43535+++ linux-2.6.30.4/security/Kconfig 2009-07-30 11:10:50.021298651 -0400
43536@@ -4,6 +4,467 @@
2380c486
JR
43537
43538 menu "Security options"
43539
43540+source grsecurity/Kconfig
43541+
43542+menu "PaX"
43543+
43544+config PAX
43545+ bool "Enable various PaX features"
43546+ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
43547+ help
43548+ This allows you to enable various PaX features. PaX adds
43549+ intrusion prevention mechanisms to the kernel that reduce
43550+ the risks posed by exploitable memory corruption bugs.
43551+
43552+menu "PaX Control"
43553+ depends on PAX
43554+
43555+config PAX_SOFTMODE
43556+ bool 'Support soft mode'
43557+ help
43558+ Enabling this option will allow you to run PaX in soft mode, that
43559+ is, PaX features will not be enforced by default, only on executables
43560+ marked explicitly. You must also enable PT_PAX_FLAGS support as it
43561+ is the only way to mark executables for soft mode use.
43562+
43563+ Soft mode can be activated by using the "pax_softmode=1" kernel command
43564+ line option on boot. Furthermore you can control various PaX features
43565+ at runtime via the entries in /proc/sys/kernel/pax.
43566+
43567+config PAX_EI_PAX
43568+ bool 'Use legacy ELF header marking'
43569+ help
43570+ Enabling this option will allow you to control PaX features on
43571+ a per executable basis via the 'chpax' utility available at
43572+ http://pax.grsecurity.net/. The control flags will be read from
43573+ an otherwise reserved part of the ELF header. This marking has
43574+ numerous drawbacks (no support for soft-mode, toolchain does not
43575+ know about the non-standard use of the ELF header) therefore it
43576+ has been deprecated in favour of PT_PAX_FLAGS support.
43577+
43578+ If you have applications not marked by the PT_PAX_FLAGS ELF
43579+ program header then you MUST enable this option otherwise they
43580+ will not get any protection.
43581+
43582+ Note that if you enable PT_PAX_FLAGS marking support as well,
43583+ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
43584+
43585+config PAX_PT_PAX_FLAGS
43586+ bool 'Use ELF program header marking'
43587+ help
43588+ Enabling this option will allow you to control PaX features on
43589+ a per executable basis via the 'paxctl' utility available at
43590+ http://pax.grsecurity.net/. The control flags will be read from
43591+ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
43592+ has the benefits of supporting both soft mode and being fully
43593+ integrated into the toolchain (the binutils patch is available
43594+ from http://pax.grsecurity.net).
43595+
43596+ If you have applications not marked by the PT_PAX_FLAGS ELF
43597+ program header then you MUST enable the EI_PAX marking support
43598+ otherwise they will not get any protection.
43599+
43600+ Note that if you enable the legacy EI_PAX marking support as well,
43601+ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
43602+
43603+choice
43604+ prompt 'MAC system integration'
43605+ default PAX_HAVE_ACL_FLAGS
43606+ help
43607+ Mandatory Access Control systems have the option of controlling
43608+ PaX flags on a per executable basis, choose the method supported
43609+ by your particular system.
43610+
43611+ - "none": if your MAC system does not interact with PaX,
43612+ - "direct": if your MAC system defines pax_set_initial_flags() itself,
43613+ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
43614+
43615+ NOTE: this option is for developers/integrators only.
43616+
43617+ config PAX_NO_ACL_FLAGS
43618+ bool 'none'
43619+
43620+ config PAX_HAVE_ACL_FLAGS
43621+ bool 'direct'
43622+
43623+ config PAX_HOOK_ACL_FLAGS
43624+ bool 'hook'
43625+endchoice
43626+
43627+endmenu
43628+
43629+menu "Non-executable pages"
43630+ depends on PAX
43631+
43632+config PAX_NOEXEC
43633+ bool "Enforce non-executable pages"
43634+ 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)
43635+ help
43636+ By design some architectures do not allow for protecting memory
43637+ pages against execution or even if they do, Linux does not make
43638+ use of this feature. In practice this means that if a page is
43639+ readable (such as the stack or heap) it is also executable.
43640+
43641+ There is a well known exploit technique that makes use of this
43642+ fact and a common programming mistake where an attacker can
43643+ introduce code of his choice somewhere in the attacked program's
43644+ memory (typically the stack or the heap) and then execute it.
43645+
43646+ If the attacked program was running with different (typically
43647+ higher) privileges than that of the attacker, then he can elevate
43648+ his own privilege level (e.g. get a root shell, write to files for
43649+ which he does not have write access to, etc).
43650+
43651+ Enabling this option will let you choose from various features
43652+ that prevent the injection and execution of 'foreign' code in
43653+ a program.
43654+
43655+ This will also break programs that rely on the old behaviour and
43656+ expect that dynamically allocated memory via the malloc() family
43657+ of functions is executable (which it is not). Notable examples
43658+ are the XFree86 4.x server, the java runtime and wine.
43659+
43660+config PAX_PAGEEXEC
43661+ bool "Paging based non-executable pages"
017d2877 43662+ depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7)
2380c486
JR
43663+ help
43664+ This implementation is based on the paging feature of the CPU.
43665+ On i386 without hardware non-executable bit support there is a
43666+ variable but usually low performance impact, however on Intel's
43667+ P4 core based CPUs it is very high so you should not enable this
43668+ for kernels meant to be used on such CPUs.
43669+
43670+ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
43671+ with hardware non-executable bit support there is no performance
43672+ impact, on ppc the impact is negligible.
43673+
43674+ Note that several architectures require various emulations due to
43675+ badly designed userland ABIs, this will cause a performance impact
43676+ but will disappear as soon as userland is fixed (e.g., ppc users
43677+ can make use of the secure-plt feature found in binutils).
43678+
43679+config PAX_SEGMEXEC
43680+ bool "Segmentation based non-executable pages"
017d2877 43681+ depends on PAX_NOEXEC && X86_32
2380c486
JR
43682+ help
43683+ This implementation is based on the segmentation feature of the
43684+ CPU and has a very small performance impact, however applications
43685+ will be limited to a 1.5 GB address space instead of the normal
43686+ 3 GB.
43687+
43688+config PAX_EMUTRAMP
43689+ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
43690+ default y if PARISC || PPC32
43691+ help
43692+ There are some programs and libraries that for one reason or
43693+ another attempt to execute special small code snippets from
43694+ non-executable memory pages. Most notable examples are the
43695+ signal handler return code generated by the kernel itself and
43696+ the GCC trampolines.
43697+
43698+ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
43699+ such programs will no longer work under your kernel.
43700+
43701+ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
43702+ utilities to enable trampoline emulation for the affected programs
43703+ yet still have the protection provided by the non-executable pages.
43704+
43705+ On parisc and ppc you MUST enable this option and EMUSIGRT as
43706+ well, otherwise your system will not even boot.
43707+
43708+ Alternatively you can say N here and use the 'chpax' or 'paxctl'
43709+ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
43710+ for the affected files.
43711+
43712+ NOTE: enabling this feature *may* open up a loophole in the
43713+ protection provided by non-executable pages that an attacker
43714+ could abuse. Therefore the best solution is to not have any
43715+ files on your system that would require this option. This can
43716+ be achieved by not using libc5 (which relies on the kernel
43717+ signal handler return code) and not using or rewriting programs
43718+ that make use of the nested function implementation of GCC.
43719+ Skilled users can just fix GCC itself so that it implements
43720+ nested function calls in a way that does not interfere with PaX.
43721+
43722+config PAX_EMUSIGRT
43723+ bool "Automatically emulate sigreturn trampolines"
43724+ depends on PAX_EMUTRAMP && (PARISC || PPC32)
43725+ default y
43726+ help
43727+ Enabling this option will have the kernel automatically detect
43728+ and emulate signal return trampolines executing on the stack
43729+ that would otherwise lead to task termination.
43730+
43731+ This solution is intended as a temporary one for users with
43732+ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
43733+ Modula-3 runtime, etc) or executables linked to such, basically
43734+ everything that does not specify its own SA_RESTORER function in
43735+ normal executable memory like glibc 2.1+ does.
43736+
43737+ On parisc and ppc you MUST enable this option, otherwise your
43738+ system will not even boot.
43739+
43740+ NOTE: this feature cannot be disabled on a per executable basis
43741+ and since it *does* open up a loophole in the protection provided
43742+ by non-executable pages, the best solution is to not have any
43743+ files on your system that would require this option.
43744+
43745+config PAX_MPROTECT
43746+ bool "Restrict mprotect()"
43747+ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
43748+ help
43749+ Enabling this option will prevent programs from
43750+ - changing the executable status of memory pages that were
43751+ not originally created as executable,
43752+ - making read-only executable pages writable again,
43753+ - creating executable pages from anonymous memory.
43754+
43755+ You should say Y here to complete the protection provided by
43756+ the enforcement of non-executable pages.
43757+
43758+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
43759+ this feature on a per file basis.
43760+
43761+config PAX_NOELFRELOCS
43762+ bool "Disallow ELF text relocations"
43763+ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86)
43764+ help
43765+ Non-executable pages and mprotect() restrictions are effective
43766+ in preventing the introduction of new executable code into an
43767+ attacked task's address space. There remain only two venues
43768+ for this kind of attack: if the attacker can execute already
43769+ existing code in the attacked task then he can either have it
43770+ create and mmap() a file containing his code or have it mmap()
43771+ an already existing ELF library that does not have position
43772+ independent code in it and use mprotect() on it to make it
43773+ writable and copy his code there. While protecting against
43774+ the former approach is beyond PaX, the latter can be prevented
43775+ by having only PIC ELF libraries on one's system (which do not
43776+ need to relocate their code). If you are sure this is your case,
43777+ then enable this option otherwise be careful as you may not even
43778+ be able to boot or log on your system (for example, some PAM
43779+ modules are erroneously compiled as non-PIC by default).
43780+
43781+ NOTE: if you are using dynamic ELF executables (as suggested
43782+ when using ASLR) then you must have made sure that you linked
43783+ your files using the PIC version of crt1 (the et_dyn.tar.gz package
43784+ referenced there has already been updated to support this).
43785+
43786+config PAX_ETEXECRELOCS
43787+ bool "Allow ELF ET_EXEC text relocations"
43788+ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
43789+ default y
43790+ help
43791+ On some architectures there are incorrectly created applications
43792+ that require text relocations and would not work without enabling
43793+ this option. If you are an alpha, ia64 or parisc user, you should
43794+ enable this option and disable it once you have made sure that
43795+ none of your applications need it.
43796+
43797+config PAX_EMUPLT
43798+ bool "Automatically emulate ELF PLT"
43799+ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
43800+ default y
43801+ help
43802+ Enabling this option will have the kernel automatically detect
43803+ and emulate the Procedure Linkage Table entries in ELF files.
43804+ On some architectures such entries are in writable memory, and
43805+ become non-executable leading to task termination. Therefore
43806+ it is mandatory that you enable this option on alpha, parisc,
43807+ ppc (if secure-plt is not used throughout in userland), sparc
43808+ and sparc64, otherwise your system would not even boot.
43809+
43810+ NOTE: this feature *does* open up a loophole in the protection
43811+ provided by the non-executable pages, therefore the proper
43812+ solution is to modify the toolchain to produce a PLT that does
43813+ not need to be writable.
43814+
43815+config PAX_DLRESOLVE
43816+ bool
43817+ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
43818+ default y
43819+
43820+config PAX_SYSCALL
43821+ bool
43822+ depends on PAX_PAGEEXEC && PPC32
43823+ default y
43824+
43825+config PAX_KERNEXEC
43826+ bool "Enforce non-executable kernel pages"
017d2877 43827+ depends on PAX_NOEXEC && X86 && (!X86_32 || X86_WP_WORKS_OK)
2380c486
JR
43828+ help
43829+ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
43830+ that is, enabling this option will make it harder to inject
43831+ and execute 'foreign' code in kernel memory itself.
43832+
43833+endmenu
43834+
43835+menu "Address Space Layout Randomization"
43836+ depends on PAX
43837+
43838+config PAX_ASLR
43839+ bool "Address Space Layout Randomization"
43840+ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
43841+ help
43842+ Many if not most exploit techniques rely on the knowledge of
43843+ certain addresses in the attacked program. The following options
43844+ will allow the kernel to apply a certain amount of randomization
43845+ to specific parts of the program thereby forcing an attacker to
43846+ guess them in most cases. Any failed guess will most likely crash
43847+ the attacked program which allows the kernel to detect such attempts
43848+ and react on them. PaX itself provides no reaction mechanisms,
43849+ instead it is strongly encouraged that you make use of Nergal's
43850+ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
43851+ (http://www.grsecurity.net/) built-in crash detection features or
43852+ develop one yourself.
43853+
43854+ By saying Y here you can choose to randomize the following areas:
43855+ - top of the task's kernel stack
43856+ - top of the task's userland stack
43857+ - base address for mmap() requests that do not specify one
43858+ (this includes all libraries)
43859+ - base address of the main executable
43860+
43861+ It is strongly recommended to say Y here as address space layout
43862+ randomization has negligible impact on performance yet it provides
43863+ a very effective protection.
43864+
43865+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
43866+ this feature on a per file basis.
43867+
43868+config PAX_RANDKSTACK
43869+ bool "Randomize kernel stack base"
43870+ depends on PAX_ASLR && X86_TSC && X86_32
43871+ help
43872+ By saying Y here the kernel will randomize every task's kernel
43873+ stack on every system call. This will not only force an attacker
43874+ to guess it but also prevent him from making use of possible
43875+ leaked information about it.
43876+
43877+ Since the kernel stack is a rather scarce resource, randomization
43878+ may cause unexpected stack overflows, therefore you should very
43879+ carefully test your system. Note that once enabled in the kernel
43880+ configuration, this feature cannot be disabled on a per file basis.
43881+
43882+config PAX_RANDUSTACK
43883+ bool "Randomize user stack base"
43884+ depends on PAX_ASLR
43885+ help
43886+ By saying Y here the kernel will randomize every task's userland
43887+ stack. The randomization is done in two steps where the second
43888+ one may apply a big amount of shift to the top of the stack and
43889+ cause problems for programs that want to use lots of memory (more
43890+ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
43891+ For this reason the second step can be controlled by 'chpax' or
43892+ 'paxctl' on a per file basis.
43893+
43894+config PAX_RANDMMAP
43895+ bool "Randomize mmap() base"
43896+ depends on PAX_ASLR
43897+ help
43898+ By saying Y here the kernel will use a randomized base address for
43899+ mmap() requests that do not specify one themselves. As a result
43900+ all dynamically loaded libraries will appear at random addresses
43901+ and therefore be harder to exploit by a technique where an attacker
43902+ attempts to execute library code for his purposes (e.g. spawn a
43903+ shell from an exploited program that is running at an elevated
43904+ privilege level).
43905+
43906+ Furthermore, if a program is relinked as a dynamic ELF file, its
43907+ base address will be randomized as well, completing the full
43908+ randomization of the address space layout. Attacking such programs
43909+ becomes a guess game. You can find an example of doing this at
43910+ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
43911+ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
43912+
43913+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
43914+ feature on a per file basis.
43915+
43916+endmenu
43917+
43918+menu "Miscellaneous hardening features"
43919+
43920+config PAX_MEMORY_SANITIZE
43921+ bool "Sanitize all freed memory"
43922+ help
43923+ By saying Y here the kernel will erase memory pages as soon as they
43924+ are freed. This in turn reduces the lifetime of data stored in the
43925+ pages, making it less likely that sensitive information such as
43926+ passwords, cryptographic secrets, etc stay in memory for too long.
43927+
43928+ This is especially useful for programs whose runtime is short, long
43929+ lived processes and the kernel itself benefit from this as long as
43930+ they operate on whole memory pages and ensure timely freeing of pages
43931+ that may hold sensitive information.
43932+
43933+ The tradeoff is performance impact, on a single CPU system kernel
43934+ compilation sees a 3% slowdown, other systems and workloads may vary
43935+ and you are advised to test this feature on your expected workload
43936+ before deploying it.
43937+
43938+ Note that this feature does not protect data stored in live pages,
43939+ e.g., process memory swapped to disk may stay there for a long time.
43940+
43941+config PAX_MEMORY_UDEREF
43942+ bool "Prevent invalid userland pointer dereference"
017d2877 43943+ depends on X86_32 && !UML_X86
2380c486
JR
43944+ help
43945+ By saying Y here the kernel will be prevented from dereferencing
43946+ userland pointers in contexts where the kernel expects only kernel
43947+ pointers. This is both a useful runtime debugging feature and a
43948+ security measure that prevents exploiting a class of kernel bugs.
43949+
43950+ The tradeoff is that some virtualization solutions may experience
43951+ a huge slowdown and therefore you should not enable this feature
43952+ for kernels meant to run in such environments. Whether a given VM
43953+ solution is affected or not is best determined by simply trying it
43954+ out, the performance impact will be obvious right on boot as this
43955+ mechanism engages from very early on. A good rule of thumb is that
43956+ VMs running on CPUs without hardware virtualization support (i.e.,
43957+ the majority of IA-32 CPUs) will likely experience the slowdown.
43958+
43959+config PAX_REFCOUNT
43960+ bool "Prevent various kernel object reference counter overflows"
de855c5d 43961+ depends on GRKERNSEC && X86
2380c486
JR
43962+ help
43963+ By saying Y here the kernel will detect and prevent overflowing
43964+ various (but not all) kinds of object reference counters. Such
43965+ overflows can normally occur due to bugs only and are often, if
43966+ not always, exploitable.
43967+
43968+ The tradeoff is that data structures protected by an overflowed
43969+ refcount will never be freed and therefore will leak memory. Note
43970+ that this leak also happens even without this protection but in
43971+ that case the overflow can eventually trigger the freeing of the
43972+ data structure while it is still being used elsewhere, resulting
43973+ in the exploitable situation that this feature prevents.
43974+
43975+ Since this has a negligible performance impact, you should enable
43976+ this feature.
de855c5d
AM
43977+
43978+config PAX_USERCOPY
43979+ bool "Bounds check heap object copies between kernel and userland"
43980+ depends on X86
43981+ depends on GRKERNSEC && (SLAB || SLUB || SLOB)
43982+ help
43983+ By saying Y here the kernel will enforce the size of heap objects
43984+ when they are copied in either direction between the kernel and
43985+ userland, even if only a part of the heap object is copied.
43986+
43987+ Specifically, this checking prevents information leaking from the
43988+ kernel heap during kernel to userland copies (if the kernel heap
43989+ object is otherwise fully initialized) and prevents kernel heap
43990+ overflows during userland to kernel copies.
43991+
43992+ Note that the current implementation provides the strictest checks
43993+ for the SLUB allocator.
43994+
017d2877
AM
43995+ Since this has a negligible performance impact, you should enable
43996+ this feature.
2380c486
JR
43997+endmenu
43998+
43999+endmenu
44000+
44001 config KEYS
44002 bool "Enable access key retention support"
44003 help
017d2877
AM
44004diff -urNp linux-2.6.30.4/security/smack/smackfs.c linux-2.6.30.4/security/smack/smackfs.c
44005--- linux-2.6.30.4/security/smack/smackfs.c 2009-07-24 17:47:51.000000000 -0400
44006+++ linux-2.6.30.4/security/smack/smackfs.c 2009-07-30 09:48:10.163665437 -0400
44007@@ -186,7 +186,7 @@ static void load_seq_stop(struct seq_fil
44008 /* No-op */
44009 }
44010
44011-static struct seq_operations load_seq_ops = {
44012+static const struct seq_operations load_seq_ops = {
44013 .start = load_seq_start,
44014 .next = load_seq_next,
44015 .show = load_seq_show,
44016@@ -502,7 +502,7 @@ static void cipso_seq_stop(struct seq_fi
44017 /* No-op */
44018 }
44019
44020-static struct seq_operations cipso_seq_ops = {
44021+static const struct seq_operations cipso_seq_ops = {
44022 .start = cipso_seq_start,
44023 .stop = cipso_seq_stop,
44024 .next = cipso_seq_next,
44025@@ -696,7 +696,7 @@ static void netlbladdr_seq_stop(struct s
44026 /* No-op */
44027 }
44028
44029-static struct seq_operations netlbladdr_seq_ops = {
44030+static const struct seq_operations netlbladdr_seq_ops = {
44031 .start = netlbladdr_seq_start,
44032 .stop = netlbladdr_seq_stop,
44033 .next = netlbladdr_seq_next,
44034diff -urNp linux-2.6.30.4/sound/core/oss/pcm_oss.c linux-2.6.30.4/sound/core/oss/pcm_oss.c
44035--- linux-2.6.30.4/sound/core/oss/pcm_oss.c 2009-07-24 17:47:51.000000000 -0400
44036+++ linux-2.6.30.4/sound/core/oss/pcm_oss.c 2009-07-30 09:48:10.164791187 -0400
44037@@ -2944,8 +2944,8 @@ static void snd_pcm_oss_proc_done(struct
2380c486
JR
44038 }
44039 }
44040 #else /* !CONFIG_SND_VERBOSE_PROCFS */
44041-#define snd_pcm_oss_proc_init(pcm)
44042-#define snd_pcm_oss_proc_done(pcm)
44043+#define snd_pcm_oss_proc_init(pcm) do {} while (0)
44044+#define snd_pcm_oss_proc_done(pcm) do {} while (0)
44045 #endif /* CONFIG_SND_VERBOSE_PROCFS */
44046
44047 /*
017d2877
AM
44048diff -urNp linux-2.6.30.4/sound/core/seq/seq_lock.h linux-2.6.30.4/sound/core/seq/seq_lock.h
44049--- linux-2.6.30.4/sound/core/seq/seq_lock.h 2009-07-24 17:47:51.000000000 -0400
44050+++ linux-2.6.30.4/sound/core/seq/seq_lock.h 2009-07-30 09:48:10.164791187 -0400
2380c486
JR
44051@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
44052 #else /* SMP || CONFIG_SND_DEBUG */
44053
44054 typedef spinlock_t snd_use_lock_t; /* dummy */
44055-#define snd_use_lock_init(lockp) /**/
44056-#define snd_use_lock_use(lockp) /**/
44057-#define snd_use_lock_free(lockp) /**/
44058-#define snd_use_lock_sync(lockp) /**/
44059+#define snd_use_lock_init(lockp) do {} while (0)
44060+#define snd_use_lock_use(lockp) do {} while (0)
44061+#define snd_use_lock_free(lockp) do {} while (0)
44062+#define snd_use_lock_sync(lockp) do {} while (0)
44063
44064 #endif /* SMP || CONFIG_SND_DEBUG */
44065
017d2877
AM
44066diff -urNp linux-2.6.30.4/sound/pci/ac97/ac97_patch.c linux-2.6.30.4/sound/pci/ac97/ac97_patch.c
44067--- linux-2.6.30.4/sound/pci/ac97/ac97_patch.c 2009-07-24 17:47:51.000000000 -0400
44068+++ linux-2.6.30.4/sound/pci/ac97/ac97_patch.c 2009-07-30 09:48:10.165681860 -0400
44069@@ -1501,7 +1501,7 @@ static const struct snd_ac97_res_table a
2380c486
JR
44070 { AC97_VIDEO, 0x9f1f },
44071 { AC97_AUX, 0x9f1f },
44072 { AC97_PCM, 0x9f1f },
44073- { } /* terminator */
44074+ { 0, 0 } /* terminator */
44075 };
44076
44077 static int patch_ad1819(struct snd_ac97 * ac97)
017d2877 44078@@ -3876,7 +3876,7 @@ static struct snd_ac97_res_table lm4550_
2380c486
JR
44079 { AC97_AUX, 0x1f1f },
44080 { AC97_PCM, 0x1f1f },
44081 { AC97_REC_GAIN, 0x0f0f },
44082- { } /* terminator */
44083+ { 0, 0 } /* terminator */
44084 };
44085
44086 static int patch_lm4550(struct snd_ac97 *ac97)
017d2877
AM
44087diff -urNp linux-2.6.30.4/sound/pci/ens1370.c linux-2.6.30.4/sound/pci/ens1370.c
44088--- linux-2.6.30.4/sound/pci/ens1370.c 2009-07-24 17:47:51.000000000 -0400
44089+++ linux-2.6.30.4/sound/pci/ens1370.c 2009-07-30 09:48:10.165681860 -0400
2380c486
JR
44090@@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
44091 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
44092 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
44093 #endif
44094- { 0, }
44095+ { 0, 0, 0, 0, 0, 0, 0 }
44096 };
44097
44098 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
017d2877
AM
44099diff -urNp linux-2.6.30.4/sound/pci/intel8x0.c linux-2.6.30.4/sound/pci/intel8x0.c
44100--- linux-2.6.30.4/sound/pci/intel8x0.c 2009-07-24 17:47:51.000000000 -0400
44101+++ linux-2.6.30.4/sound/pci/intel8x0.c 2009-07-30 09:48:10.166748224 -0400
44102@@ -444,7 +444,7 @@ static struct pci_device_id snd_intel8x0
2380c486
JR
44103 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
44104 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
44105 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
44106- { 0, }
44107+ { 0, 0, 0, 0, 0, 0, 0 }
44108 };
44109
44110 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
017d2877 44111@@ -2105,7 +2105,7 @@ static struct ac97_quirk ac97_quirks[] _
2380c486
JR
44112 .type = AC97_TUNE_HP_ONLY
44113 },
44114 #endif
44115- { } /* terminator */
44116+ { 0, 0, 0, 0, NULL, 0 } /* terminator */
44117 };
44118
44119 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
017d2877
AM
44120diff -urNp linux-2.6.30.4/sound/pci/intel8x0m.c linux-2.6.30.4/sound/pci/intel8x0m.c
44121--- linux-2.6.30.4/sound/pci/intel8x0m.c 2009-07-24 17:47:51.000000000 -0400
44122+++ linux-2.6.30.4/sound/pci/intel8x0m.c 2009-07-30 09:48:10.167822693 -0400
2380c486
JR
44123@@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
44124 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
44125 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
44126 #endif
44127- { 0, }
44128+ { 0, 0, 0, 0, 0, 0, 0 }
44129 };
44130
44131 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
017d2877 44132@@ -1264,7 +1264,7 @@ static struct shortname_table {
2380c486
JR
44133 { 0x5455, "ALi M5455" },
44134 { 0x746d, "AMD AMD8111" },
44135 #endif
44136- { 0 },
44137+ { 0, NULL },
44138 };
44139
44140 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
017d2877
AM
44141diff -urNp linux-2.6.30.4/sound/usb/usx2y/us122l.c linux-2.6.30.4/sound/usb/usx2y/us122l.c
44142--- linux-2.6.30.4/sound/usb/usx2y/us122l.c 2009-07-24 17:47:51.000000000 -0400
44143+++ linux-2.6.30.4/sound/usb/usx2y/us122l.c 2009-07-30 09:48:10.167822693 -0400
44144@@ -154,7 +154,7 @@ static void usb_stream_hwdep_vm_close(st
44145 snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
44146 }
44147
44148-static struct vm_operations_struct usb_stream_hwdep_vm_ops = {
44149+static const struct vm_operations_struct usb_stream_hwdep_vm_ops = {
44150 .open = usb_stream_hwdep_vm_open,
44151 .fault = usb_stream_hwdep_vm_fault,
44152 .close = usb_stream_hwdep_vm_close,
44153diff -urNp linux-2.6.30.4/sound/usb/usx2y/usX2Yhwdep.c linux-2.6.30.4/sound/usb/usx2y/usX2Yhwdep.c
44154--- linux-2.6.30.4/sound/usb/usx2y/usX2Yhwdep.c 2009-07-24 17:47:51.000000000 -0400
44155+++ linux-2.6.30.4/sound/usb/usx2y/usX2Yhwdep.c 2009-07-30 09:48:10.167822693 -0400
44156@@ -53,7 +53,7 @@ static int snd_us428ctls_vm_fault(struct
44157 return 0;
44158 }
44159
44160-static struct vm_operations_struct us428ctls_vm_ops = {
44161+static const struct vm_operations_struct us428ctls_vm_ops = {
44162 .fault = snd_us428ctls_vm_fault,
44163 };
44164
44165diff -urNp linux-2.6.30.4/sound/usb/usx2y/usx2yhwdeppcm.c linux-2.6.30.4/sound/usb/usx2y/usx2yhwdeppcm.c
44166--- linux-2.6.30.4/sound/usb/usx2y/usx2yhwdeppcm.c 2009-07-24 17:47:51.000000000 -0400
44167+++ linux-2.6.30.4/sound/usb/usx2y/usx2yhwdeppcm.c 2009-07-30 09:48:10.168781015 -0400
44168@@ -697,7 +697,7 @@ static int snd_usX2Y_hwdep_pcm_vm_fault(
44169 }
44170
44171
44172-static struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
44173+static const struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
44174 .open = snd_usX2Y_hwdep_pcm_vm_open,
44175 .close = snd_usX2Y_hwdep_pcm_vm_close,
44176 .fault = snd_usX2Y_hwdep_pcm_vm_fault,
44177diff -urNp linux-2.6.30.4/virt/kvm/kvm_main.c linux-2.6.30.4/virt/kvm/kvm_main.c
44178--- linux-2.6.30.4/virt/kvm/kvm_main.c 2009-07-24 17:47:51.000000000 -0400
44179+++ linux-2.6.30.4/virt/kvm/kvm_main.c 2009-07-30 12:42:02.581987537 -0400
44180@@ -2061,6 +2061,9 @@ static struct miscdevice kvm_dev = {
2380c486
JR
44181 KVM_MINOR,
44182 "kvm",
44183 &kvm_chardev_ops,
44184+ {NULL, NULL},
44185+ NULL,
44186+ NULL
44187 };
44188
44189 static void hardware_enable(void *junk)
017d2877
AM
44190@@ -2220,7 +2223,7 @@ static int vcpu_stat_get(void *_offset,
44191
44192 DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n");
44193
44194-static struct file_operations *stat_fops[] = {
44195+static const struct file_operations *stat_fops[] = {
44196 [KVM_STAT_VCPU] = &vcpu_stat_fops,
44197 [KVM_STAT_VM] = &vm_stat_fops,
44198 };
44199@@ -2292,7 +2295,7 @@ static void kvm_sched_out(struct preempt
2380c486
JR
44200 kvm_arch_vcpu_put(vcpu);
44201 }
44202
44203-int kvm_init(void *opaque, unsigned int vcpu_size,
44204+int kvm_init(const void *opaque, unsigned int vcpu_size,
44205 struct module *module)
44206 {
44207 int r;
52284610
AM
44208diff -u linux-2.6.30.4/arch/x86/include/asm/uaccess.h linux-2.6.30.4/arch/x86/include/asm/uaccess.h
44209--- linux-2.6.30.4/arch/x86/include/asm/uaccess.h 2009-07-30 20:32:47.926577259 -0400
44210+++ linux-2.6.30.4/arch/x86/include/asm/uaccess.h 2009-08-09 07:48:47.926451868 -0400
44211@@ -190,16 +190,21 @@
44212 asm volatile("call __put_user_" #size : "=a" (__ret_pu) \
44213 : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
44214
44215-
44216+#ifdef CONFIG_X86_32
44217+#define _ASM_LOAD_USER_DS(ds) "movw %w" #ds ",%%ds\n"
44218+#define _ASM_LOAD_KERNEL_DS "pushl %%ss; popl %%ds\n"
44219+#else
44220+#define _ASM_LOAD_USER_DS(ds)
44221+#define _ASM_LOAD_KERNEL_DS
44222+#endif
44223
44224 #ifdef CONFIG_X86_32
44225 #define __put_user_asm_u64(x, addr, err, errret) \
44226- asm volatile(" movw %w5,%%ds\n" \
44227+ asm volatile(_ASM_LOAD_USER_DS(5) \
44228 "1: movl %%eax,%%ds:0(%2)\n" \
44229 "2: movl %%edx,%%ds:4(%2)\n" \
44230 "3:\n" \
44231- " pushl %%ss\n" \
44232- " popl %%ds\n" \
44233+ _ASM_LOAD_KERNEL_DS \
44234 ".section .fixup,\"ax\"\n" \
44235 "4: movl %3,%0\n" \
44236 " jmp 3b\n" \
44237@@ -211,12 +216,14 @@
44238 "r"(__USER_DS))
44239
44240 #define __put_user_asm_ex_u64(x, addr) \
44241- asm volatile("1: movl %%eax,0(%1)\n" \
44242- "2: movl %%edx,4(%1)\n" \
44243+ asm volatile(_ASM_LOAD_USER_DS(2) \
44244+ "1: movl %%eax,%%ds:0(%1)\n" \
44245+ "2: movl %%edx,%%ds:4(%1)\n" \
44246 "3:\n" \
44247+ _ASM_LOAD_KERNEL_DS \
44248 _ASM_EXTABLE(1b, 2b - 1b) \
44249 _ASM_EXTABLE(2b, 3b - 2b) \
44250- : : "A" (x), "r" (addr))
44251+ : : "A" (x), "r" (addr), "r"(__USER_DS))
44252
44253 #define __put_user_x8(x, ptr, __ret_pu) \
44254 asm volatile("call __put_user_8" : "=a" (__ret_pu) \
44255@@ -384,34 +391,19 @@
44256 } \
44257 } while (0)
44258
44259-#ifdef CONFIG_X86_32
44260 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
44261- asm volatile(" movw %w5,%%ds\n" \
44262+ asm volatile(_ASM_LOAD_USER_DS(5) \
44263 "1: mov"itype" %%ds:%2,%"rtype"1\n" \
44264 "2:\n" \
44265- " pushl %%ss\n" \
44266- " popl %%ds\n" \
44267+ _ASM_LOAD_KERNEL_DS \
44268 ".section .fixup,\"ax\"\n" \
44269- "3: movl %3,%0\n" \
44270+ "3: mov %3,%0\n" \
44271 " xor"itype" %"rtype"1,%"rtype"1\n" \
44272 " jmp 2b\n" \
44273 ".previous\n" \
44274 _ASM_EXTABLE(1b, 3b) \
44275 : "=r" (err), ltype (x) \
44276 : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
44277-#else
44278-#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
44279- asm volatile("1: mov"itype" %2,%"rtype"1\n" \
44280- "2:\n" \
44281- ".section .fixup,\"ax\"\n" \
44282- "3: mov %3,%0\n" \
44283- " xor"itype" %"rtype"1,%"rtype"1\n" \
44284- " jmp 2b\n" \
44285- ".previous\n" \
44286- _ASM_EXTABLE(1b, 3b) \
44287- : "=r" (err), ltype(x) \
44288- : "m" (__m(addr)), "i" (errret), "0" (err))
44289-#endif
44290
44291 #define __get_user_size_ex(x, ptr, size) \
44292 do { \
44293@@ -434,22 +426,13 @@
44294 } \
44295 } while (0)
44296
44297-#ifdef CONFIG_X86_32
44298 #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
44299- asm volatile(" movw %w2,%%ds\n" \
44300+ asm volatile(_ASM_LOAD_USER_DS(2) \
44301 "1: mov"itype" %%ds:%1,%"rtype"0\n" \
44302 "2:\n" \
44303- " pushl %%ss\n" \
44304- " popl %%ds\n" \
44305+ _ASM_LOAD_KERNEL_DS \
44306 _ASM_EXTABLE(1b, 2b - 1b) \
44307 : ltype(x) : "m" (__m(addr)), "r"(__USER_DS))
44308-#else
44309-#define __get_user_asm_ex(x, addr, itype, rtype, ltype) \
44310- asm volatile("1: mov"itype" %1,%"rtype"0\n" \
44311- "2:\n" \
44312- _ASM_EXTABLE(1b, 2b - 1b) \
44313- : ltype(x) : "m" (__m(addr)))
44314-#endif
44315
44316 #define __put_user_nocheck(x, ptr, size) \
44317 ({ \
44318@@ -476,50 +459,27 @@
44319 * we do not write to any memory gcc knows about, so there are no
44320 * aliasing issues.
44321 */
44322-#ifdef CONFIG_X86_32
44323 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
44324- asm volatile(" movw %w5,%%ds\n" \
44325+ asm volatile(_ASM_LOAD_USER_DS(5) \
44326 "1: mov"itype" %"rtype"1,%%ds:%2\n" \
44327 "2:\n" \
44328- " pushl %%ss\n" \
44329- " popl %%ds\n" \
44330+ _ASM_LOAD_KERNEL_DS \
44331 ".section .fixup,\"ax\"\n" \
44332- "3: movl %3,%0\n" \
44333+ "3: mov %3,%0\n" \
44334 " jmp 2b\n" \
44335 ".previous\n" \
44336 _ASM_EXTABLE(1b, 3b) \
44337 : "=r"(err) \
44338 : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
44339 "r"(__USER_DS))
44340-#else
44341-#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
44342- asm volatile("1: mov"itype" %"rtype"1,%2\n" \
44343- "2:\n" \
44344- ".section .fixup,\"ax\"\n" \
44345- "3: mov %3,%0\n" \
44346- " jmp 2b\n" \
44347- ".previous\n" \
44348- _ASM_EXTABLE(1b, 3b) \
44349- : "=r"(err) \
44350- : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
44351-#endif
44352
44353-#ifdef CONFIG_X86_32
44354 #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \
44355- asm volatile(" movw %w2,%%ds\n" \
44356+ asm volatile(_ASM_LOAD_USER_DS(2) \
44357 "1: mov"itype" %"rtype"0,%%ds:%1\n" \
44358 "2:\n" \
44359- " pushl %%ss\n" \
44360- " popl %%ds\n" \
44361+ _ASM_LOAD_KERNEL_DS \
44362 _ASM_EXTABLE(1b, 2b - 1b) \
44363 : : ltype(x), "m" (__m(addr)), "r"(__USER_DS))
44364-#else
44365-#define __put_user_asm_ex(x, addr, itype, rtype, ltype) \
44366- asm volatile("1: mov"itype" %"rtype"0,%1\n" \
44367- "2:\n" \
44368- _ASM_EXTABLE(1b, 2b - 1b) \
44369- : : ltype(x), "m" (__m(addr)))
44370-#endif
44371
44372 /*
44373 * uaccess_try and catch
44374diff -u linux-2.6.30.4/arch/x86/Kconfig linux-2.6.30.4/arch/x86/Kconfig
44375--- linux-2.6.30.4/arch/x86/Kconfig 2009-07-30 12:32:41.330879042 -0400
44376+++ linux-2.6.30.4/arch/x86/Kconfig 2009-08-04 17:52:34.387861424 -0400
44377@@ -1471,8 +1471,7 @@
44378
44379 config PHYSICAL_START
44380 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
44381- default "0x1000000" if X86_NUMAQ
44382- default "0x200000"
44383+ default "0x1000000"
44384 ---help---
44385 This gives the physical address where the kernel is loaded.
44386
44387@@ -1531,8 +1530,7 @@
44388 config PHYSICAL_ALIGN
44389 hex
44390 prompt "Alignment value to which kernel should be aligned" if X86_32
44391- default "0x100000" if X86_32
44392- default "0x200000" if X86_64
44393+ default "0x200000"
44394 range 0x2000 0x400000
44395 ---help---
44396 This value puts the alignment restrictions on physical address
44397diff -u linux-2.6.30.4/arch/x86/kernel/entry_32.S linux-2.6.30.4/arch/x86/kernel/entry_32.S
44398--- linux-2.6.30.4/arch/x86/kernel/entry_32.S 2009-07-30 09:48:09.945662533 -0400
44399+++ linux-2.6.30.4/arch/x86/kernel/entry_32.S 2009-08-12 21:15:21.098460043 -0400
44400@@ -776,11 +776,11 @@
44401 .macro FIXUP_ESPFIX_STACK
44402 /* since we are on a wrong stack, we cant make it a C code :( */
44403 #ifdef CONFIG_SMP
44404- movl PER_CPU_VAR(cpu_number), %ebx;
44405- shll $PAGE_SHIFT_asm, %ebx;
44406- addl $cpu_gdt_table, %ebx;
44407+ movl PER_CPU_VAR(cpu_number), %ebx
44408+ shll $PAGE_SHIFT_asm, %ebx
44409+ addl $cpu_gdt_table, %ebx
44410 #else
44411- movl $cpu_gdt_table, %ebx;
44412+ movl $cpu_gdt_table, %ebx
44413 #endif
44414 GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah)
44415 addl %esp, %eax
44416diff -u linux-2.6.30.4/arch/x86/kernel/entry_64.S linux-2.6.30.4/arch/x86/kernel/entry_64.S
44417--- linux-2.6.30.4/arch/x86/kernel/entry_64.S 2009-07-30 09:48:09.945662533 -0400
44418+++ linux-2.6.30.4/arch/x86/kernel/entry_64.S 2009-08-12 21:15:21.099483377 -0400
44419@@ -1073,8 +1073,12 @@
44420 TRACE_IRQS_OFF
44421 movq %rsp,%rdi /* pt_regs pointer */
44422 xorl %esi,%esi /* no error code */
44423+#ifdef CONFIG_SMP
44424 imul $TSS_size, PER_CPU_VAR(cpu_number), %ebp
44425 lea init_tss(%rbp), %rbp
44426+#else
44427+ lea init_tss(%rip), %rbp
44428+#endif
44429 subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
44430 call \do_sym
44431 addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
44432diff -u linux-2.6.30.4/arch/x86/kernel/head_32.S linux-2.6.30.4/arch/x86/kernel/head_32.S
44433--- linux-2.6.30.4/arch/x86/kernel/head_32.S 2009-07-30 19:56:23.400350396 -0400
44434+++ linux-2.6.30.4/arch/x86/kernel/head_32.S 2009-08-05 19:08:00.458589400 -0400
44435@@ -110,6 +110,7 @@
44436 movl %eax,%gs
44437 2:
44438
44439+#ifdef CONFIG_SMP
44440 movl $pa(cpu_gdt_table),%edi
44441 movl $__per_cpu_load,%eax
44442 movw %ax,__KERNEL_PERCPU + 2(%edi)
44443@@ -119,6 +120,7 @@
44444 movl $__per_cpu_end - 1,%eax
44445 subl $__per_cpu_load,%eax
44446 movw %ax,__KERNEL_PERCPU + 0(%edi)
44447+#endif
44448
44449 #ifdef CONFIG_PAX_MEMORY_UDEREF
44450 /* check for VMware */
44451@@ -515,7 +517,9 @@
44452 jne 1f
44453 movl $cpu_gdt_table,%eax
44454 movl $per_cpu__stack_canary,%ecx
44455+#ifdef CONFIG_SMP
44456 addl $__per_cpu_load,%ecx
44457+#endif
44458 subl $20, %ecx
44459 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
44460 shrl $16, %ecx
c80fd991
AM
44461diff -u linux-2.6.30.4/arch/x86/kernel/head_64.S linux-2.6.30.4/arch/x86/kernel/head_64.S
44462--- linux-2.6.30.4/arch/x86/kernel/head_64.S 2009-07-30 09:48:09.947450201 -0400
44463+++ linux-2.6.30.4/arch/x86/kernel/head_64.S 2009-08-01 08:46:06.399105315 -0400
44464@@ -454,7 +454,7 @@
44465 .section .rodata,"a",@progbits
44466 .align L1_CACHE_BYTES
44467 ENTRY(idt_table)
44468- .fill 256,16,0
44469+ .fill 512,8,0
44470
44471 .section .bss.page_aligned, "aw", @nobits
44472 .align PAGE_SIZE
44473diff -u linux-2.6.30.4/arch/x86/kernel/module_32.c linux-2.6.30.4/arch/x86/kernel/module_32.c
44474--- linux-2.6.30.4/arch/x86/kernel/module_32.c 2009-07-30 09:48:09.950015875 -0400
44475+++ linux-2.6.30.4/arch/x86/kernel/module_32.c 2009-08-01 15:35:35.138919235 -0400
44476@@ -107,6 +107,7 @@
44477 WARN_ON(1);
44478 }
44479 }
44480+EXPORT_SYMBOL(module_free_exec);
44481 #endif
44482
44483 /* We don't need anything special. */
44484diff -u linux-2.6.30.4/arch/x86/kernel/module_64.c linux-2.6.30.4/arch/x86/kernel/module_64.c
44485--- linux-2.6.30.4/arch/x86/kernel/module_64.c 2009-07-30 09:48:09.950015875 -0400
44486+++ linux-2.6.30.4/arch/x86/kernel/module_64.c 2009-08-01 15:35:35.161871747 -0400
44487@@ -67,10 +67,12 @@
44488 {
44489 module_free(mod, module_region);
44490 }
44491+EXPORT_SYMBOL(module_free_exec);
44492
44493 void *module_alloc_exec(unsigned long size)
44494 {
44495 return __module_alloc(size, PAGE_KERNEL_RX);
44496+EXPORT_SYMBOL(module_alloc_exec);
44497 }
44498 #else
44499 void *module_alloc(unsigned long size)
52284610
AM
44500diff -u linux-2.6.30.4/arch/x86/kernel/process.c linux-2.6.30.4/arch/x86/kernel/process.c
44501--- linux-2.6.30.4/arch/x86/kernel/process.c 2009-07-30 09:48:09.950702241 -0400
44502+++ linux-2.6.30.4/arch/x86/kernel/process.c 2009-08-05 19:08:00.495411211 -0400
44503@@ -105,7 +105,7 @@
44504
44505 clear_tsk_thread_flag(tsk, TIF_DEBUG);
44506
44507-#ifndef CONFIG_CC_STACKPROTECTOR
44508+#if defined(CONFIG_X86_32) && !defined(CONFIG_CC_STACKPROTECTOR)
44509 loadsegment(gs, 0);
44510 #endif
44511 tsk->thread.debugreg0 = 0;
44512diff -u linux-2.6.30.4/arch/x86/kernel/setup_percpu.c linux-2.6.30.4/arch/x86/kernel/setup_percpu.c
44513--- linux-2.6.30.4/arch/x86/kernel/setup_percpu.c 2009-07-30 09:48:09.957530438 -0400
44514+++ linux-2.6.30.4/arch/x86/kernel/setup_percpu.c 2009-08-05 19:08:00.518752374 -0400
44515@@ -335,10 +335,9 @@
44516 {
44517 #ifdef CONFIG_X86_32
44518 struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
44519- unsigned long base, limit;
44520+ unsigned long base = per_cpu_offset(cpu);
44521+ const unsigned long limit = VMALLOC_END - base - 1;
44522
44523- base = per_cpu_offset(cpu);
44524- limit = PERCPU_ENOUGH_ROOM - 1;
44525 if (limit < 64*1024)
44526 pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
44527 else
44528diff -u linux-2.6.30.4/arch/x86/kernel/vmi_32.c linux-2.6.30.4/arch/x86/kernel/vmi_32.c
44529--- linux-2.6.30.4/arch/x86/kernel/vmi_32.c 2009-07-30 09:48:09.962543704 -0400
44530+++ linux-2.6.30.4/arch/x86/kernel/vmi_32.c 2009-08-12 21:15:21.104308164 -0400
44531@@ -466,7 +466,7 @@
44532 ap.ds = __KERNEL_DS;
44533 ap.es = __KERNEL_DS;
44534 ap.fs = __KERNEL_PERCPU;
44535- ap.gs = 0;
44536+ ap.gs = __KERNEL_STACK_CANARY;
44537
44538 ap.eflags = 0;
44539
c80fd991
AM
44540diff -u linux-2.6.30.4/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.30.4/arch/x86/kernel/vmlinux_64.lds.S
44541--- linux-2.6.30.4/arch/x86/kernel/vmlinux_64.lds.S 2009-07-30 19:56:23.500027109 -0400
44542+++ linux-2.6.30.4/arch/x86/kernel/vmlinux_64.lds.S 2009-08-01 08:46:06.438873305 -0400
44543@@ -62,8 +62,8 @@
44544 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
44545 #endif
44546 /* Data */
44547- _data = .;
44548 .data : AT(ADDR(.data) - LOAD_OFFSET) {
44549+ _data = .;
44550 DATA_DATA
44551 CONSTRUCTORS
44552 } :data
52284610
AM
44553diff -u linux-2.6.30.4/arch/x86/mm/fault.c linux-2.6.30.4/arch/x86/mm/fault.c
44554--- linux-2.6.30.4/arch/x86/mm/fault.c 2009-07-30 11:10:48.941676108 -0400
44555+++ linux-2.6.30.4/arch/x86/mm/fault.c 2009-08-05 19:15:53.629625442 -0400
44556@@ -39,6 +39,7 @@
44557 #include <asm/proto.h>
44558 #include <asm/traps.h>
44559 #include <asm/desc.h>
44560+#include <asm/vsyscall.h>
44561
44562 /*
44563 * Page fault error code bits:
44564diff -u linux-2.6.30.4/arch/x86/vdso/vclock_gettime.c linux-2.6.30.4/arch/x86/vdso/vclock_gettime.c
44565--- linux-2.6.30.4/arch/x86/vdso/vclock_gettime.c 2009-07-30 09:48:09.978662746 -0400
44566+++ linux-2.6.30.4/arch/x86/vdso/vclock_gettime.c 2009-08-05 19:15:53.673598242 -0400
44567@@ -22,6 +22,7 @@
44568 #include <asm/hpet.h>
44569 #include <asm/unistd.h>
44570 #include <asm/io.h>
44571+#include <asm/fixmap.h>
44572 #include "vextern.h"
44573
44574 #define gtod vdso_vsyscall_gtod_data
44575diff -u linux-2.6.30.4/arch/x86/xen/enlighten.c linux-2.6.30.4/arch/x86/xen/enlighten.c
44576--- linux-2.6.30.4/arch/x86/xen/enlighten.c 2009-07-30 09:48:09.980662517 -0400
44577+++ linux-2.6.30.4/arch/x86/xen/enlighten.c 2009-08-04 17:23:47.808223131 -0400
44578@@ -67,8 +67,6 @@
44579
44580 struct shared_info xen_dummy_shared_info;
44581
44582-void *xen_initial_gdt;
44583-
44584 /*
44585 * Point at some empty memory to start with. We map the real shared_info
44586 * page as soon as fixmap is up and running.
44587@@ -962,12 +960,6 @@
44588 */
44589 load_percpu_segment(0);
44590 #endif
44591- /*
44592- * The only reliable way to retain the initial address of the
44593- * percpu gdt_page is to remember it here, so we can go and
44594- * mark it RW later, when the initial percpu area is freed.
44595- */
44596- xen_initial_gdt = &per_cpu(gdt_page, 0);
44597
44598 xen_smp_init();
44599
44600diff -u linux-2.6.30.4/Documentation/dontdiff linux-2.6.30.4/Documentation/dontdiff
44601--- linux-2.6.30.4/Documentation/dontdiff 2009-07-30 09:48:09.870977266 -0400
44602+++ linux-2.6.30.4/Documentation/dontdiff 2009-08-04 17:23:49.932547446 -0400
44603@@ -113,6 +113,7 @@
44604 ihex2fw
44605 ikconfig.h*
44606 initramfs_data.cpio
44607+initramfs_data.cpio.bz2
44608 initramfs_data.cpio.gz
44609 initramfs_list
44610 kallsyms
44611@@ -196,6 +197,7 @@
44612 vmlinux-*
44613 vmlinux.aout
44614 vmlinux.bin.all
44615+vmlinux.bin.bz2
44616 vmlinux.lds
44617 vmlinux.relocs
44618 vsyscall.lds
c80fd991
AM
44619diff -u linux-2.6.30.4/fs/exec.c linux-2.6.30.4/fs/exec.c
44620--- linux-2.6.30.4/fs/exec.c 2009-07-30 11:10:49.146300194 -0400
44621+++ linux-2.6.30.4/fs/exec.c 2009-08-01 14:58:11.881121157 -0400
44622@@ -124,7 +124,7 @@
44623 goto out;
44624
44625 file = do_filp_open(AT_FDCWD, tmp,
44626- O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
44627+ O_LARGEFILE | O_RDONLY | FMODE_EXEC | FMODE_GREXEC, 0,
44628 MAY_READ | MAY_EXEC | MAY_OPEN);
44629 putname(tmp);
44630 error = PTR_ERR(file);
44631@@ -680,7 +680,7 @@
44632 int err;
44633
44634 file = do_filp_open(AT_FDCWD, name,
44635- O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
44636+ O_LARGEFILE | O_RDONLY | FMODE_EXEC | FMODE_GREXEC, 0,
44637 MAY_EXEC | MAY_OPEN);
44638 if (IS_ERR(file))
44639 goto out;
44640diff -u linux-2.6.30.4/grsecurity/gracl_fs.c linux-2.6.30.4/grsecurity/gracl_fs.c
44641--- linux-2.6.30.4/grsecurity/gracl_fs.c 2009-07-30 11:10:49.347341041 -0400
44642+++ linux-2.6.30.4/grsecurity/gracl_fs.c 2009-08-01 15:00:28.098114831 -0400
44643@@ -48,7 +48,8 @@
44644 reqmode |= GR_WRITE;
44645 if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
44646 reqmode |= GR_READ;
44647-
44648+ if ((fmode & FMODE_GREXEC) && (fmode & FMODE_EXEC))
44649+ reqmode &= ~GR_READ;
44650 mode =
44651 gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
44652 mnt);
52284610
AM
44653diff -u linux-2.6.30.4/grsecurity/grsec_init.c linux-2.6.30.4/grsecurity/grsec_init.c
44654--- linux-2.6.30.4/grsecurity/grsec_init.c 2009-07-30 12:01:03.627768838 -0400
44655+++ linux-2.6.30.4/grsecurity/grsec_init.c 2009-08-02 09:38:20.116597572 -0400
44656@@ -77,7 +77,7 @@
44657 #endif
44658
44659 for (j = 0; j < 4; j++) {
44660- gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, 0);
44661+ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(unsigned long long));
44662 if (gr_shared_page[j] == NULL) {
44663 panic("Unable to allocate grsecurity shared page");
44664 return;
44665reverted:
44666--- linux-2.6.30.4/include/asm-generic/sections.h 2009-07-30 09:48:10.105294791 -0400
44667+++ linux-2.6.30.4/include/asm-generic/sections.h 2009-07-24 17:47:51.000000000 -0400
44668@@ -9,7 +9,7 @@
44669 extern char __init_begin[], __init_end[];
44670 extern char _sinittext[], _einittext[];
44671 extern char _end[];
44672+extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
44673-extern char per_cpu_load[], __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
44674 extern char __kprobes_text_start[], __kprobes_text_end[];
44675 extern char __initdata_begin[], __initdata_end[];
44676 extern char __start_rodata[], __end_rodata[];
44677diff -u linux-2.6.30.4/include/asm-generic/vmlinux.lds.h linux-2.6.30.4/include/asm-generic/vmlinux.lds.h
44678--- linux-2.6.30.4/include/asm-generic/vmlinux.lds.h 2009-07-30 09:48:10.106233963 -0400
44679+++ linux-2.6.30.4/include/asm-generic/vmlinux.lds.h 2009-08-09 07:48:48.045905474 -0400
44680@@ -474,15 +474,15 @@
44681 * address, use PERCPU().
44682 */
44683 #define PERCPU_VADDR(vaddr, phdr) \
44684- VMLINUX_SYMBOL(per_cpu_load) = .; \
44685+ per_cpu_load = .; \
44686 .data.percpu vaddr : AT(VMLINUX_SYMBOL(per_cpu_load) \
44687 - LOAD_OFFSET) { \
44688 VMLINUX_SYMBOL(__per_cpu_load) = . + per_cpu_load; \
44689 VMLINUX_SYMBOL(__per_cpu_start) = .; \
44690 *(.data.percpu.first) \
44691+ *(.data.percpu) \
44692 . = ALIGN(PAGE_SIZE); \
44693 *(.data.percpu.page_aligned) \
44694- *(.data.percpu) \
44695 *(.data.percpu.shared_aligned) \
44696 VMLINUX_SYMBOL(__per_cpu_end) = .; \
44697 } phdr \
c80fd991
AM
44698diff -u linux-2.6.30.4/include/linux/fs.h linux-2.6.30.4/include/linux/fs.h
44699--- linux-2.6.30.4/include/linux/fs.h 2009-07-30 09:48:10.109883773 -0400
44700+++ linux-2.6.30.4/include/linux/fs.h 2009-08-01 14:57:12.341093728 -0400
44701@@ -87,6 +87,10 @@
44702 */
44703 #define FMODE_NOCMTIME ((__force fmode_t)2048)
44704
44705+/* Hack for grsec so as not to require read permission simply to execute
44706+ a binary */
44707+#define FMODE_GREXEC ((__force fmode_t)8192)
44708+
44709 /*
44710 * The below are the various read and write types that we support. Some of
44711 * them include behavioral modifiers that send information down to the
52284610
AM
44712diff -u linux-2.6.30.4/kernel/module.c linux-2.6.30.4/kernel/module.c
44713--- linux-2.6.30.4/kernel/module.c 2009-07-30 11:10:49.634551667 -0400
44714+++ linux-2.6.30.4/kernel/module.c 2009-08-04 17:52:34.401055170 -0400
44715@@ -369,8 +369,6 @@
44716
44717 #ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA
44718
44719-EXPORT_SYMBOL(__per_cpu_load);
44720-
44721 static void *percpu_modalloc(unsigned long size, unsigned long align,
44722 const char *name)
44723 {
44724@@ -433,8 +431,6 @@
44725 return val;
44726 }
44727
44728-EXPORT_SYMBOL(__per_cpu_load);
44729-
44730 static void *percpu_modalloc(unsigned long size, unsigned long align,
44731 const char *name)
44732 {
44733@@ -1646,15 +1642,9 @@
44734
44735 default:
44736 /* Divert to percpu allocation if a percpu var. */
44737- if (sym[i].st_shndx == pcpuindex) {
44738-
44739-#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
44740- secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_load;
44741-#else
44742+ if (sym[i].st_shndx == pcpuindex)
44743 secbase = (unsigned long)mod->percpu;
44744-#endif
44745-
44746- } else
44747+ else
44748 secbase = sechdrs[sym[i].st_shndx].sh_addr;
44749
44750 #ifdef CONFIG_PAX_KERNEXEC
44751diff -u linux-2.6.30.4/kernel/sysctl.c linux-2.6.30.4/kernel/sysctl.c
44752--- linux-2.6.30.4/kernel/sysctl.c 2009-07-30 11:10:49.710420812 -0400
44753+++ linux-2.6.30.4/kernel/sysctl.c 2009-08-04 17:52:34.402065998 -0400
44754@@ -265,6 +265,24 @@
44755 #endif
44756
44757 static struct ctl_table kern_table[] = {
44758+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
44759+ {
44760+ .ctl_name = CTL_UNNUMBERED,
44761+ .procname = "grsecurity",
44762+ .mode = 0500,
44763+ .child = grsecurity_table,
44764+ },
44765+#endif
44766+
44767+#ifdef CONFIG_PAX_SOFTMODE
44768+ {
44769+ .ctl_name = CTL_UNNUMBERED,
44770+ .procname = "pax",
44771+ .mode = 0500,
44772+ .child = pax_table,
44773+ },
44774+#endif
44775+
44776 #ifdef CONFIG_SCHED_DEBUG
44777 {
44778 .ctl_name = CTL_UNNUMBERED,
44779@@ -1303,25 +1321,6 @@
44780 .proc_handler = &scan_unevictable_handler,
44781 },
44782 #endif
44783-
44784-#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
44785- {
44786- .ctl_name = CTL_UNNUMBERED,
44787- .procname = "grsecurity",
44788- .mode = 0500,
44789- .child = grsecurity_table,
44790- },
44791-#endif
44792-
44793-#ifdef CONFIG_PAX_SOFTMODE
44794- {
44795- .ctl_name = CTL_UNNUMBERED,
44796- .procname = "pax",
44797- .mode = 0500,
44798- .child = pax_table,
44799- },
44800-#endif
44801-
44802 /*
44803 * NOTE: do not add new entries to this table unless you have read
44804 * Documentation/sysctl/ctl_unnumbered.txt
44805diff -u linux-2.6.30.4/net/socket.c linux-2.6.30.4/net/socket.c
44806--- linux-2.6.30.4/net/socket.c 2009-07-30 11:29:24.032618401 -0400
44807+++ linux-2.6.30.4/net/socket.c 2009-08-13 20:40:32.961482335 -0400
44808@@ -752,7 +752,7 @@
44809 if (more)
44810 flags |= MSG_MORE;
44811
44812- return sock->ops->sendpage(sock, page, offset, size, flags);
44813+ return kernel_sendpage(sock, page, offset, size, flags);
44814 }
44815
44816 static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
44817only in patch2:
44818unchanged:
44819--- linux-2.6.30.4/arch/x86/lguest/Kconfig 2009-07-24 17:47:51.000000000 -0400
44820+++ linux-2.6.30.4/arch/x86/lguest/Kconfig 2009-08-02 09:47:36.165378342 -0400
44821@@ -3,6 +3,7 @@ config LGUEST_GUEST
44822 select PARAVIRT
44823 depends on X86_32
44824 depends on !X86_PAE
44825+ depends on !PAX_KERNEXEC
44826 select VIRTIO
44827 select VIRTIO_RING
44828 select VIRTIO_CONSOLE
44829only in patch2:
44830unchanged:
44831--- linux-2.6.30.4/arch/x86/xen/Kconfig 2009-07-24 17:47:51.000000000 -0400
44832+++ linux-2.6.30.4/arch/x86/xen/Kconfig 2009-08-02 09:47:15.079210101 -0400
44833@@ -8,6 +8,7 @@ config XEN
44834 select PARAVIRT_CLOCK
44835 depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
44836 depends on X86_CMPXCHG && X86_TSC
44837+ depends on !PAX_KERNEXEC
44838 help
44839 This is the Linux Xen port. Enabling this will allow the
44840 kernel to boot in a paravirtualized environment under the
44841only in patch2:
44842unchanged:
44843--- linux-2.6.30.4/arch/x86/xen/xen-ops.h 2009-07-24 17:47:51.000000000 -0400
44844+++ linux-2.6.30.4/arch/x86/xen/xen-ops.h 2009-08-04 17:23:47.809460830 -0400
44845@@ -10,8 +10,6 @@
44846 extern const char xen_hypervisor_callback[];
44847 extern const char xen_failsafe_callback[];
44848
44849-extern void *xen_initial_gdt;
44850-
44851 struct trap_info;
44852 void xen_copy_trap_info(struct trap_info *traps);
44853
44854only in patch2:
44855unchanged:
44856--- linux-2.6.30.4/drivers/media/video/usbvideo/konicawc.c 2009-07-24 17:47:51.000000000 -0400
44857+++ linux-2.6.30.4/drivers/media/video/usbvideo/konicawc.c 2009-08-09 07:48:48.178565450 -0400
44858@@ -225,7 +225,7 @@ static void konicawc_register_input(stru
44859 int error;
44860
44861 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
44862- strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
44863+ strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
44864
44865 cam->input = input_dev = input_allocate_device();
44866 if (!input_dev) {
44867only in patch2:
44868unchanged:
44869--- linux-2.6.30.4/drivers/media/video/usbvideo/quickcam_messenger.c 2009-07-24 17:47:51.000000000 -0400
44870+++ linux-2.6.30.4/drivers/media/video/usbvideo/quickcam_messenger.c 2009-08-09 07:48:48.199403940 -0400
44871@@ -89,7 +89,7 @@ static void qcm_register_input(struct qc
44872 int error;
44873
44874 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
44875- strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
44876+ strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
44877
44878 cam->input = input_dev = input_allocate_device();
44879 if (!input_dev) {
44880only in patch2:
44881unchanged:
44882--- linux-2.6.30.4/drivers/message/i2o/i2o_proc.c 2009-07-24 17:47:51.000000000 -0400
44883+++ linux-2.6.30.4/drivers/message/i2o/i2o_proc.c 2009-08-09 07:48:48.246416282 -0400
44884@@ -259,13 +259,6 @@ static char *scsi_devices[] = {
44885 "Array Controller Device"
44886 };
44887
44888-static char *chtostr(u8 * chars, int n)
44889-{
44890- char tmp[256];
44891- tmp[0] = 0;
44892- return strncat(tmp, (char *)chars, n);
44893-}
44894-
44895 static int i2o_report_query_status(struct seq_file *seq, int block_status,
44896 char *group)
44897 {
44898@@ -842,8 +835,7 @@ static int i2o_seq_show_ddm_table(struct
44899
44900 seq_printf(seq, "%-#7x", ddm_table.i2o_vendor_id);
44901 seq_printf(seq, "%-#8x", ddm_table.module_id);
44902- seq_printf(seq, "%-29s",
44903- chtostr(ddm_table.module_name_version, 28));
44904+ seq_printf(seq, "%-.28s", ddm_table.module_name_version);
44905 seq_printf(seq, "%9d ", ddm_table.data_size);
44906 seq_printf(seq, "%8d", ddm_table.code_size);
44907
44908@@ -944,8 +936,8 @@ static int i2o_seq_show_drivers_stored(s
44909
44910 seq_printf(seq, "%-#7x", dst->i2o_vendor_id);
44911 seq_printf(seq, "%-#8x", dst->module_id);
44912- seq_printf(seq, "%-29s", chtostr(dst->module_name_version, 28));
44913- seq_printf(seq, "%-9s", chtostr(dst->date, 8));
44914+ seq_printf(seq, "%-.28s", dst->module_name_version);
44915+ seq_printf(seq, "%-.8s", dst->date);
44916 seq_printf(seq, "%8d ", dst->module_size);
44917 seq_printf(seq, "%8d ", dst->mpb_size);
44918 seq_printf(seq, "0x%04x", dst->module_flags);
44919@@ -1276,14 +1268,10 @@ static int i2o_seq_show_dev_identity(str
44920 seq_printf(seq, "Device Class : %s\n", i2o_get_class_name(work16[0]));
44921 seq_printf(seq, "Owner TID : %0#5x\n", work16[2]);
44922 seq_printf(seq, "Parent TID : %0#5x\n", work16[3]);
44923- seq_printf(seq, "Vendor info : %s\n",
44924- chtostr((u8 *) (work32 + 2), 16));
44925- seq_printf(seq, "Product info : %s\n",
44926- chtostr((u8 *) (work32 + 6), 16));
44927- seq_printf(seq, "Description : %s\n",
44928- chtostr((u8 *) (work32 + 10), 16));
44929- seq_printf(seq, "Product rev. : %s\n",
44930- chtostr((u8 *) (work32 + 14), 8));
44931+ seq_printf(seq, "Vendor info : %.16s\n", (u8 *) (work32 + 2));
44932+ seq_printf(seq, "Product info : %.16s\n", (u8 *) (work32 + 6));
44933+ seq_printf(seq, "Description : %.16s\n", (u8 *) (work32 + 10));
44934+ seq_printf(seq, "Product rev. : %.8s\n", (u8 *) (work32 + 14));
44935
44936 seq_printf(seq, "Serial number : ");
44937 print_serial_number(seq, (u8 *) (work32 + 16),
44938@@ -1328,10 +1316,8 @@ static int i2o_seq_show_ddm_identity(str
44939 }
44940
44941 seq_printf(seq, "Registering DDM TID : 0x%03x\n", result.ddm_tid);
44942- seq_printf(seq, "Module name : %s\n",
44943- chtostr(result.module_name, 24));
44944- seq_printf(seq, "Module revision : %s\n",
44945- chtostr(result.module_rev, 8));
44946+ seq_printf(seq, "Module name : %.24s\n", result.module_name);
44947+ seq_printf(seq, "Module revision : %.8s\n", result.module_rev);
44948
44949 seq_printf(seq, "Serial number : ");
44950 print_serial_number(seq, result.serial_number, sizeof(result) - 36);
44951@@ -1362,14 +1348,10 @@ static int i2o_seq_show_uinfo(struct seq
44952 return 0;
44953 }
44954
44955- seq_printf(seq, "Device name : %s\n",
44956- chtostr(result.device_name, 64));
44957- seq_printf(seq, "Service name : %s\n",
44958- chtostr(result.service_name, 64));
44959- seq_printf(seq, "Physical name : %s\n",
44960- chtostr(result.physical_location, 64));
44961- seq_printf(seq, "Instance number : %s\n",
44962- chtostr(result.instance_number, 4));
44963+ seq_printf(seq, "Device name : %.64s\n", result.device_name);
44964+ seq_printf(seq, "Service name : %.64s\n", result.service_name);
44965+ seq_printf(seq, "Physical name : %.64s\n", result.physical_location);
44966+ seq_printf(seq, "Instance number : %.4s\n", result.instance_number);
44967
44968 return 0;
44969 }
44970only in patch2:
44971unchanged:
44972--- linux-2.6.30.4/drivers/platform/x86/wmi.c 2009-07-24 17:47:51.000000000 -0400
44973+++ linux-2.6.30.4/drivers/platform/x86/wmi.c 2009-08-09 07:48:48.278373587 -0400
44974@@ -270,7 +270,7 @@ u32 method_id, const struct acpi_buffer
44975 acpi_status status;
44976 struct acpi_object_list input;
44977 union acpi_object params[3];
44978- char method[4] = "WM";
44979+ char method[5] = "WM";
44980
44981 if (!find_guid(guid_string, &wblock))
44982 return AE_ERROR;
44983@@ -328,8 +328,8 @@ struct acpi_buffer *out)
44984 acpi_status status, wc_status = AE_ERROR;
44985 struct acpi_object_list input, wc_input;
44986 union acpi_object wc_params[1], wq_params[1];
44987- char method[4];
44988- char wc_method[4] = "WC";
44989+ char method[5];
44990+ char wc_method[5] = "WC";
44991
44992 if (!guid_string || !out)
44993 return AE_BAD_PARAMETER;
44994@@ -410,7 +410,7 @@ const struct acpi_buffer *in)
44995 acpi_handle handle;
44996 struct acpi_object_list input;
44997 union acpi_object params[2];
44998- char method[4] = "WS";
44999+ char method[5] = "WS";
45000
45001 if (!guid_string || !in)
45002 return AE_BAD_DATA;
45003only in patch2:
45004unchanged:
45005--- linux-2.6.30.4/mm/highmem.c 2009-07-24 17:47:51.000000000 -0400
45006+++ linux-2.6.30.4/mm/highmem.c 2009-08-02 11:24:41.617453261 -0400
45007@@ -95,6 +95,9 @@ static void flush_all_zero_pkmaps(void)
45008
45009 for (i = 0; i < LAST_PKMAP; i++) {
45010 struct page *page;
45011+#ifdef CONFIG_PAX_KERNEXEC
45012+ unsigned long cr0;
45013+#endif
45014
45015 /*
45016 * zero means we don't have anything to do,
45017@@ -117,9 +120,18 @@ static void flush_all_zero_pkmaps(void)
45018 * So no dangers, even with speculative execution.
45019 */
45020 page = pte_page(pkmap_page_table[i]);
45021+
45022+#ifdef CONFIG_PAX_KERNEXEC
45023+ pax_open_kernel(cr0);
45024+#endif
45025+
45026 pte_clear(&init_mm, (unsigned long)page_address(page),
45027 &pkmap_page_table[i]);
45028
45029+#ifdef CONFIG_PAX_KERNEXEC
45030+ pax_close_kernel(cr0);
45031+#endif
45032+
45033 set_page_address(page, NULL);
45034 need_flush = 1;
45035 }
45036@@ -141,6 +153,9 @@ static inline unsigned long map_new_virt
45037 {
45038 unsigned long vaddr;
45039 int count;
45040+#ifdef CONFIG_PAX_KERNEXEC
45041+ unsigned long cr0;
45042+#endif
45043
45044 start:
45045 count = LAST_PKMAP;
45046@@ -178,8 +193,14 @@ start:
45047 }
45048 }
45049 vaddr = PKMAP_ADDR(last_pkmap_nr);
45050+#ifdef CONFIG_PAX_KERNEXEC
45051+ pax_open_kernel(cr0);
45052+#endif
45053 set_pte_at(&init_mm, vaddr,
45054 &(pkmap_page_table[last_pkmap_nr]), mk_pte(page, kmap_prot));
45055+#ifdef CONFIG_PAX_KERNEXEC
45056+ pax_close_kernel(cr0);
45057+#endif
45058
45059 pkmap_count[last_pkmap_nr] = 1;
45060 set_page_address(page, (void *)vaddr);
45061only in patch2:
45062unchanged:
45063--- linux-2.6.30.4/usr/gen_init_cpio.c 2009-07-24 17:47:51.000000000 -0400
45064+++ linux-2.6.30.4/usr/gen_init_cpio.c 2009-08-09 07:48:48.304466902 -0400
45065@@ -383,9 +383,10 @@ static char *cpio_replace_env(char *new_
45066 *env_var = *expanded = '\0';
45067 strncat(env_var, start + 2, end - start - 2);
45068 strncat(expanded, new_location, start - new_location);
45069- strncat(expanded, getenv(env_var), PATH_MAX);
45070- strncat(expanded, end + 1, PATH_MAX);
45071+ strncat(expanded, getenv(env_var), PATH_MAX - strlen(expanded));
45072+ strncat(expanded, end + 1, PATH_MAX - strlen(expanded));
45073 strncpy(new_location, expanded, PATH_MAX);
45074+ new_location[PATH_MAX] = 0;
45075 } else
45076 break;
45077 }
This page took 7.4056 seconds and 4 git commands to generate.